summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig.arm13
-rw-r--r--drivers/cpufreq/Makefile1
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c20
-rw-r--r--drivers/cpufreq/arm_big_little.c9
-rw-r--r--drivers/cpufreq/armada-37xx-cpufreq.c2
-rw-r--r--drivers/cpufreq/brcmstb-avs-cpufreq.c6
-rw-r--r--drivers/cpufreq/cppc_cpufreq.c27
-rw-r--r--drivers/cpufreq/cpufreq-dt.c8
-rw-r--r--drivers/cpufreq/cpufreq.c28
-rw-r--r--drivers/cpufreq/e_powersaver.c8
-rw-r--r--drivers/cpufreq/elanfreq.c3
-rw-r--r--drivers/cpufreq/freq_table.c10
-rw-r--r--drivers/cpufreq/ia64-acpi-cpufreq.c7
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c7
-rw-r--r--drivers/cpufreq/intel_pstate.c1
-rw-r--r--drivers/cpufreq/longhaul.c3
-rw-r--r--drivers/cpufreq/mediatek-cpufreq.c13
-rw-r--r--drivers/cpufreq/p4-clockmod.c3
-rw-r--r--drivers/cpufreq/powernow-k6.c3
-rw-r--r--drivers/cpufreq/powernow-k7.c3
-rw-r--r--drivers/cpufreq/powernow-k8.c24
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c11
-rw-r--r--drivers/cpufreq/ppc_cbe_cpufreq.c5
-rw-r--r--drivers/cpufreq/pxa2xx-cpufreq.c4
-rw-r--r--drivers/cpufreq/pxa3xx-cpufreq.c4
-rw-r--r--drivers/cpufreq/qoriq-cpufreq.c21
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c13
-rw-r--r--drivers/cpufreq/sc520_freq.c3
-rw-r--r--drivers/cpufreq/scmi-cpufreq.c256
-rw-r--r--drivers/cpufreq/scpi-cpufreq.c10
-rw-r--r--drivers/cpufreq/sfi-cpufreq.c3
-rw-r--r--drivers/cpufreq/sh-cpufreq.c22
-rw-r--r--drivers/cpufreq/sparc-us2e-cpufreq.c3
-rw-r--r--drivers/cpufreq/sparc-us3-cpufreq.c3
-rw-r--r--drivers/cpufreq/speedstep-centrino.c4
-rw-r--r--drivers/cpufreq/speedstep-ich.c4
-rw-r--r--drivers/cpufreq/speedstep-smi.c4
-rw-r--r--drivers/cpufreq/tegra186-cpufreq.c3
-rw-r--r--drivers/cpufreq/ti-cpufreq.c2
39 files changed, 397 insertions, 177 deletions
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index fb586e09682d..7f56fe5183f2 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -45,6 +45,7 @@ config ARM_DT_BL_CPUFREQ
config ARM_SCPI_CPUFREQ
tristate "SCPI based CPUfreq driver"
depends on ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
+ depends on !CPU_THERMAL || THERMAL
help
This adds the CPUfreq driver support for ARM platforms using SCPI
protocol for CPU power management.
@@ -238,6 +239,18 @@ config ARM_SA1100_CPUFREQ
config ARM_SA1110_CPUFREQ
bool
+config ARM_SCMI_CPUFREQ
+ tristate "SCMI based CPUfreq driver"
+ depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+ depends on !CPU_THERMAL || THERMAL
+ select PM_OPP
+ help
+ This adds the CPUfreq driver support for ARM platforms using SCMI
+ protocol for CPU power management.
+
+ This driver uses SCMI Message Protocol driver to interact with the
+ firmware providing the CPU DVFS functionality.
+
config ARM_SPEAR_CPUFREQ
bool "SPEAr CPUFreq support"
depends on PLAT_SPEAR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index b2cbdc016c77..8d24ade3bd02 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o
obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o
+obj-$(CONFIG_ARM_SCMI_CPUFREQ) += scmi-cpufreq.o
obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o
obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index d0c34df0529c..9449657d72f0 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -794,15 +794,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
valid_states++;
}
freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
+ policy->freq_table = freq_table;
perf->state = 0;
- result = cpufreq_table_validate_and_show(policy, freq_table);
- if (result)
- goto err_freqfree;
-
- if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
- pr_warn(FW_WARN "P-state 0 is not max freq\n");
-
switch (perf->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
/*
@@ -842,8 +836,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
return result;
-err_freqfree:
- kfree(freq_table);
err_unreg:
acpi_processor_unregister_performance(cpu);
err_free_mask:
@@ -871,6 +863,15 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
+static void acpi_cpufreq_cpu_ready(struct cpufreq_policy *policy)
+{
+ struct acpi_processor_performance *perf = per_cpu_ptr(acpi_perf_data,
+ policy->cpu);
+
+ if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
+ pr_warn(FW_WARN "P-state 0 is not max freq\n");
+}
+
static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
{
struct acpi_cpufreq_data *data = policy->driver_data;
@@ -898,6 +899,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.bios_limit = acpi_processor_get_bios_limit,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
+ .ready = acpi_cpufreq_cpu_ready,
.resume = acpi_cpufreq_resume,
.name = "acpi-cpufreq",
.attr = acpi_cpufreq_attr,
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index c56b57dcfda5..1d7ef5fc1977 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -483,14 +483,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
if (ret)
return ret;
- ret = cpufreq_table_validate_and_show(policy, freq_table[cur_cluster]);
- if (ret) {
- dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n",
- policy->cpu, cur_cluster);
- put_cluster_clk_and_freq_table(cpu_dev, policy->cpus);
- return ret;
- }
-
+ policy->freq_table = freq_table[cur_cluster];
policy->cpuinfo.transition_latency =
arm_bL_ops->get_transition_latency(cpu_dev);
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
index c6ebc88a7d8d..72a2975499db 100644
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -202,6 +202,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
cur_frequency = clk_get_rate(clk);
if (!cur_frequency) {
dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
+ clk_put(clk);
return -EINVAL;
}
@@ -210,6 +211,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
return -EINVAL;
armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
+ clk_put(clk);
for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
load_lvl++) {
diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c
index 7281a2c19c36..6cdac1aaf23c 100644
--- a/drivers/cpufreq/brcmstb-avs-cpufreq.c
+++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c
@@ -902,11 +902,7 @@ static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy)
return ret;
}
- ret = cpufreq_table_validate_and_show(policy, freq_table);
- if (ret) {
- dev_err(dev, "invalid frequency table: %d\n", ret);
- return ret;
- }
+ policy->freq_table = freq_table;
/* All cores share the same clock and thus the same policy. */
cpumask_setall(policy->cpus);
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index a1c3025f9df7..bc5fc1630876 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -20,6 +20,7 @@
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/dmi.h>
+#include <linux/time.h>
#include <linux/vmalloc.h>
#include <asm/unaligned.h>
@@ -161,12 +162,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpu->perf_caps.highest_perf;
policy->cpuinfo.max_freq = cppc_dmi_max_khz;
- policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num);
+ policy->transition_delay_us = cppc_get_transition_latency(cpu_num) /
+ NSEC_PER_USEC;
policy->shared_type = cpu->shared_type;
- if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+ if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+ int i;
+
cpumask_copy(policy->cpus, cpu->shared_cpu_map);
- else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
+
+ for_each_cpu(i, policy->cpus) {
+ if (unlikely(i == policy->cpu))
+ continue;
+
+ memcpy(&all_cpu_data[i]->perf_caps, &cpu->perf_caps,
+ sizeof(cpu->perf_caps));
+ }
+ } else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
/* Support only SW_ANY for now. */
pr_debug("Unsupported CPU co-ord type\n");
return -EFAULT;
@@ -230,8 +242,13 @@ static int __init cppc_cpufreq_init(void)
return ret;
out:
- for_each_possible_cpu(i)
- kfree(all_cpu_data[i]);
+ for_each_possible_cpu(i) {
+ cpu = all_cpu_data[i];
+ if (!cpu)
+ break;
+ free_cpumask_var(cpu->shared_cpu_map);
+ kfree(cpu);
+ }
kfree(all_cpu_data);
return -ENODEV;
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index de3d104c25d7..190ea0dccb79 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -258,16 +258,10 @@ static int cpufreq_init(struct cpufreq_policy *policy)
priv->cpu_dev = cpu_dev;
policy->driver_data = priv;
policy->clk = cpu_clk;
+ policy->freq_table = freq_table;
policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000;
- ret = cpufreq_table_validate_and_show(policy, freq_table);
- if (ret) {
- dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__,
- ret);
- goto out_free_cpufreq_table;
- }
-
/* Support turbo/boost mode */
if (policy_has_boost_freq(policy)) {
/* This gets disabled by core on driver unregister */
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index de33ebf008ad..075d18f6ba7a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -178,14 +178,7 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int transition_latency)
{
- int ret;
-
- ret = cpufreq_table_validate_and_show(policy, table);
- if (ret) {
- pr_err("%s: invalid frequency table: %d\n", __func__, ret);
- return ret;
- }
-
+ policy->freq_table = table;
policy->cpuinfo.transition_latency = transition_latency;
/*
@@ -1219,6 +1212,10 @@ static int cpufreq_online(unsigned int cpu)
goto out_free_policy;
}
+ ret = cpufreq_table_validate_and_sort(policy);
+ if (ret)
+ goto out_exit_policy;
+
down_write(&policy->rwsem);
if (new_policy) {
@@ -1249,7 +1246,7 @@ static int cpufreq_online(unsigned int cpu)
policy->cur = cpufreq_driver->get(policy->cpu);
if (!policy->cur) {
pr_err("%s: ->get() failed\n", __func__);
- goto out_exit_policy;
+ goto out_destroy_policy;
}
}
@@ -1296,7 +1293,7 @@ static int cpufreq_online(unsigned int cpu)
if (new_policy) {
ret = cpufreq_add_dev_interface(policy);
if (ret)
- goto out_exit_policy;
+ goto out_destroy_policy;
cpufreq_stats_create_table(policy);
@@ -1311,7 +1308,7 @@ static int cpufreq_online(unsigned int cpu)
__func__, cpu, ret);
/* cpufreq_policy_free() will notify based on this */
new_policy = false;
- goto out_exit_policy;
+ goto out_destroy_policy;
}
up_write(&policy->rwsem);
@@ -1326,15 +1323,16 @@ static int cpufreq_online(unsigned int cpu)
return 0;
-out_exit_policy:
+out_destroy_policy:
+ for_each_cpu(j, policy->real_cpus)
+ remove_cpu_dev_symlink(policy, get_cpu_device(j));
+
up_write(&policy->rwsem);
+out_exit_policy:
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
- for_each_cpu(j, policy->real_cpus)
- remove_cpu_dev_symlink(policy, get_cpu_device(j));
-
out_free_policy:
cpufreq_policy_free(policy);
return ret;
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index cdf097b29862..60bea302abbe 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -184,7 +184,6 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
struct cpuinfo_x86 *c = &cpu_data(0);
struct cpufreq_frequency_table *f_table;
int k, step, voltage;
- int ret;
int states;
#if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
unsigned int limit;
@@ -359,12 +358,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
}
policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */
-
- ret = cpufreq_table_validate_and_show(policy, &centaur->freq_table[0]);
- if (ret) {
- kfree(centaur);
- return ret;
- }
+ policy->freq_table = &centaur->freq_table[0];
return 0;
}
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index 45e2ca62515e..03419f064752 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -165,7 +165,8 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
if (pos->frequency > max_freq)
pos->frequency = CPUFREQ_ENTRY_INVALID;
- return cpufreq_table_validate_and_show(policy, elanfreq_table);
+ policy->freq_table = elanfreq_table;
+ return 0;
}
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 6d007f824ca7..3a8cc99e6815 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -352,19 +352,19 @@ static int set_freq_table_sorted(struct cpufreq_policy *policy)
return 0;
}
-int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table)
+int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy)
{
int ret;
- ret = cpufreq_frequency_table_cpuinfo(policy, table);
+ if (!policy->freq_table)
+ return 0;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);
if (ret)
return ret;
- policy->freq_table = table;
return set_freq_table_sorted(policy);
}
-EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show);
MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION("CPUfreq frequency table helpers");
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c
index a757c0a1e7b5..7974a2fdb760 100644
--- a/drivers/cpufreq/ia64-acpi-cpufreq.c
+++ b/drivers/cpufreq/ia64-acpi-cpufreq.c
@@ -270,10 +270,7 @@ acpi_cpufreq_cpu_init (
}
}
- result = cpufreq_table_validate_and_show(policy, freq_table);
- if (result) {
- goto err_freqfree;
- }
+ policy->freq_table = freq_table;
/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);
@@ -296,8 +293,6 @@ acpi_cpufreq_cpu_init (
return (result);
- err_freqfree:
- kfree(freq_table);
err_unreg:
acpi_processor_unregister_performance(cpu);
err_free:
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index ff67859948b3..83cf631fc9bc 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -52,6 +52,7 @@ static struct clk_bulk_data clks[] = {
static struct device *cpu_dev;
static bool free_opp;
static struct cpufreq_frequency_table *freq_table;
+static unsigned int max_freq;
static unsigned int transition_latency;
static u32 *imx6_soc_volt;
@@ -196,7 +197,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
policy->clk = clks[ARM].clk;
ret = cpufreq_generic_init(policy, freq_table, transition_latency);
- policy->suspend_freq = policy->max;
+ policy->suspend_freq = max_freq;
return ret;
}
@@ -437,12 +438,12 @@ soc_opp_out:
* freq_table initialised from OPP is therefore sorted in the
* same order.
*/
+ max_freq = freq_table[--num].frequency;
opp = dev_pm_opp_find_freq_exact(cpu_dev,
freq_table[0].frequency * 1000, true);
min_volt = dev_pm_opp_get_voltage(opp);
dev_pm_opp_put(opp);
- opp = dev_pm_opp_find_freq_exact(cpu_dev,
- freq_table[--num].frequency * 1000, true);
+ opp = dev_pm_opp_find_freq_exact(cpu_dev, max_freq * 1000, true);
max_volt = dev_pm_opp_get_voltage(opp);
dev_pm_opp_put(opp);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6d084c61ee25..17e566afbb41 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -26,7 +26,6 @@
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/debugfs.h>
#include <linux/acpi.h>
#include <linux/vmalloc.h>
#include <trace/events/power.h>
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index f730b6528c18..61a4c5b08219 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -895,8 +895,9 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
longhaul_setup_voltagescaling();
policy->transition_delay_us = 200000; /* usec */
+ policy->freq_table = longhaul_table;
- return cpufreq_table_validate_and_show(policy, longhaul_table);
+ return 0;
}
static struct cpufreq_driver longhaul_driver = {
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 8c04dddd3c28..eb8920d39818 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -460,21 +460,12 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
return ret;
}
- ret = cpufreq_table_validate_and_show(policy, freq_table);
- if (ret) {
- pr_err("%s: invalid frequency table: %d\n", __func__, ret);
- goto out_free_cpufreq_table;
- }
-
cpumask_copy(policy->cpus, &info->cpus);
+ policy->freq_table = freq_table;
policy->driver_data = info;
policy->clk = info->cpu_clk;
return 0;
-
-out_free_cpufreq_table:
- dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
- return ret;
}
static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
@@ -578,7 +569,7 @@ static int __init mtk_cpufreq_driver_init(void)
match = of_match_node(mtk_cpufreq_machines, np);
of_node_put(np);
if (!match) {
- pr_warn("Machine is not compatible with mtk-cpufreq\n");
+ pr_debug("Machine is not compatible with mtk-cpufreq\n");
return -ENODEV;
}
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
index a25741b1281b..911206243050 100644
--- a/drivers/cpufreq/p4-clockmod.c
+++ b/drivers/cpufreq/p4-clockmod.c
@@ -202,8 +202,9 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
/* the transition latency is set to be 1 higher than the maximum
* transition latency of the ondemand governor */
policy->cpuinfo.transition_latency = 10000001;
+ policy->freq_table = &p4clockmod_table[0];
- return cpufreq_table_validate_and_show(policy, &p4clockmod_table[0]);
+ return 0;
}
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index dedd2568e852..8a8ea68611a8 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -214,8 +214,9 @@ have_busfreq:
/* cpuinfo and default policy values */
policy->cpuinfo.transition_latency = 500000;
+ policy->freq_table = clock_ratio;
- return cpufreq_table_validate_and_show(policy, clock_ratio);
+ return 0;
}
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index 302e9ce793a0..d6cb052b0a75 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -639,8 +639,9 @@ static int powernow_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency =
cpufreq_scale(2000000UL, fsb, latency);
+ policy->freq_table = powernow_table;
- return cpufreq_table_validate_and_show(policy, powernow_table);
+ return 0;
}
static int powernow_cpu_exit(struct cpufreq_policy *policy)
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index b01e31db5f83..fb77b39a4ce3 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -122,14 +122,12 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
static void count_off_irt(struct powernow_k8_data *data)
{
udelay((1 << data->irt) * 10);
- return;
}
/* the voltage stabilization time */
static void count_off_vst(struct powernow_k8_data *data)
{
udelay(data->vstable * VST_UNITS_20US);
- return;
}
/* need to init the control msr to a safe value (for each cpu) */
@@ -591,10 +589,8 @@ static int fill_powernow_table(struct powernow_k8_data *data,
powernow_table = kzalloc((sizeof(*powernow_table)
* (data->numps + 1)), GFP_KERNEL);
- if (!powernow_table) {
- pr_err("powernow_table memory alloc failure\n");
+ if (!powernow_table)
return -ENOMEM;
- }
for (j = 0; j < data->numps; j++) {
int freq;
@@ -760,10 +756,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
/* fill in data->powernow_table */
powernow_table = kzalloc((sizeof(*powernow_table)
* (data->acpi_data.state_count + 1)), GFP_KERNEL);
- if (!powernow_table) {
- pr_debug("powernow_table memory alloc failure\n");
+ if (!powernow_table)
goto err_out;
- }
/* fill in data */
data->numps = data->acpi_data.state_count;
@@ -1042,10 +1036,8 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
return -ENODEV;
data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- pr_err("unable to alloc powernow_k8_data\n");
+ if (!data)
return -ENOMEM;
- }
data->cpu = pol->cpu;
@@ -1084,15 +1076,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
cpumask_copy(pol->cpus, topology_core_cpumask(pol->cpu));
data->available_cores = pol->cpus;
-
- /* min/max the cpu is capable of */
- if (cpufreq_table_validate_and_show(pol, data->powernow_table)) {
- pr_err(FW_BUG "invalid powernow_table\n");
- powernow_k8_cpu_exit_acpi(data);
- kfree(data->powernow_table);
- kfree(data);
- return -EINVAL;
- }
+ pol->freq_table = data->powernow_table;
pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 29cdec198657..0591874856d3 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -812,7 +812,7 @@ gpstates_done:
static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
- int base, i, ret;
+ int base, i;
struct kernfs_node *kn;
struct global_pstate_info *gpstates;
@@ -848,15 +848,10 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
gpstates->timer.expires = jiffies +
msecs_to_jiffies(GPSTATE_TIMER_INTERVAL);
spin_lock_init(&gpstates->gpstate_lock);
- ret = cpufreq_table_validate_and_show(policy, powernv_freqs);
-
- if (ret < 0) {
- kfree(policy->driver_data);
- return ret;
- }
+ policy->freq_table = powernv_freqs;
policy->fast_switch_possible = true;
- return ret;
+ return 0;
}
static int powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy)
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
index 5a4c5a639f61..41a0f0be3f9f 100644
--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
@@ -121,9 +121,8 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
- /* this ensures that policy->cpuinfo_min
- * and policy->cpuinfo_max are set correctly */
- return cpufreq_table_validate_and_show(policy, cbe_freqs);
+ policy->freq_table = cbe_freqs;
+ return 0;
}
static int cbe_cpufreq_target(struct cpufreq_policy *policy,
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c
index 06b024a3e474..46254e583982 100644
--- a/drivers/cpufreq/pxa2xx-cpufreq.c
+++ b/drivers/cpufreq/pxa2xx-cpufreq.c
@@ -292,10 +292,10 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
pr_info("using %s frequency table\n",
pxa255_turbo_table ? "turbo" : "run");
- cpufreq_table_validate_and_show(policy, pxa255_freq_table);
+ policy->freq_table = pxa255_freq_table;
}
else if (cpu_is_pxa27x()) {
- cpufreq_table_validate_and_show(policy, pxa27x_freq_table);
+ policy->freq_table = pxa27x_freq_table;
}
pr_info("frequency change support initialized\n");
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c
index a01275900389..7acc7fa4536d 100644
--- a/drivers/cpufreq/pxa3xx-cpufreq.c
+++ b/drivers/cpufreq/pxa3xx-cpufreq.c
@@ -108,7 +108,9 @@ static int setup_freqs_table(struct cpufreq_policy *policy,
pxa3xx_freqs_num = num;
pxa3xx_freqs_table = table;
- return cpufreq_table_validate_and_show(policy, table);
+ policy->freq_table = table;
+
+ return 0;
}
static void __update_core_freq(struct pxa3xx_freq_info *info)
diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
index 0562761a3dec..3d773f64b4df 100644
--- a/drivers/cpufreq/qoriq-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -165,7 +165,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
struct device_node *np;
- int i, count, ret;
+ int i, count;
u32 freq;
struct clk *clk;
const struct clk_hw *hwclk;
@@ -192,16 +192,12 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
count = clk_hw_get_num_parents(hwclk);
data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
- if (!data->pclk) {
- pr_err("%s: no memory\n", __func__);
+ if (!data->pclk)
goto err_nomem2;
- }
table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
- if (!table) {
- pr_err("%s: no memory\n", __func__);
+ if (!table)
goto err_pclk;
- }
for (i = 0; i < count; i++) {
clk = clk_hw_get_parent_by_index(hwclk, i)->clk;
@@ -213,14 +209,7 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
freq_table_redup(table, count);
freq_table_sort(table, count);
table[i].frequency = CPUFREQ_TABLE_END;
-
- /* set the min and max frequency properly */
- ret = cpufreq_table_validate_and_show(policy, table);
- if (ret) {
- pr_err("invalid frequency table: %d\n", ret);
- goto err_nomem1;
- }
-
+ policy->freq_table = table;
data->table = table;
/* update ->cpus if we have cluster, no harm if not */
@@ -236,8 +225,6 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
return 0;
-err_nomem1:
- kfree(table);
err_pclk:
kfree(data->pclk);
err_nomem2:
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c
index 6bebc1f9f55a..909bd6e27639 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -351,11 +351,8 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
static int s3c_cpufreq_init(struct cpufreq_policy *policy)
{
policy->clk = clk_arm;
-
policy->cpuinfo.transition_latency = cpu_cur.info->latency;
-
- if (ftab)
- return cpufreq_table_validate_and_show(policy, ftab);
+ policy->freq_table = ftab;
return 0;
}
@@ -479,10 +476,8 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
* initdata. */
ours = kzalloc(sizeof(*ours), GFP_KERNEL);
- if (ours == NULL) {
- pr_err("%s: no memory\n", __func__);
+ if (!ours)
return -ENOMEM;
- }
*ours = *board;
cpu_cur.board = ours;
@@ -568,10 +563,8 @@ static int s3c_cpufreq_build_freq(void)
size++;
ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL);
- if (!ftab) {
- pr_err("%s: no memory for tables\n", __func__);
+ if (!ftab)
return -ENOMEM;
- }
ftab_size = size;
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
index 4225501a4b78..abaa75e86148 100644
--- a/drivers/cpufreq/sc520_freq.c
+++ b/drivers/cpufreq/sc520_freq.c
@@ -83,8 +83,9 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
policy->cpuinfo.transition_latency = 1000000; /* 1ms */
+ policy->freq_table = sc520_freq_table;
- return cpufreq_table_validate_and_show(policy, sc520_freq_table);
+ return 0;
}
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
new file mode 100644
index 000000000000..b4dbc77459b6
--- /dev/null
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Power Interface (SCMI) based CPUFreq Interface driver
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ * Sudeep Holla <sudeep.holla@arm.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_cooling.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/scmi_protocol.h>
+#include <linux/types.h>
+
+struct scmi_data {
+ int domain_id;
+ struct device *cpu_dev;
+ struct thermal_cooling_device *cdev;
+};
+
+static const struct scmi_handle *handle;
+
+static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
+{
+ struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
+ struct scmi_perf_ops *perf_ops = handle->perf_ops;
+ struct scmi_data *priv = policy->driver_data;
+ unsigned long rate;
+ int ret;
+
+ ret = perf_ops->freq_get(handle, priv->domain_id, &rate, false);
+ if (ret)
+ return 0;
+ return rate / 1000;
+}
+
+/*
+ * perf_ops->freq_set is not a synchronous, the actual OPP change will
+ * happen asynchronously and can get notified if the events are
+ * subscribed for by the SCMI firmware
+ */
+static int
+scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ int ret;
+ struct scmi_data *priv = policy->driver_data;
+ struct scmi_perf_ops *perf_ops = handle->perf_ops;
+ u64 freq = policy->freq_table[index].frequency * 1000;
+
+ ret = perf_ops->freq_set(handle, priv->domain_id, freq, false);
+ if (!ret)
+ arch_set_freq_scale(policy->related_cpus, freq,
+ policy->cpuinfo.max_freq);
+ return ret;
+}
+
+static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct scmi_data *priv = policy->driver_data;
+ struct scmi_perf_ops *perf_ops = handle->perf_ops;
+
+ if (!perf_ops->freq_set(handle, priv->domain_id,
+ target_freq * 1000, true)) {
+ arch_set_freq_scale(policy->related_cpus, target_freq,
+ policy->cpuinfo.max_freq);
+ return target_freq;
+ }
+
+ return 0;
+}
+
+static int
+scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+{
+ int cpu, domain, tdomain;
+ struct device *tcpu_dev;
+
+ domain = handle->perf_ops->device_domain_id(cpu_dev);
+ if (domain < 0)
+ return domain;
+
+ for_each_possible_cpu(cpu) {
+ if (cpu == cpu_dev->id)
+ continue;
+
+ tcpu_dev = get_cpu_device(cpu);
+ if (!tcpu_dev)
+ continue;
+
+ tdomain = handle->perf_ops->device_domain_id(tcpu_dev);
+ if (tdomain == domain)
+ cpumask_set_cpu(cpu, cpumask);
+ }
+
+ return 0;
+}
+
+static int scmi_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ unsigned int latency;
+ struct device *cpu_dev;
+ struct scmi_data *priv;
+ struct cpufreq_frequency_table *freq_table;
+
+ cpu_dev = get_cpu_device(policy->cpu);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu%d device\n", policy->cpu);
+ return -ENODEV;
+ }
+
+ ret = handle->perf_ops->add_opps_to_device(handle, cpu_dev);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to add opps to the device\n");
+ return ret;
+ }
+
+ ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to get sharing cpumask\n");
+ return ret;
+ }
+
+ ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
+ if (ret) {
+ dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = dev_pm_opp_get_opp_count(cpu_dev);
+ if (ret <= 0) {
+ dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n");
+ ret = -EPROBE_DEFER;
+ goto out_free_opp;
+ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto out_free_opp;
+ }
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+ goto out_free_priv;
+ }
+
+ priv->cpu_dev = cpu_dev;
+ priv->domain_id = handle->perf_ops->device_domain_id(cpu_dev);
+
+ policy->driver_data = priv;
+ policy->freq_table = freq_table;
+
+ /* SCMI allows DVFS request for any domain from any CPU */
+ policy->dvfs_possible_from_any_cpu = true;
+
+ latency = handle->perf_ops->get_transition_latency(handle, cpu_dev);
+ if (!latency)
+ latency = CPUFREQ_ETERNAL;
+
+ policy->cpuinfo.transition_latency = latency;
+
+ policy->fast_switch_possible = true;
+ return 0;
+
+out_free_priv:
+ kfree(priv);
+out_free_opp:
+ dev_pm_opp_cpumask_remove_table(policy->cpus);
+
+ return ret;
+}
+
+static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ struct scmi_data *priv = policy->driver_data;
+
+ cpufreq_cooling_unregister(priv->cdev);
+ dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+ kfree(priv);
+ dev_pm_opp_cpumask_remove_table(policy->related_cpus);
+
+ return 0;
+}
+
+static void scmi_cpufreq_ready(struct cpufreq_policy *policy)
+{
+ struct scmi_data *priv = policy->driver_data;
+
+ priv->cdev = of_cpufreq_cooling_register(policy);
+}
+
+static struct cpufreq_driver scmi_cpufreq_driver = {
+ .name = "scmi",
+ .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+ CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .attr = cpufreq_generic_attr,
+ .target_index = scmi_cpufreq_set_target,
+ .fast_switch = scmi_cpufreq_fast_switch,
+ .get = scmi_cpufreq_get_rate,
+ .init = scmi_cpufreq_init,
+ .exit = scmi_cpufreq_exit,
+ .ready = scmi_cpufreq_ready,
+};
+
+static int scmi_cpufreq_probe(struct scmi_device *sdev)
+{
+ int ret;
+
+ handle = sdev->handle;
+
+ if (!handle || !handle->perf_ops)
+ return -ENODEV;
+
+ ret = cpufreq_register_driver(&scmi_cpufreq_driver);
+ if (ret) {
+ dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static void scmi_cpufreq_remove(struct scmi_device *sdev)
+{
+ cpufreq_unregister_driver(&scmi_cpufreq_driver);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+ { SCMI_PROTOCOL_PERF },
+ { },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_cpufreq_drv = {
+ .name = "scmi-cpufreq",
+ .probe = scmi_cpufreq_probe,
+ .remove = scmi_cpufreq_remove,
+ .id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_cpufreq_drv);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI CPUFreq interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
index d300a163945f..87a98ec77773 100644
--- a/drivers/cpufreq/scpi-cpufreq.c
+++ b/drivers/cpufreq/scpi-cpufreq.c
@@ -158,13 +158,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
}
policy->driver_data = priv;
-
- ret = cpufreq_table_validate_and_show(policy, freq_table);
- if (ret) {
- dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__,
- ret);
- goto out_put_clk;
- }
+ policy->freq_table = freq_table;
/* scpi allows DVFS request for any domain from any CPU */
policy->dvfs_possible_from_any_cpu = true;
@@ -178,8 +172,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
policy->fast_switch_possible = false;
return 0;
-out_put_clk:
- clk_put(priv->clk);
out_free_cpufreq_table:
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
out_free_priv:
diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c
index 3779742f86e3..9767afe05da2 100644
--- a/drivers/cpufreq/sfi-cpufreq.c
+++ b/drivers/cpufreq/sfi-cpufreq.c
@@ -72,8 +72,9 @@ static int sfi_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
policy->cpuinfo.transition_latency = 100000; /* 100us */
+ policy->freq_table = freq_table;
- return cpufreq_table_validate_and_show(policy, freq_table);
+ return 0;
}
static struct cpufreq_driver sfi_cpufreq_driver = {
diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c
index 28893d435cf5..5096c0ab781b 100644
--- a/drivers/cpufreq/sh-cpufreq.c
+++ b/drivers/cpufreq/sh-cpufreq.c
@@ -122,11 +122,7 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL;
if (freq_table) {
- int result;
-
- result = cpufreq_table_validate_and_show(policy, freq_table);
- if (result)
- return result;
+ policy->freq_table = freq_table;
} else {
dev_notice(dev, "no frequency table found, falling back "
"to rate rounding.\n");
@@ -137,11 +133,6 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
(clk_round_rate(cpuclk, ~0UL) + 500) / 1000;
}
- dev_info(dev, "CPU Frequencies - Minimum %u.%03u MHz, "
- "Maximum %u.%03u MHz.\n",
- policy->min / 1000, policy->min % 1000,
- policy->max / 1000, policy->max % 1000);
-
return 0;
}
@@ -155,6 +146,16 @@ static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
+static void sh_cpufreq_cpu_ready(struct cpufreq_policy *policy)
+{
+ struct device *dev = get_cpu_device(policy->cpu);
+
+ dev_info(dev, "CPU Frequencies - Minimum %u.%03u MHz, "
+ "Maximum %u.%03u MHz.\n",
+ policy->min / 1000, policy->min % 1000,
+ policy->max / 1000, policy->max % 1000);
+}
+
static struct cpufreq_driver sh_cpufreq_driver = {
.name = "sh",
.flags = CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
@@ -163,6 +164,7 @@ static struct cpufreq_driver sh_cpufreq_driver = {
.verify = sh_cpufreq_verify,
.init = sh_cpufreq_cpu_init,
.exit = sh_cpufreq_cpu_exit,
+ .ready = sh_cpufreq_cpu_ready,
.attr = cpufreq_generic_attr,
};
diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c
index 90f33efee5fc..bbd1d1e166b8 100644
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -292,8 +292,9 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = 0;
policy->cur = clock_tick;
+ policy->freq_table = table;
- return cpufreq_table_validate_and_show(policy, table);
+ return 0;
}
static int us2e_freq_cpu_exit(struct cpufreq_policy *policy)
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c
index 30645b0118f9..51e3c6018e74 100644
--- a/drivers/cpufreq/sparc-us3-cpufreq.c
+++ b/drivers/cpufreq/sparc-us3-cpufreq.c
@@ -136,8 +136,9 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = 0;
policy->cur = clock_tick;
+ policy->freq_table = table;
- return cpufreq_table_validate_and_show(policy, table);
+ return 0;
}
static int us3_freq_cpu_exit(struct cpufreq_policy *policy)
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index 4fa5adf16c70..a1fb735685db 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -394,9 +394,9 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = 10000;
/* 10uS transition latency */
+ policy->freq_table = per_cpu(centrino_model, policy->cpu)->op_points;
- return cpufreq_table_validate_and_show(policy,
- per_cpu(centrino_model, policy->cpu)->op_points);
+ return 0;
}
static int centrino_cpu_exit(struct cpufreq_policy *policy)
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index 0412a246a785..fbbcb88db061 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -304,7 +304,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
if (gf.ret)
return gf.ret;
- return cpufreq_table_validate_and_show(policy, speedstep_freqs);
+ policy->freq_table = speedstep_freqs;
+
+ return 0;
}
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index d23f24ccff38..01fe70dae20b 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -266,7 +266,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
pr_debug("workaround worked.\n");
}
- return cpufreq_table_validate_and_show(policy, speedstep_freqs);
+ policy->freq_table = speedstep_freqs;
+
+ return 0;
}
static unsigned int speedstep_get(unsigned int cpu)
diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c
index fe7875311d62..1f59966573aa 100644
--- a/drivers/cpufreq/tegra186-cpufreq.c
+++ b/drivers/cpufreq/tegra186-cpufreq.c
@@ -78,7 +78,8 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy)
policy->driver_data =
data->regs + info->offset + EDVD_CORE_VOLT_FREQ(core);
- cpufreq_table_validate_and_show(policy, cluster->table);
+ policy->freq_table = cluster->table;
+ break;
}
policy->cpuinfo.transition_latency = 300 * 1000;
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index a099b7bf74cd..6ba709b6f095 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -304,7 +304,7 @@ static struct platform_driver ti_cpufreq_driver = {
.name = "ti-cpufreq",
},
};
-module_platform_driver(ti_cpufreq_driver);
+builtin_platform_driver(ti_cpufreq_driver);
MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver");
MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
OpenPOWER on IntegriCloud