mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
ARM cpufreq updates for 6.11
- cpufreq: Add Loongson-3 CPUFreq driver support (Huacai Chen). - Make exit() callback return void (Lizhe and Viresh Kumar). - Minor cleanups and fixes in several drivers (Bryan Brattlof, Javier Carrasco, Jagadeesh Kona, Jeff Johnson, Nícolas F. R. A. Prado, Primoz Fiser, Raphael Gallais-Pou, and Riwen Lu). -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmaM3agACgkQ0rkcPK6B Ehw2QA//W+HaHbEf3zOFvwDgG23h3ampEzIoZ1LTznU7rsK7as1XgJ12pHk3uZyy L9OppUeN0zH9LaIgOCG5C5oVnRujl30LK3jo/vyBkGROdpng6w4Wci/2XIqPEZFJ sMC3om+VgbXGu1UaxSTX/fBjuWeuoLY6rrGHjkDcAh52bgEWuRTzgOIrcRTRpcvb G8Gy1YU/t2j/UocYkiR3s5JAFyujmiWcoD4fO4wt+JaYRnDmfQXSrE9X0dpjN+Vp wxftLn3RgbuIXGmrDnnwUiDa/e6YSTLKgkrdzshSyOeHUzW7SoMfkMqb26bnFsLY m2FKnTtT2uQIPdFwrPPseXhUvjklyOAeIZH6tO/QGoteXU3SVWB1kBQNcVbztWF5 hHGL/qERACIt3xU/WQ0h1nvTMf46+1vc944uArh6F6t/XvmcoXv05YDRymyZBWLx mNRqG89gDex/TB+R15GBbXibK2UEGB26Bu84m7nFgbo5B0oM+OPebm49133gfz3V b8XaxzQMMFgdV3CpqRxQTNSnPWiwspttBZE7hYULONDxj8Ys/yfY7Gq8khjQxEBO xxQ4QRtlwkLSilyNb19i5LM9F+HpmkxdjO6su3SgZW5QVUUKsNA/aY0CbrXuIRiS dBGwBz8/EZ/7+/bK+TIU5tdR8UCSrVifF/bVGaQnWRWvB/2gPhw= =qMmS -----END PGP SIGNATURE----- Merge tag 'cpufreq-arm-updates-6.11' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Merge ARM cpufreq updates for 6.11 from Viresh Kumar: "- cpufreq: Add Loongson-3 CPUFreq driver support (Huacai Chen). - Make exit() callback return void (Lizhe and Viresh Kumar). - Minor cleanups and fixes in several drivers (Bryan Brattlof, Javier Carrasco, Jagadeesh Kona, Jeff Johnson, Nícolas F. R. A. Prado, Primoz Fiser, Raphael Gallais-Pou, and Riwen Lu)." * tag 'cpufreq-arm-updates-6.11' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: (21 commits) cpufreq: sti: fix build warning cpufreq: mediatek: Use dev_err_probe in every error path in probe cpufreq: Add Loongson-3 CPUFreq driver support cpufreq: Make cpufreq_driver->exit() return void cpufreq: pcc: Remove empty exit() callback cpufreq: loongson2: Remove empty exit() callback cpufreq: nforce2: Remove empty exit() callback cpufreq: sti: add missing MODULE_DEVICE_TABLE entry for stih418 cpufreq: ti: update OPP table for AM62Px SoCs cpufreq: ti: update OPP table for AM62Ax SoCs cpufreq: sun50i: add Allwinner H700 speed bin cpufreq/cppc: Don't compare desired_perf in target() OPP: ti: Fix ti_opp_supply_probe wrong return values cpufreq: ti-cpufreq: Handle deferred probe with dev_err_probe() cpufreq: dt-platdev: add missing MODULE_DESCRIPTION() macro cpufreq: longhaul: Fix kernel-doc param for longhaul_setstate cpufreq: qcom-nvmem: eliminate uses of of_node_put() cpufreq: qcom-nvmem: fix memory leaks in probe error paths cpufreq: scmi: Avoid overflow of target_freq in fast switch cpufreq: sun50i: replace of_node_put() with automatic cleanup handler ...
This commit is contained in:
commit
7ad9eab9d4
@ -12967,6 +12967,7 @@ F: Documentation/arch/loongarch/
|
||||
F: Documentation/translations/zh_CN/arch/loongarch/
|
||||
F: arch/loongarch/
|
||||
F: drivers/*/*loongarch*
|
||||
F: drivers/cpufreq/loongson3_cpufreq.c
|
||||
|
||||
LOONGSON GPIO DRIVER
|
||||
M: Yinbo Zhu <zhuyinbo@loongson.cn>
|
||||
|
@ -262,6 +262,18 @@ config LOONGSON2_CPUFREQ
|
||||
If in doubt, say N.
|
||||
endif
|
||||
|
||||
if LOONGARCH
|
||||
config LOONGSON3_CPUFREQ
|
||||
tristate "Loongson3 CPUFreq Driver"
|
||||
help
|
||||
This option adds a CPUFreq driver for Loongson processors which
|
||||
support software configurable cpu frequency.
|
||||
|
||||
Loongson-3 family processors support this feature.
|
||||
|
||||
If in doubt, say N.
|
||||
endif
|
||||
|
||||
if SPARC64
|
||||
config SPARC_US3_CPUFREQ
|
||||
tristate "UltraSPARC-III CPU Frequency driver"
|
||||
|
@ -103,6 +103,7 @@ obj-$(CONFIG_POWERNV_CPUFREQ) += powernv-cpufreq.o
|
||||
# Other platform drivers
|
||||
obj-$(CONFIG_BMIPS_CPUFREQ) += bmips-cpufreq.o
|
||||
obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o
|
||||
obj-$(CONFIG_LOONGSON3_CPUFREQ) += loongson3_cpufreq.o
|
||||
obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o
|
||||
obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o
|
||||
obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o
|
||||
|
@ -904,7 +904,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct acpi_cpufreq_data *data = policy->driver_data;
|
||||
|
||||
@ -917,8 +917,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
free_cpumask_var(data->freqdomain_cpus);
|
||||
kfree(policy->freq_table);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
|
||||
|
@ -1093,7 +1093,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct amd_cpudata *cpudata = policy->driver_data;
|
||||
|
||||
@ -1101,8 +1101,6 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
|
||||
freq_qos_remove_request(&cpudata->req[0]);
|
||||
policy->fast_switch_possible = false;
|
||||
kfree(cpudata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pstate_cpu_resume(struct cpufreq_policy *policy)
|
||||
@ -1545,7 +1543,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct amd_cpudata *cpudata = policy->driver_data;
|
||||
|
||||
@ -1555,7 +1553,6 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
|
||||
}
|
||||
|
||||
pr_debug("CPU %d exiting\n", policy->cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
|
||||
|
@ -305,7 +305,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int apple_soc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void apple_soc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct apple_cpu_priv *priv = policy->driver_data;
|
||||
|
||||
@ -313,8 +313,6 @@ static int apple_soc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
|
||||
iounmap(priv->reg_base);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver apple_soc_cpufreq_driver = {
|
||||
|
@ -121,11 +121,9 @@ static int bmips_cpufreq_target_index(struct cpufreq_policy *policy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bmips_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void bmips_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
kfree(policy->freq_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bmips_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
@ -291,15 +291,10 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
|
||||
struct cppc_cpudata *cpu_data = policy->driver_data;
|
||||
unsigned int cpu = policy->cpu;
|
||||
struct cpufreq_freqs freqs;
|
||||
u32 desired_perf;
|
||||
int ret = 0;
|
||||
|
||||
desired_perf = cppc_khz_to_perf(&cpu_data->perf_caps, target_freq);
|
||||
/* Return if it is exactly the same perf */
|
||||
if (desired_perf == cpu_data->perf_ctrls.desired_perf)
|
||||
return ret;
|
||||
|
||||
cpu_data->perf_ctrls.desired_perf = desired_perf;
|
||||
cpu_data->perf_ctrls.desired_perf =
|
||||
cppc_khz_to_perf(&cpu_data->perf_caps, target_freq);
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = target_freq;
|
||||
|
||||
@ -688,7 +683,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cppc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void cppc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cppc_cpudata *cpu_data = policy->driver_data;
|
||||
struct cppc_perf_caps *caps = &cpu_data->perf_caps;
|
||||
@ -705,7 +700,6 @@ static int cppc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
caps->lowest_perf, cpu, ret);
|
||||
|
||||
cppc_cpufreq_put_cpu_data(policy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u64 get_delta(u64 t1, u64 t0)
|
||||
|
@ -233,4 +233,5 @@ static int __init cpufreq_dt_platdev_init(void)
|
||||
sizeof(struct cpufreq_dt_platform_data)));
|
||||
}
|
||||
core_initcall(cpufreq_dt_platdev_init);
|
||||
MODULE_DESCRIPTION("Generic DT based cpufreq platdev driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -157,10 +157,9 @@ static int cpufreq_offline(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
clk_put(policy->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver dt_cpufreq_driver = {
|
||||
|
@ -359,11 +359,6 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nforce2_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver nforce2_driver = {
|
||||
.name = "nforce2",
|
||||
.flags = CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
|
||||
@ -371,7 +366,6 @@ static struct cpufreq_driver nforce2_driver = {
|
||||
.target = nforce2_target,
|
||||
.get = nforce2_get,
|
||||
.init = nforce2_cpu_init,
|
||||
.exit = nforce2_cpu_exit,
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
|
@ -360,14 +360,13 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eps_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void eps_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int cpu = policy->cpu;
|
||||
|
||||
/* Bye */
|
||||
kfree(eps_cpu[cpu]);
|
||||
eps_cpu[cpu] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver eps_driver = {
|
||||
|
@ -2715,13 +2715,11 @@ static int intel_pstate_cpu_offline(struct cpufreq_policy *policy)
|
||||
return intel_cpufreq_cpu_offline(policy);
|
||||
}
|
||||
|
||||
static int intel_pstate_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void intel_pstate_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
pr_debug("CPU %d exiting\n", policy->cpu);
|
||||
|
||||
policy->fast_switch_possible = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
|
||||
@ -3052,7 +3050,7 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void intel_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct freq_qos_request *req;
|
||||
|
||||
@ -3062,7 +3060,7 @@ static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
freq_qos_remove_request(req);
|
||||
kfree(req);
|
||||
|
||||
return intel_pstate_cpu_exit(policy);
|
||||
intel_pstate_cpu_exit(policy);
|
||||
}
|
||||
|
||||
static int intel_cpufreq_suspend(struct cpufreq_policy *policy)
|
||||
|
@ -236,8 +236,9 @@ static void do_powersaver(int cx_address, unsigned int mults_index,
|
||||
}
|
||||
|
||||
/**
|
||||
* longhaul_set_cpu_frequency()
|
||||
* @mults_index : bitpattern of the new multiplier.
|
||||
* longhaul_setstate()
|
||||
* @policy: cpufreq_policy structure containing the current policy.
|
||||
* @table_index: index of the frequency within the cpufreq_frequency_table.
|
||||
*
|
||||
* Sets a new clock ratio.
|
||||
*/
|
||||
|
@ -85,18 +85,12 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver loongson2_cpufreq_driver = {
|
||||
.name = "loongson2",
|
||||
.init = loongson2_cpufreq_cpu_init,
|
||||
.verify = cpufreq_generic_frequency_table_verify,
|
||||
.target_index = loongson2_cpufreq_target,
|
||||
.get = cpufreq_generic_get,
|
||||
.exit = loongson2_cpufreq_exit,
|
||||
.attr = cpufreq_generic_attr,
|
||||
};
|
||||
|
||||
|
395
drivers/cpufreq/loongson3_cpufreq.c
Normal file
395
drivers/cpufreq/loongson3_cpufreq.c
Normal file
@ -0,0 +1,395 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* CPUFreq driver for the Loongson-3 processors.
|
||||
*
|
||||
* All revisions of Loongson-3 processor support cpu_has_scalefreq feature.
|
||||
*
|
||||
* Author: Huacai Chen <chenhuacai@loongson.cn>
|
||||
* Copyright (C) 2024 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <asm/idle.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/loongson.h>
|
||||
|
||||
/* Message */
|
||||
union smc_message {
|
||||
u32 value;
|
||||
struct {
|
||||
u32 id : 4;
|
||||
u32 info : 4;
|
||||
u32 val : 16;
|
||||
u32 cmd : 6;
|
||||
u32 extra : 1;
|
||||
u32 complete : 1;
|
||||
};
|
||||
};
|
||||
|
||||
/* Command return values */
|
||||
#define CMD_OK 0 /* No error */
|
||||
#define CMD_ERROR 1 /* Regular error */
|
||||
#define CMD_NOCMD 2 /* Command does not support */
|
||||
#define CMD_INVAL 3 /* Invalid Parameter */
|
||||
|
||||
/* Version commands */
|
||||
/*
|
||||
* CMD_GET_VERSION - Get interface version
|
||||
* Input: none
|
||||
* Output: version
|
||||
*/
|
||||
#define CMD_GET_VERSION 0x1
|
||||
|
||||
/* Feature commands */
|
||||
/*
|
||||
* CMD_GET_FEATURE - Get feature state
|
||||
* Input: feature ID
|
||||
* Output: feature flag
|
||||
*/
|
||||
#define CMD_GET_FEATURE 0x2
|
||||
|
||||
/*
|
||||
* CMD_SET_FEATURE - Set feature state
|
||||
* Input: feature ID, feature flag
|
||||
* output: none
|
||||
*/
|
||||
#define CMD_SET_FEATURE 0x3
|
||||
|
||||
/* Feature IDs */
|
||||
#define FEATURE_SENSOR 0
|
||||
#define FEATURE_FAN 1
|
||||
#define FEATURE_DVFS 2
|
||||
|
||||
/* Sensor feature flags */
|
||||
#define FEATURE_SENSOR_ENABLE BIT(0)
|
||||
#define FEATURE_SENSOR_SAMPLE BIT(1)
|
||||
|
||||
/* Fan feature flags */
|
||||
#define FEATURE_FAN_ENABLE BIT(0)
|
||||
#define FEATURE_FAN_AUTO BIT(1)
|
||||
|
||||
/* DVFS feature flags */
|
||||
#define FEATURE_DVFS_ENABLE BIT(0)
|
||||
#define FEATURE_DVFS_BOOST BIT(1)
|
||||
#define FEATURE_DVFS_AUTO BIT(2)
|
||||
#define FEATURE_DVFS_SINGLE_BOOST BIT(3)
|
||||
|
||||
/* Sensor commands */
|
||||
/*
|
||||
* CMD_GET_SENSOR_NUM - Get number of sensors
|
||||
* Input: none
|
||||
* Output: number
|
||||
*/
|
||||
#define CMD_GET_SENSOR_NUM 0x4
|
||||
|
||||
/*
|
||||
* CMD_GET_SENSOR_STATUS - Get sensor status
|
||||
* Input: sensor ID, type
|
||||
* Output: sensor status
|
||||
*/
|
||||
#define CMD_GET_SENSOR_STATUS 0x5
|
||||
|
||||
/* Sensor types */
|
||||
#define SENSOR_INFO_TYPE 0
|
||||
#define SENSOR_INFO_TYPE_TEMP 1
|
||||
|
||||
/* Fan commands */
|
||||
/*
|
||||
* CMD_GET_FAN_NUM - Get number of fans
|
||||
* Input: none
|
||||
* Output: number
|
||||
*/
|
||||
#define CMD_GET_FAN_NUM 0x6
|
||||
|
||||
/*
|
||||
* CMD_GET_FAN_INFO - Get fan status
|
||||
* Input: fan ID, type
|
||||
* Output: fan info
|
||||
*/
|
||||
#define CMD_GET_FAN_INFO 0x7
|
||||
|
||||
/*
|
||||
* CMD_SET_FAN_INFO - Set fan status
|
||||
* Input: fan ID, type, value
|
||||
* Output: none
|
||||
*/
|
||||
#define CMD_SET_FAN_INFO 0x8
|
||||
|
||||
/* Fan types */
|
||||
#define FAN_INFO_TYPE_LEVEL 0
|
||||
|
||||
/* DVFS commands */
|
||||
/*
|
||||
* CMD_GET_FREQ_LEVEL_NUM - Get number of freq levels
|
||||
* Input: CPU ID
|
||||
* Output: number
|
||||
*/
|
||||
#define CMD_GET_FREQ_LEVEL_NUM 0x9
|
||||
|
||||
/*
|
||||
* CMD_GET_FREQ_BOOST_LEVEL - Get the first boost level
|
||||
* Input: CPU ID
|
||||
* Output: number
|
||||
*/
|
||||
#define CMD_GET_FREQ_BOOST_LEVEL 0x10
|
||||
|
||||
/*
|
||||
* CMD_GET_FREQ_LEVEL_INFO - Get freq level info
|
||||
* Input: CPU ID, level ID
|
||||
* Output: level info
|
||||
*/
|
||||
#define CMD_GET_FREQ_LEVEL_INFO 0x11
|
||||
|
||||
/*
|
||||
* CMD_GET_FREQ_INFO - Get freq info
|
||||
* Input: CPU ID, type
|
||||
* Output: freq info
|
||||
*/
|
||||
#define CMD_GET_FREQ_INFO 0x12
|
||||
|
||||
/*
|
||||
* CMD_SET_FREQ_INFO - Set freq info
|
||||
* Input: CPU ID, type, value
|
||||
* Output: none
|
||||
*/
|
||||
#define CMD_SET_FREQ_INFO 0x13
|
||||
|
||||
/* Freq types */
|
||||
#define FREQ_INFO_TYPE_FREQ 0
|
||||
#define FREQ_INFO_TYPE_LEVEL 1
|
||||
|
||||
#define FREQ_MAX_LEVEL 16
|
||||
|
||||
struct loongson3_freq_data {
|
||||
unsigned int def_freq_level;
|
||||
struct cpufreq_frequency_table table[];
|
||||
};
|
||||
|
||||
static struct mutex cpufreq_mutex[MAX_PACKAGES];
|
||||
static struct cpufreq_driver loongson3_cpufreq_driver;
|
||||
static DEFINE_PER_CPU(struct loongson3_freq_data *, freq_data);
|
||||
|
||||
static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 extra)
|
||||
{
|
||||
int retries;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
unsigned int package = cpu_data[cpu].package;
|
||||
union smc_message msg, last;
|
||||
|
||||
mutex_lock(&cpufreq_mutex[package]);
|
||||
|
||||
last.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
|
||||
if (!last.complete) {
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
msg.id = id;
|
||||
msg.info = info;
|
||||
msg.cmd = cmd;
|
||||
msg.val = val;
|
||||
msg.extra = extra;
|
||||
msg.complete = 0;
|
||||
|
||||
iocsr_write32(msg.value, LOONGARCH_IOCSR_SMCMBX);
|
||||
iocsr_write32(iocsr_read32(LOONGARCH_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
|
||||
LOONGARCH_IOCSR_MISC_FUNC);
|
||||
|
||||
for (retries = 0; retries < 10000; retries++) {
|
||||
msg.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
|
||||
if (msg.complete)
|
||||
break;
|
||||
|
||||
usleep_range(8, 12);
|
||||
}
|
||||
|
||||
if (!msg.complete || msg.cmd != CMD_OK) {
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
mutex_unlock(&cpufreq_mutex[package]);
|
||||
|
||||
return msg.val;
|
||||
}
|
||||
|
||||
static unsigned int loongson3_cpufreq_get(unsigned int cpu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0);
|
||||
|
||||
return ret * KILO;
|
||||
}
|
||||
|
||||
static int loongson3_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = do_service_request(cpu_data[policy->cpu].core,
|
||||
FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO, index, 0);
|
||||
|
||||
return (ret >= 0) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int configure_freq_table(int cpu)
|
||||
{
|
||||
int i, ret, boost_level, max_level, freq_level;
|
||||
struct platform_device *pdev = cpufreq_get_driver_data();
|
||||
struct loongson3_freq_data *data;
|
||||
|
||||
if (per_cpu(freq_data, cpu))
|
||||
return 0;
|
||||
|
||||
ret = do_service_request(cpu, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
max_level = ret;
|
||||
|
||||
ret = do_service_request(cpu, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
boost_level = ret;
|
||||
|
||||
freq_level = min(max_level, FREQ_MAX_LEVEL);
|
||||
data = devm_kzalloc(&pdev->dev, struct_size(data, table, freq_level + 1), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->def_freq_level = boost_level - 1;
|
||||
|
||||
for (i = 0; i < freq_level; i++) {
|
||||
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0);
|
||||
if (ret < 0) {
|
||||
devm_kfree(&pdev->dev, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->table[i].frequency = ret * KILO;
|
||||
data->table[i].flags = (i >= boost_level) ? CPUFREQ_BOOST_FREQ : 0;
|
||||
}
|
||||
|
||||
data->table[freq_level].flags = 0;
|
||||
data->table[freq_level].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
per_cpu(freq_data, cpu) = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loongson3_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int i, ret, cpu = policy->cpu;
|
||||
|
||||
ret = configure_freq_table(cpu);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
policy->cpuinfo.transition_latency = 10000;
|
||||
policy->freq_table = per_cpu(freq_data, cpu)->table;
|
||||
policy->suspend_freq = policy->freq_table[per_cpu(freq_data, cpu)->def_freq_level].frequency;
|
||||
cpumask_copy(policy->cpus, topology_sibling_cpumask(cpu));
|
||||
|
||||
for_each_cpu(i, policy->cpus) {
|
||||
if (i != cpu)
|
||||
per_cpu(freq_data, i) = per_cpu(freq_data, cpu);
|
||||
}
|
||||
|
||||
if (policy_has_boost_freq(policy)) {
|
||||
ret = cpufreq_enable_boost_support();
|
||||
if (ret < 0) {
|
||||
pr_warn("cpufreq: Failed to enable boost: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
loongson3_cpufreq_driver.boost_enabled = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void loongson3_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
int cpu = policy->cpu;
|
||||
|
||||
loongson3_cpufreq_target(policy, per_cpu(freq_data, cpu)->def_freq_level);
|
||||
}
|
||||
|
||||
static int loongson3_cpufreq_cpu_online(struct cpufreq_policy *policy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loongson3_cpufreq_cpu_offline(struct cpufreq_policy *policy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver loongson3_cpufreq_driver = {
|
||||
.name = "loongson3",
|
||||
.flags = CPUFREQ_CONST_LOOPS,
|
||||
.init = loongson3_cpufreq_cpu_init,
|
||||
.exit = loongson3_cpufreq_cpu_exit,
|
||||
.online = loongson3_cpufreq_cpu_online,
|
||||
.offline = loongson3_cpufreq_cpu_offline,
|
||||
.get = loongson3_cpufreq_get,
|
||||
.target_index = loongson3_cpufreq_target,
|
||||
.attr = cpufreq_generic_attr,
|
||||
.verify = cpufreq_generic_frequency_table_verify,
|
||||
.suspend = cpufreq_generic_suspend,
|
||||
};
|
||||
|
||||
static int loongson3_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < MAX_PACKAGES; i++)
|
||||
devm_mutex_init(&pdev->dev, &cpufreq_mutex[i]);
|
||||
|
||||
ret = do_service_request(0, 0, CMD_GET_VERSION, 0, 0);
|
||||
if (ret <= 0)
|
||||
return -EPERM;
|
||||
|
||||
ret = do_service_request(FEATURE_DVFS, 0, CMD_SET_FEATURE,
|
||||
FEATURE_DVFS_ENABLE | FEATURE_DVFS_BOOST, 0);
|
||||
if (ret < 0)
|
||||
return -EPERM;
|
||||
|
||||
loongson3_cpufreq_driver.driver_data = pdev;
|
||||
|
||||
ret = cpufreq_register_driver(&loongson3_cpufreq_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_info("cpufreq: Loongson-3 CPU frequency driver.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void loongson3_cpufreq_remove(struct platform_device *pdev)
|
||||
{
|
||||
cpufreq_unregister_driver(&loongson3_cpufreq_driver);
|
||||
}
|
||||
|
||||
static struct platform_device_id cpufreq_id_table[] = {
|
||||
{ "loongson3_cpufreq", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, cpufreq_id_table);
|
||||
|
||||
static struct platform_driver loongson3_platform_driver = {
|
||||
.driver = {
|
||||
.name = "loongson3_cpufreq",
|
||||
},
|
||||
.id_table = cpufreq_id_table,
|
||||
.probe = loongson3_cpufreq_probe,
|
||||
.remove_new = loongson3_cpufreq_remove,
|
||||
};
|
||||
module_platform_driver(loongson3_platform_driver);
|
||||
|
||||
MODULE_AUTHOR("Huacai Chen <chenhuacai@loongson.cn>");
|
||||
MODULE_DESCRIPTION("CPUFreq driver for Loongson-3 processors");
|
||||
MODULE_LICENSE("GPL");
|
@ -260,7 +260,7 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct mtk_cpufreq_data *data = policy->driver_data;
|
||||
struct resource *res = data->res;
|
||||
@ -270,8 +270,6 @@ static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
writel_relaxed(0x0, data->reg_bases[REG_FREQ_ENABLE]);
|
||||
iounmap(base);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_cpufreq_register_em(struct cpufreq_policy *policy)
|
||||
|
@ -390,28 +390,23 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
int ret;
|
||||
|
||||
cpu_dev = get_cpu_device(cpu);
|
||||
if (!cpu_dev) {
|
||||
dev_err(cpu_dev, "failed to get cpu%d device\n", cpu);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!cpu_dev)
|
||||
return dev_err_probe(cpu_dev, -ENODEV, "failed to get cpu%d device\n", cpu);
|
||||
info->cpu_dev = cpu_dev;
|
||||
|
||||
info->ccifreq_bound = false;
|
||||
if (info->soc_data->ccifreq_supported) {
|
||||
info->cci_dev = of_get_cci(info->cpu_dev);
|
||||
if (IS_ERR(info->cci_dev)) {
|
||||
ret = PTR_ERR(info->cci_dev);
|
||||
dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (IS_ERR(info->cci_dev))
|
||||
return dev_err_probe(cpu_dev, PTR_ERR(info->cci_dev),
|
||||
"cpu%d: failed to get cci device\n",
|
||||
cpu);
|
||||
}
|
||||
|
||||
info->cpu_clk = clk_get(cpu_dev, "cpu");
|
||||
if (IS_ERR(info->cpu_clk)) {
|
||||
ret = PTR_ERR(info->cpu_clk);
|
||||
return dev_err_probe(cpu_dev, ret,
|
||||
if (IS_ERR(info->cpu_clk))
|
||||
return dev_err_probe(cpu_dev, PTR_ERR(info->cpu_clk),
|
||||
"cpu%d: failed to get cpu clk\n", cpu);
|
||||
}
|
||||
|
||||
info->inter_clk = clk_get(cpu_dev, "intermediate");
|
||||
if (IS_ERR(info->inter_clk)) {
|
||||
@ -431,7 +426,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
|
||||
ret = regulator_enable(info->proc_reg);
|
||||
if (ret) {
|
||||
dev_warn(cpu_dev, "cpu%d: failed to enable vproc\n", cpu);
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable vproc\n", cpu);
|
||||
goto out_free_proc_reg;
|
||||
}
|
||||
|
||||
@ -439,14 +434,17 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
info->sram_reg = regulator_get_optional(cpu_dev, "sram");
|
||||
if (IS_ERR(info->sram_reg)) {
|
||||
ret = PTR_ERR(info->sram_reg);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
dev_err_probe(cpu_dev, ret,
|
||||
"cpu%d: Failed to get sram regulator\n", cpu);
|
||||
goto out_disable_proc_reg;
|
||||
}
|
||||
|
||||
info->sram_reg = NULL;
|
||||
} else {
|
||||
ret = regulator_enable(info->sram_reg);
|
||||
if (ret) {
|
||||
dev_warn(cpu_dev, "cpu%d: failed to enable vsram\n", cpu);
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable vsram\n", cpu);
|
||||
goto out_free_sram_reg;
|
||||
}
|
||||
}
|
||||
@ -454,31 +452,34 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
/* Get OPP-sharing information from "operating-points-v2" bindings */
|
||||
ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
|
||||
if (ret) {
|
||||
dev_err(cpu_dev,
|
||||
dev_err_probe(cpu_dev, ret,
|
||||
"cpu%d: failed to get OPP-sharing information\n", cpu);
|
||||
goto out_disable_sram_reg;
|
||||
}
|
||||
|
||||
ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
|
||||
if (ret) {
|
||||
dev_warn(cpu_dev, "cpu%d: no OPP table\n", cpu);
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: no OPP table\n", cpu);
|
||||
goto out_disable_sram_reg;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(info->cpu_clk);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable cpu clk\n", cpu);
|
||||
goto out_free_opp_table;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(info->inter_clk);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable inter clk\n", cpu);
|
||||
goto out_disable_mux_clock;
|
||||
}
|
||||
|
||||
if (info->soc_data->ccifreq_supported) {
|
||||
info->vproc_on_boot = regulator_get_voltage(info->proc_reg);
|
||||
if (info->vproc_on_boot < 0) {
|
||||
ret = info->vproc_on_boot;
|
||||
dev_err(info->cpu_dev,
|
||||
"invalid Vproc value: %d\n", info->vproc_on_boot);
|
||||
ret = dev_err_probe(info->cpu_dev, info->vproc_on_boot,
|
||||
"invalid Vproc value\n");
|
||||
goto out_disable_inter_clock;
|
||||
}
|
||||
}
|
||||
@ -487,8 +488,8 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
rate = clk_get_rate(info->inter_clk);
|
||||
opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
|
||||
if (IS_ERR(opp)) {
|
||||
dev_err(cpu_dev, "cpu%d: failed to get intermediate opp\n", cpu);
|
||||
ret = PTR_ERR(opp);
|
||||
ret = dev_err_probe(cpu_dev, PTR_ERR(opp),
|
||||
"cpu%d: failed to get intermediate opp\n", cpu);
|
||||
goto out_disable_inter_clock;
|
||||
}
|
||||
info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
|
||||
@ -501,7 +502,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
info->opp_nb.notifier_call = mtk_cpufreq_opp_notifier;
|
||||
ret = dev_pm_opp_register_notifier(cpu_dev, &info->opp_nb);
|
||||
if (ret) {
|
||||
dev_err(cpu_dev, "cpu%d: failed to register opp notifier\n", cpu);
|
||||
dev_err_probe(cpu_dev, ret, "cpu%d: failed to register opp notifier\n", cpu);
|
||||
goto out_disable_inter_clock;
|
||||
}
|
||||
|
||||
@ -599,13 +600,11 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void mtk_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct mtk_cpu_dvfs_info *info = policy->driver_data;
|
||||
|
||||
dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver mtk_cpufreq_driver = {
|
||||
@ -629,11 +628,9 @@ static int mtk_cpufreq_probe(struct platform_device *pdev)
|
||||
int cpu, ret;
|
||||
|
||||
data = dev_get_platdata(&pdev->dev);
|
||||
if (!data) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get mtk cpufreq platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!data)
|
||||
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||
"failed to get mtk cpufreq platform data\n");
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
info = mtk_cpu_dvfs_info_lookup(cpu);
|
||||
@ -642,25 +639,22 @@ static int mtk_cpufreq_probe(struct platform_device *pdev)
|
||||
|
||||
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
||||
if (!info) {
|
||||
ret = -ENOMEM;
|
||||
ret = dev_err_probe(&pdev->dev, -ENOMEM,
|
||||
"Failed to allocate dvfs_info\n");
|
||||
goto release_dvfs_info_list;
|
||||
}
|
||||
|
||||
info->soc_data = data;
|
||||
ret = mtk_cpu_dvfs_info_init(info, cpu);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to initialize dvfs info for cpu%d\n",
|
||||
cpu);
|
||||
if (ret)
|
||||
goto release_dvfs_info_list;
|
||||
}
|
||||
|
||||
list_add(&info->list_head, &dvfs_info_list);
|
||||
}
|
||||
|
||||
ret = cpufreq_register_driver(&mtk_cpufreq_driver);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n");
|
||||
dev_err_probe(&pdev->dev, ret, "failed to register mtk cpufreq driver\n");
|
||||
goto release_dvfs_info_list;
|
||||
}
|
||||
|
||||
|
@ -135,11 +135,10 @@ static int omap_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void omap_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
freq_table_free();
|
||||
clk_put(policy->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver omap_driver = {
|
||||
|
@ -204,21 +204,19 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
/*
|
||||
* We don't support CPU hotplug. Don't unmap after the system
|
||||
* has already made it to a running state.
|
||||
*/
|
||||
if (system_state >= SYSTEM_RUNNING)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (sdcasr_mapbase)
|
||||
iounmap(sdcasr_mapbase);
|
||||
if (sdcpwr_mapbase)
|
||||
iounmap(sdcpwr_mapbase);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pas_cpufreq_target(struct cpufreq_policy *policy,
|
||||
|
@ -562,18 +562,12 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver pcc_cpufreq_driver = {
|
||||
.flags = CPUFREQ_CONST_LOOPS,
|
||||
.get = pcc_get_freq,
|
||||
.verify = pcc_cpufreq_verify,
|
||||
.target = pcc_cpufreq_target,
|
||||
.init = pcc_cpufreq_cpu_init,
|
||||
.exit = pcc_cpufreq_cpu_exit,
|
||||
.name = "pcc-cpufreq",
|
||||
};
|
||||
|
||||
|
@ -219,7 +219,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
|
||||
}
|
||||
|
||||
|
||||
static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void powernow_k6_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -234,10 +234,9 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
|
||||
cpufreq_freq_transition_begin(policy, &freqs);
|
||||
powernow_k6_target(policy, i);
|
||||
cpufreq_freq_transition_end(policy, &freqs, 0);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int powernow_k6_get(unsigned int cpu)
|
||||
|
@ -644,7 +644,7 @@ static int powernow_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int powernow_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void powernow_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
|
||||
if (acpi_processor_perf) {
|
||||
@ -655,7 +655,6 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy)
|
||||
#endif
|
||||
|
||||
kfree(powernow_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver powernow_driver = {
|
||||
|
@ -1089,13 +1089,13 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
|
||||
static void powernowk8_cpu_exit(struct cpufreq_policy *pol)
|
||||
{
|
||||
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
|
||||
int cpu;
|
||||
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
powernow_k8_cpu_exit_acpi(data);
|
||||
|
||||
@ -1104,8 +1104,6 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
|
||||
/* pol->cpus will be empty here, use related_cpus instead. */
|
||||
for_each_cpu(cpu, pol->related_cpus)
|
||||
per_cpu(powernow_data, cpu) = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void query_values_on_cpu(void *_err)
|
||||
|
@ -874,7 +874,7 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct powernv_smp_call_data freq_data;
|
||||
struct global_pstate_info *gpstates = policy->driver_data;
|
||||
@ -886,8 +886,6 @@ static int powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
del_timer_sync(&gpstates->timer);
|
||||
|
||||
kfree(policy->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int powernv_cpufreq_reboot_notifier(struct notifier_block *nb,
|
||||
|
@ -113,10 +113,9 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
cbe_cpufreq_pmi_policy_exit(policy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbe_cpufreq_target(struct cpufreq_policy *policy,
|
||||
|
@ -573,7 +573,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
|
||||
return qcom_cpufreq_hw_lmh_init(policy, index);
|
||||
}
|
||||
|
||||
static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct device *cpu_dev = get_cpu_device(policy->cpu);
|
||||
struct qcom_cpufreq_data *data = policy->driver_data;
|
||||
@ -583,8 +583,6 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
||||
qcom_cpufreq_hw_lmh_exit(data);
|
||||
kfree(policy->freq_table);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
|
||||
|
@ -455,7 +455,6 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_cpufreq_drv *drv;
|
||||
struct nvmem_cell *speedbin_nvmem;
|
||||
struct device_node *np;
|
||||
struct device *cpu_dev;
|
||||
char pvs_name_buffer[] = "speedXX-pvsXX-vXX";
|
||||
char *pvs_name = pvs_name_buffer;
|
||||
@ -467,16 +466,15 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
|
||||
if (!cpu_dev)
|
||||
return -ENODEV;
|
||||
|
||||
np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
struct device_node *np __free(device_node) =
|
||||
dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
|
||||
ret = of_device_is_compatible(np, "operating-points-v2-kryo-cpu") ||
|
||||
of_device_is_compatible(np, "operating-points-v2-krait-cpu");
|
||||
if (!ret) {
|
||||
of_node_put(np);
|
||||
if (!ret)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
drv = devm_kzalloc(&pdev->dev, struct_size(drv, cpus, num_possible_cpus()),
|
||||
GFP_KERNEL);
|
||||
@ -502,7 +500,6 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
|
||||
}
|
||||
nvmem_cell_put(speedbin_nvmem);
|
||||
}
|
||||
of_node_put(np);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct device **virt_devs = NULL;
|
||||
@ -638,7 +635,7 @@ MODULE_DEVICE_TABLE(of, qcom_cpufreq_match_list);
|
||||
*/
|
||||
static int __init qcom_cpufreq_init(void)
|
||||
{
|
||||
struct device_node *np = of_find_node_by_path("/");
|
||||
struct device_node *np __free(device_node) = of_find_node_by_path("/");
|
||||
const struct of_device_id *match;
|
||||
int ret;
|
||||
|
||||
@ -646,7 +643,6 @@ static int __init qcom_cpufreq_init(void)
|
||||
return -ENODEV;
|
||||
|
||||
match = of_match_node(qcom_cpufreq_match_list, np);
|
||||
of_node_put(np);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -225,7 +225,7 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpu_data *data = policy->driver_data;
|
||||
|
||||
@ -233,8 +233,6 @@ static int qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
kfree(data->table);
|
||||
kfree(data);
|
||||
policy->driver_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
|
||||
|
@ -63,9 +63,9 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
struct scmi_data *priv = policy->driver_data;
|
||||
unsigned long freq = target_freq;
|
||||
|
||||
if (!perf_ops->freq_set(ph, priv->domain_id,
|
||||
target_freq * 1000, true))
|
||||
if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true))
|
||||
return target_freq;
|
||||
|
||||
return 0;
|
||||
@ -308,7 +308,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void scmi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct scmi_data *priv = policy->driver_data;
|
||||
|
||||
@ -316,8 +316,6 @@ static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
|
||||
free_cpumask_var(priv->opp_shared_cpus);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void scmi_cpufreq_register_em(struct cpufreq_policy *policy)
|
||||
|
@ -167,7 +167,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scpi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void scpi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct scpi_data *priv = policy->driver_data;
|
||||
|
||||
@ -175,8 +175,6 @@ static int scpi_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
|
||||
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver scpi_cpufreq_driver = {
|
||||
|
@ -135,14 +135,12 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void sh_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int cpu = policy->cpu;
|
||||
struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu);
|
||||
|
||||
clk_put(cpuclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver sh_cpufreq_driver = {
|
||||
|
@ -296,10 +296,9 @@ static int us2e_freq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int us2e_freq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void us2e_freq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
us2e_freq_target(policy, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver cpufreq_us2e_driver = {
|
||||
|
@ -140,10 +140,9 @@ static int us3_freq_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int us3_freq_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void us3_freq_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
us3_freq_target(policy, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver cpufreq_us3_driver = {
|
||||
|
@ -400,16 +400,12 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int centrino_cpu_exit(struct cpufreq_policy *policy)
|
||||
static void centrino_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int cpu = policy->cpu;
|
||||
|
||||
if (!per_cpu(centrino_model, cpu))
|
||||
return -ENODEV;
|
||||
|
||||
per_cpu(centrino_model, cpu) = NULL;
|
||||
|
||||
return 0;
|
||||
if (per_cpu(centrino_model, cpu))
|
||||
per_cpu(centrino_model, cpu) = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define VERSION_ELEMENTS 3
|
||||
#define MAX_PCODE_NAME_LEN 7
|
||||
#define MAX_PCODE_NAME_LEN 16
|
||||
|
||||
#define VERSION_SHIFT 28
|
||||
#define HW_INFO_INDEX 1
|
||||
@ -293,6 +293,7 @@ module_init(sti_cpufreq_init);
|
||||
static const struct of_device_id __maybe_unused sti_cpufreq_of_match[] = {
|
||||
{ .compatible = "st,stih407" },
|
||||
{ .compatible = "st,stih410" },
|
||||
{ .compatible = "st,stih418" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sti_cpufreq_of_match);
|
||||
|
@ -91,6 +91,9 @@ static u32 sun50i_h616_efuse_xlate(u32 speedbin)
|
||||
case 0x5d00:
|
||||
value = 0;
|
||||
break;
|
||||
case 0x6c00:
|
||||
value = 5;
|
||||
break;
|
||||
default:
|
||||
pr_warn("sun50i-cpufreq-nvmem: unknown speed bin 0x%x, using default bin 0\n",
|
||||
speedbin & 0xffff);
|
||||
@ -131,26 +134,24 @@ static const struct of_device_id cpu_opp_match_list[] = {
|
||||
static bool dt_has_supported_hw(void)
|
||||
{
|
||||
bool has_opp_supported_hw = false;
|
||||
struct device_node *np, *opp;
|
||||
struct device *cpu_dev;
|
||||
|
||||
cpu_dev = get_cpu_device(0);
|
||||
if (!cpu_dev)
|
||||
return false;
|
||||
|
||||
np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
struct device_node *np __free(device_node) =
|
||||
dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
if (!np)
|
||||
return false;
|
||||
|
||||
for_each_child_of_node(np, opp) {
|
||||
for_each_child_of_node_scoped(np, opp) {
|
||||
if (of_find_property(opp, "opp-supported-hw", NULL)) {
|
||||
has_opp_supported_hw = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
return has_opp_supported_hw;
|
||||
}
|
||||
|
||||
@ -165,7 +166,6 @@ static int sun50i_cpufreq_get_efuse(void)
|
||||
const struct sunxi_cpufreq_data *opp_data;
|
||||
struct nvmem_cell *speedbin_nvmem;
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np;
|
||||
struct device *cpu_dev;
|
||||
u32 *speedbin;
|
||||
int ret;
|
||||
@ -174,19 +174,18 @@ static int sun50i_cpufreq_get_efuse(void)
|
||||
if (!cpu_dev)
|
||||
return -ENODEV;
|
||||
|
||||
np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
struct device_node *np __free(device_node) =
|
||||
dev_pm_opp_of_get_opp_desc_node(cpu_dev);
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
|
||||
match = of_match_node(cpu_opp_match_list, np);
|
||||
if (!match) {
|
||||
of_node_put(np);
|
||||
if (!match)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
opp_data = match->data;
|
||||
|
||||
speedbin_nvmem = of_nvmem_cell_get(np, NULL);
|
||||
of_node_put(np);
|
||||
if (IS_ERR(speedbin_nvmem))
|
||||
return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
|
||||
"Could not get nvmem cell\n");
|
||||
@ -301,14 +300,9 @@ MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list);
|
||||
|
||||
static const struct of_device_id *sun50i_cpufreq_match_node(void)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np;
|
||||
struct device_node *np __free(device_node) = of_find_node_by_path("/");
|
||||
|
||||
np = of_find_node_by_path("/");
|
||||
match = of_match_node(sun50i_cpufreq_match_list, np);
|
||||
of_node_put(np);
|
||||
|
||||
return match;
|
||||
return of_match_node(sun50i_cpufreq_match_list, np);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -551,14 +551,12 @@ static int tegra194_cpufreq_offline(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra194_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void tegra194_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct device *cpu_dev = get_cpu_device(policy->cpu);
|
||||
|
||||
dev_pm_opp_remove_all_dynamic(cpu_dev);
|
||||
dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra194_cpufreq_set_target(struct cpufreq_policy *policy,
|
||||
|
@ -47,6 +47,35 @@
|
||||
#define AM625_SUPPORT_S_MPU_OPP BIT(1)
|
||||
#define AM625_SUPPORT_T_MPU_OPP BIT(2)
|
||||
|
||||
enum {
|
||||
AM62A7_EFUSE_M_MPU_OPP = 13,
|
||||
AM62A7_EFUSE_N_MPU_OPP,
|
||||
AM62A7_EFUSE_O_MPU_OPP,
|
||||
AM62A7_EFUSE_P_MPU_OPP,
|
||||
AM62A7_EFUSE_Q_MPU_OPP,
|
||||
AM62A7_EFUSE_R_MPU_OPP,
|
||||
AM62A7_EFUSE_S_MPU_OPP,
|
||||
/*
|
||||
* The V, U, and T speed grade numbering is out of order
|
||||
* to align with the AM625 more uniformly. I promise I know
|
||||
* my ABCs ;)
|
||||
*/
|
||||
AM62A7_EFUSE_V_MPU_OPP,
|
||||
AM62A7_EFUSE_U_MPU_OPP,
|
||||
AM62A7_EFUSE_T_MPU_OPP,
|
||||
};
|
||||
|
||||
#define AM62A7_SUPPORT_N_MPU_OPP BIT(0)
|
||||
#define AM62A7_SUPPORT_R_MPU_OPP BIT(1)
|
||||
#define AM62A7_SUPPORT_V_MPU_OPP BIT(2)
|
||||
|
||||
#define AM62P5_EFUSE_O_MPU_OPP 15
|
||||
#define AM62P5_EFUSE_S_MPU_OPP 19
|
||||
#define AM62P5_EFUSE_U_MPU_OPP 21
|
||||
|
||||
#define AM62P5_SUPPORT_O_MPU_OPP BIT(0)
|
||||
#define AM62P5_SUPPORT_U_MPU_OPP BIT(2)
|
||||
|
||||
#define VERSION_COUNT 2
|
||||
|
||||
struct ti_cpufreq_data;
|
||||
@ -112,6 +141,49 @@ static unsigned long omap3_efuse_xlate(struct ti_cpufreq_data *opp_data,
|
||||
return BIT(efuse);
|
||||
}
|
||||
|
||||
static unsigned long am62p5_efuse_xlate(struct ti_cpufreq_data *opp_data,
|
||||
unsigned long efuse)
|
||||
{
|
||||
unsigned long calculated_efuse = AM62P5_SUPPORT_O_MPU_OPP;
|
||||
|
||||
switch (efuse) {
|
||||
case AM62P5_EFUSE_U_MPU_OPP:
|
||||
case AM62P5_EFUSE_S_MPU_OPP:
|
||||
calculated_efuse |= AM62P5_SUPPORT_U_MPU_OPP;
|
||||
fallthrough;
|
||||
case AM62P5_EFUSE_O_MPU_OPP:
|
||||
calculated_efuse |= AM62P5_SUPPORT_O_MPU_OPP;
|
||||
}
|
||||
|
||||
return calculated_efuse;
|
||||
}
|
||||
|
||||
static unsigned long am62a7_efuse_xlate(struct ti_cpufreq_data *opp_data,
|
||||
unsigned long efuse)
|
||||
{
|
||||
unsigned long calculated_efuse = AM62A7_SUPPORT_N_MPU_OPP;
|
||||
|
||||
switch (efuse) {
|
||||
case AM62A7_EFUSE_V_MPU_OPP:
|
||||
case AM62A7_EFUSE_U_MPU_OPP:
|
||||
case AM62A7_EFUSE_T_MPU_OPP:
|
||||
case AM62A7_EFUSE_S_MPU_OPP:
|
||||
calculated_efuse |= AM62A7_SUPPORT_V_MPU_OPP;
|
||||
fallthrough;
|
||||
case AM62A7_EFUSE_R_MPU_OPP:
|
||||
case AM62A7_EFUSE_Q_MPU_OPP:
|
||||
case AM62A7_EFUSE_P_MPU_OPP:
|
||||
case AM62A7_EFUSE_O_MPU_OPP:
|
||||
calculated_efuse |= AM62A7_SUPPORT_R_MPU_OPP;
|
||||
fallthrough;
|
||||
case AM62A7_EFUSE_N_MPU_OPP:
|
||||
case AM62A7_EFUSE_M_MPU_OPP:
|
||||
calculated_efuse |= AM62A7_SUPPORT_N_MPU_OPP;
|
||||
}
|
||||
|
||||
return calculated_efuse;
|
||||
}
|
||||
|
||||
static unsigned long am625_efuse_xlate(struct ti_cpufreq_data *opp_data,
|
||||
unsigned long efuse)
|
||||
{
|
||||
@ -234,6 +306,24 @@ static struct ti_cpufreq_soc_data am625_soc_data = {
|
||||
.multi_regulator = false,
|
||||
};
|
||||
|
||||
static struct ti_cpufreq_soc_data am62a7_soc_data = {
|
||||
.efuse_xlate = am62a7_efuse_xlate,
|
||||
.efuse_offset = 0x0,
|
||||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.rev_offset = 0x0014,
|
||||
.multi_regulator = false,
|
||||
};
|
||||
|
||||
static struct ti_cpufreq_soc_data am62p5_soc_data = {
|
||||
.efuse_xlate = am62p5_efuse_xlate,
|
||||
.efuse_offset = 0x0,
|
||||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.rev_offset = 0x0014,
|
||||
.multi_regulator = false,
|
||||
};
|
||||
|
||||
/**
|
||||
* ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC
|
||||
* @opp_data: pointer to ti_cpufreq_data context
|
||||
@ -337,8 +427,8 @@ static const struct of_device_id ti_cpufreq_of_match[] = {
|
||||
{ .compatible = "ti,omap34xx", .data = &omap34xx_soc_data, },
|
||||
{ .compatible = "ti,omap36xx", .data = &omap36xx_soc_data, },
|
||||
{ .compatible = "ti,am625", .data = &am625_soc_data, },
|
||||
{ .compatible = "ti,am62a7", .data = &am625_soc_data, },
|
||||
{ .compatible = "ti,am62p5", .data = &am625_soc_data, },
|
||||
{ .compatible = "ti,am62a7", .data = &am62a7_soc_data, },
|
||||
{ .compatible = "ti,am62p5", .data = &am62p5_soc_data, },
|
||||
/* legacy */
|
||||
{ .compatible = "ti,omap3430", .data = &omap34xx_soc_data, },
|
||||
{ .compatible = "ti,omap3630", .data = &omap36xx_soc_data, },
|
||||
@ -417,7 +507,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
|
||||
|
||||
ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config);
|
||||
if (ret < 0) {
|
||||
dev_err(opp_data->cpu_dev, "Failed to set OPP config\n");
|
||||
dev_err_probe(opp_data->cpu_dev, ret, "Failed to set OPP config\n");
|
||||
goto fail_put_node;
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,7 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static void ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct device *cpu_dev;
|
||||
|
||||
@ -455,11 +455,10 @@ static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
if (!cpu_dev) {
|
||||
pr_err("%s: failed to get cpu%d device\n", __func__,
|
||||
policy->cpu);
|
||||
return -ENODEV;
|
||||
return;
|
||||
}
|
||||
|
||||
put_cluster_clk_and_freq_table(cpu_dev, policy->related_cpus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver ve_spc_cpufreq_driver = {
|
||||
|
@ -393,10 +393,12 @@ static int ti_opp_supply_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ret = dev_pm_opp_set_config_regulators(cpu_dev, ti_opp_config_regulators);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
_free_optimized_voltages(dev, &opp_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ti_opp_supply_driver = {
|
||||
|
@ -396,7 +396,7 @@ struct cpufreq_driver {
|
||||
|
||||
int (*online)(struct cpufreq_policy *policy);
|
||||
int (*offline)(struct cpufreq_policy *policy);
|
||||
int (*exit)(struct cpufreq_policy *policy);
|
||||
void (*exit)(struct cpufreq_policy *policy);
|
||||
int (*suspend)(struct cpufreq_policy *policy);
|
||||
int (*resume)(struct cpufreq_policy *policy);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user