aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig.arm9
-rw-r--r--drivers/cpufreq/Makefile2
-rw-r--r--drivers/cpufreq/cppc_cpufreq.c19
-rw-r--r--drivers/cpufreq/cpufreq-dt-platdev.c1
-rw-r--r--drivers/cpufreq/cpufreq.c34
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c4
-rw-r--r--drivers/cpufreq/cpufreq_stats.c2
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c6
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c6
-rw-r--r--drivers/cpufreq/intel_pstate.c179
-rw-r--r--drivers/cpufreq/kirkwood-cpufreq.c19
-rw-r--r--drivers/cpufreq/pasemi-cpufreq.c2
-rw-r--r--drivers/cpufreq/scpi-cpufreq.c38
-rw-r--r--drivers/cpufreq/sfi-cpufreq.c2
14 files changed, 171 insertions, 152 deletions
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 74ed7e9a7f27..2011fec2d6ad 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -71,6 +71,15 @@ config ARM_HIGHBANK_CPUFREQ
If in doubt, say N.
+config ARM_DB8500_CPUFREQ
+ tristate "ST-Ericsson DB8500 cpufreq" if COMPILE_TEST && !ARCH_U8500
+ default ARCH_U8500
+ depends on HAS_IOMEM
+ depends on !CPU_THERMAL || THERMAL
+ help
+ This adds the CPUFreq driver for ST-Ericsson Ux500 (DB8500) SoC
+ series.
+
config ARM_IMX6Q_CPUFREQ
tristate "Freescale i.MX6 cpufreq support"
depends on ARCH_MXC
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index b7e78f063c4f..ab3a42cd29ef 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -53,7 +53,7 @@ obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
-obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o
+obj-$(CONFIG_ARM_DB8500_CPUFREQ) += dbx500-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index e82bb3c30b92..10be285c9055 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -144,10 +144,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
cppc_dmi_max_khz = cppc_get_dmi_max_khz();
- policy->min = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz / cpu->perf_caps.highest_perf;
+ /*
+ * Set min to lowest nonlinear perf to avoid any efficiency penalty (see
+ * Section 8.4.7.1.1.5 of ACPI 6.1 spec)
+ */
+ policy->min = cpu->perf_caps.lowest_nonlinear_perf * cppc_dmi_max_khz /
+ cpu->perf_caps.highest_perf;
policy->max = cppc_dmi_max_khz;
- policy->cpuinfo.min_freq = policy->min;
- policy->cpuinfo.max_freq = policy->max;
+
+ /*
+ * Set cpuinfo.min_freq to Lowest to make the full range of performance
+ * available if userspace wants to use any perf between lowest & lowest
+ * nonlinear perf
+ */
+ policy->cpuinfo.min_freq = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz /
+ cpu->perf_caps.highest_perf;
+ policy->cpuinfo.max_freq = cppc_dmi_max_khz;
+
policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num);
policy->shared_type = cpu->shared_type;
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 921b4a6c3d16..1c262923fe58 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -31,6 +31,7 @@ static const struct of_device_id machines[] __initconst = {
{ .compatible = "arm,integrator-ap", },
{ .compatible = "arm,integrator-cp", },
+ { .compatible = "hisilicon,hi3660", },
{ .compatible = "hisilicon,hi6220", },
{ .compatible = "fsl,imx27", },
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0e3f6496524d..9bf97a366029 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -632,11 +632,21 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
show_one(scaling_min_freq, min);
show_one(scaling_max_freq, max);
+__weak unsigned int arch_freq_get_on_cpu(int cpu)
+{
+ return 0;
+}
+
static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
{
ssize_t ret;
+ unsigned int freq;
- if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
+ freq = arch_freq_get_on_cpu(policy->cpu);
+ if (freq)
+ ret = sprintf(buf, "%u\n", freq);
+ else if (cpufreq_driver && cpufreq_driver->setpolicy &&
+ cpufreq_driver->get)
ret = sprintf(buf, "%u\n", cpufreq_driver->get(policy->cpu));
else
ret = sprintf(buf, "%u\n", policy->cur);
@@ -887,7 +897,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
struct freq_attr *fattr = to_attr(attr);
ssize_t ret = -EINVAL;
- get_online_cpus();
+ cpus_read_lock();
if (cpu_online(policy->cpu)) {
down_write(&policy->rwsem);
@@ -895,7 +905,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
up_write(&policy->rwsem);
}
- put_online_cpus();
+ cpus_read_unlock();
return ret;
}
@@ -2441,7 +2451,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
pr_debug("trying to register driver %s\n", driver_data->name);
/* Protect against concurrent CPU online/offline. */
- get_online_cpus();
+ cpus_read_lock();
write_lock_irqsave(&cpufreq_driver_lock, flags);
if (cpufreq_driver) {
@@ -2468,14 +2478,16 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
if (!(cpufreq_driver->flags & CPUFREQ_STICKY) &&
list_empty(&cpufreq_policy_list)) {
/* if all ->init() calls failed, unregister */
+ ret = -ENODEV;
pr_debug("%s: No CPU initialized for driver %s\n", __func__,
driver_data->name);
goto err_if_unreg;
}
- ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online",
- cpuhp_cpufreq_online,
- cpuhp_cpufreq_offline);
+ ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
+ "cpufreq:online",
+ cpuhp_cpufreq_online,
+ cpuhp_cpufreq_offline);
if (ret < 0)
goto err_if_unreg;
hp_online = ret;
@@ -2493,7 +2505,7 @@ err_null_driver:
cpufreq_driver = NULL;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
out:
- put_online_cpus();
+ cpus_read_unlock();
return ret;
}
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
@@ -2516,17 +2528,17 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
pr_debug("unregistering driver %s\n", driver->name);
/* Protect against concurrent cpu hotplug */
- get_online_cpus();
+ cpus_read_lock();
subsys_interface_unregister(&cpufreq_interface);
remove_boost_sysfs_file();
- cpuhp_remove_state_nocalls(hp_online);
+ cpuhp_remove_state_nocalls_cpuslocked(hp_online);
write_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver = NULL;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
- put_online_cpus();
+ cpus_read_unlock();
return 0;
}
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 992f7c20760f..88220ff3e1c2 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -185,8 +185,8 @@ static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
int ret;
ret = sscanf(buf, "%u", &input);
- /* cannot be lower than 11 otherwise freq will not fall */
- if (ret != 1 || input < 11 || input > 100 ||
+ /* cannot be lower than 1 otherwise freq will not fall */
+ if (ret != 1 || input < 1 || input > 100 ||
input >= dbs_data->up_threshold)
return -EINVAL;
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index f570ead62454..d362739a71f3 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -135,7 +135,7 @@ static struct attribute *default_attrs[] = {
&trans_table.attr,
NULL
};
-static struct attribute_group stats_attr_group = {
+static const struct attribute_group stats_attr_group = {
.attrs = default_attrs,
.name = "stats"
};
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index 9180d34cc9fc..b6b369c22272 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -173,12 +173,12 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
/* Enable PSTATE Change Event */
tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN);
tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT);
- __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN);
+ __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN);
/* Enable PSTATE Change IRQ */
tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN);
tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT);
- __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
+ __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
/* Set initial performance index */
cpufreq_for_each_entry(pos, freq_table)
@@ -330,7 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
struct resource res;
unsigned int cur_frequency;
- np = pdev->dev.of_node;
+ np = pdev->dev.of_node;
if (!np)
return -ENODEV;
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 9c13f097fd8c..b6edd3ccaa55 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -101,7 +101,8 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
* - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
* - Disable pll2_pfd2_396m_clk
*/
- if (of_machine_is_compatible("fsl,imx6ul")) {
+ if (of_machine_is_compatible("fsl,imx6ul") ||
+ of_machine_is_compatible("fsl,imx6ull")) {
/*
* When changing pll1_sw_clk's parent to pll1_sys_clk,
* CPU may run at higher than 528MHz, this will lead to
@@ -215,7 +216,8 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
goto put_clk;
}
- if (of_machine_is_compatible("fsl,imx6ul")) {
+ if (of_machine_is_compatible("fsl,imx6ul") ||
+ of_machine_is_compatible("fsl,imx6ull")) {
pll2_bus_clk = clk_get(cpu_dev, "pll2_bus");
secondary_sel_clk = clk_get(cpu_dev, "secondary_sel");
if (IS_ERR(pll2_bus_clk) || IS_ERR(secondary_sel_clk)) {
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index b7de5bd76a31..d6f323560da3 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -231,10 +231,8 @@ struct global_params {
* @prev_cummulative_iowait: IO Wait time difference from last and
* current sample
* @sample: Storage for storing last Sample data
- * @min_perf: Minimum capacity limit as a fraction of the maximum
- * turbo P-state capacity.
- * @max_perf: Maximum capacity limit as a fraction of the maximum
- * turbo P-state capacity.
+ * @min_perf_ratio: Minimum capacity in terms of PERF or HWP ratios
+ * @max_perf_ratio: Maximum capacity in terms of PERF or HWP ratios
* @acpi_perf_data: Stores ACPI perf information read from _PSS
* @valid_pss_table: Set to true for valid ACPI _PSS entries found
* @epp_powersave: Last saved HWP energy performance preference
@@ -266,8 +264,8 @@ struct cpudata {
u64 prev_tsc;
u64 prev_cummulative_iowait;
struct sample sample;
- int32_t min_perf;
- int32_t max_perf;
+ int32_t min_perf_ratio;
+ int32_t max_perf_ratio;
#ifdef CONFIG_ACPI
struct acpi_processor_performance acpi_perf_data;
bool valid_pss_table;
@@ -571,9 +569,10 @@ static inline void update_turbo_state(void)
static int min_perf_pct_min(void)
{
struct cpudata *cpu = all_cpu_data[0];
+ int turbo_pstate = cpu->pstate.turbo_pstate;
- return DIV_ROUND_UP(cpu->pstate.min_pstate * 100,
- cpu->pstate.turbo_pstate);
+ return turbo_pstate ?
+ DIV_ROUND_UP(cpu->pstate.min_pstate * 100, turbo_pstate) : 0;
}
static s16 intel_pstate_get_epb(struct cpudata *cpu_data)
@@ -652,6 +651,12 @@ static const char * const energy_perf_strings[] = {
"power",
NULL
};
+static const unsigned int epp_values[] = {
+ HWP_EPP_PERFORMANCE,
+ HWP_EPP_BALANCE_PERFORMANCE,
+ HWP_EPP_BALANCE_POWERSAVE,
+ HWP_EPP_POWERSAVE
+};
static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data)
{
@@ -663,17 +668,14 @@ static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data)
return epp;
if (static_cpu_has(X86_FEATURE_HWP_EPP)) {
- /*
- * Range:
- * 0x00-0x3F : Performance
- * 0x40-0x7F : Balance performance
- * 0x80-0xBF : Balance power
- * 0xC0-0xFF : Power
- * The EPP is a 8 bit value, but our ranges restrict the
- * value which can be set. Here only using top two bits
- * effectively.
- */
- index = (epp >> 6) + 1;
+ if (epp == HWP_EPP_PERFORMANCE)
+ return 1;
+ if (epp <= HWP_EPP_BALANCE_PERFORMANCE)
+ return 2;
+ if (epp <= HWP_EPP_BALANCE_POWERSAVE)
+ return 3;
+ else
+ return 4;
} else if (static_cpu_has(X86_FEATURE_EPB)) {
/*
* Range:
@@ -711,15 +713,8 @@ static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data,
value &= ~GENMASK_ULL(31, 24);
- /*
- * If epp is not default, convert from index into
- * energy_perf_strings to epp value, by shifting 6
- * bits left to use only top two bits in epp.
- * The resultant epp need to shifted by 24 bits to
- * epp position in MSR_HWP_REQUEST.
- */
if (epp == -EINVAL)
- epp = (pref_index - 1) << 6;
+ epp = epp_values[pref_index - 1];
value |= (u64)epp << 24;
ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value);
@@ -793,25 +788,32 @@ static struct freq_attr *hwp_cpufreq_attrs[] = {
NULL,
};
-static void intel_pstate_hwp_set(unsigned int cpu)
+static void intel_pstate_get_hwp_max(unsigned int cpu, int *phy_max,
+ int *current_max)
{
- struct cpudata *cpu_data = all_cpu_data[cpu];
- int min, hw_min, max, hw_max;
- u64 value, cap;
- s16 epp;
+ u64 cap;
rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
- hw_min = HWP_LOWEST_PERF(cap);
if (global.no_turbo)
- hw_max = HWP_GUARANTEED_PERF(cap);
+ *current_max = HWP_GUARANTEED_PERF(cap);
else
- hw_max = HWP_HIGHEST_PERF(cap);
+ *current_max = HWP_HIGHEST_PERF(cap);
+
+ *phy_max = HWP_HIGHEST_PERF(cap);
+}
+
+static void intel_pstate_hwp_set(unsigned int cpu)
+{
+ struct cpudata *cpu_data = all_cpu_data[cpu];
+ int max, min;
+ u64 value;
+ s16 epp;
+
+ max = cpu_data->max_perf_ratio;
+ min = cpu_data->min_perf_ratio;
- max = fp_ext_toint(hw_max * cpu_data->max_perf);
if (cpu_data->policy == CPUFREQ_POLICY_PERFORMANCE)
min = max;
- else
- min = fp_ext_toint(hw_max * cpu_data->min_perf);
rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
@@ -1212,7 +1214,7 @@ static struct attribute *intel_pstate_attributes[] = {
NULL
};
-static struct attribute_group intel_pstate_attr_group = {
+static const struct attribute_group intel_pstate_attr_group = {
.attrs = intel_pstate_attributes,
};
@@ -1527,8 +1529,7 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
update_turbo_state();
pstate = intel_pstate_get_base_pstate(cpu);
- pstate = max(cpu->pstate.min_pstate,
- fp_ext_toint(pstate * cpu->max_perf));
+ pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio);
intel_pstate_set_pstate(cpu, pstate);
}
@@ -1615,9 +1616,6 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
int32_t busy_frac, boost;
int target, avg_pstate;
- if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE)
- return cpu->pstate.turbo_pstate;
-
busy_frac = div_fp(sample->mperf, sample->tsc);
boost = cpu->iowait_boost;
@@ -1654,9 +1652,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
int32_t perf_scaled, max_pstate, current_pstate, sample_ratio;
u64 duration_ns;
- if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE)
- return cpu->pstate.turbo_pstate;
-
/*
* perf_scaled is the ratio of the average P-state during the last
* sampling period to the P-state requested last time (in percent).
@@ -1694,9 +1689,8 @@ static int intel_pstate_prepare_request(struct cpudata *cpu, int pstate)
int max_pstate = intel_pstate_get_base_pstate(cpu);
int min_pstate;
- min_pstate = max(cpu->pstate.min_pstate,
- fp_ext_toint(max_pstate * cpu->min_perf));
- max_pstate = max(min_pstate, fp_ext_toint(max_pstate * cpu->max_perf));
+ min_pstate = max(cpu->pstate.min_pstate, cpu->min_perf_ratio);
+ max_pstate = max(min_pstate, cpu->max_perf_ratio);
return clamp_t(int, pstate, min_pstate, max_pstate);
}
@@ -1732,16 +1726,6 @@ static void intel_pstate_adjust_pstate(struct cpudata *cpu, int target_pstate)
fp_toint(cpu->iowait_boost * 100));
}
-static void intel_pstate_update_util_hwp(struct update_util_data *data,
- u64 time, unsigned int flags)
-{
- struct cpudata *cpu = container_of(data, struct cpudata, update_util);
- u64 delta_ns = time - cpu->sample.time;
-
- if ((s64)delta_ns >= INTEL_PSTATE_HWP_SAMPLING_INTERVAL)
- intel_pstate_sample(cpu, time);
-}
-
static void intel_pstate_update_util_pid(struct update_util_data *data,
u64 time, unsigned int flags)
{
@@ -1933,6 +1917,9 @@ static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
{
struct cpudata *cpu = all_cpu_data[cpu_num];
+ if (hwp_active)
+ return;
+
if (cpu->update_util_set)
return;
@@ -1966,52 +1953,61 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
{
int max_freq = intel_pstate_get_max_freq(cpu);
int32_t max_policy_perf, min_policy_perf;
+ int max_state, turbo_max;
- max_policy_perf = div_ext_fp(policy->max, max_freq);
- max_policy_perf = clamp_t(int32_t, max_policy_perf, 0, int_ext_tofp(1));
+ /*
+ * HWP needs some special consideration, because on BDX the
+ * HWP_REQUEST uses abstract value to represent performance
+ * rather than pure ratios.
+ */
+ if (hwp_active) {
+ intel_pstate_get_hwp_max(cpu->cpu, &turbo_max, &max_state);
+ } else {
+ max_state = intel_pstate_get_base_pstate(cpu);
+ turbo_max = cpu->pstate.turbo_pstate;
+ }
+
+ max_policy_perf = max_state * policy->max / max_freq;
if (policy->max == policy->min) {
min_policy_perf = max_policy_perf;
} else {
- min_policy_perf = div_ext_fp(policy->min, max_freq);
+ min_policy_perf = max_state * policy->min / max_freq;
min_policy_perf = clamp_t(int32_t, min_policy_perf,
0, max_policy_perf);
}
+ pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n",
+ policy->cpu, max_state,
+ min_policy_perf, max_policy_perf);
+
/* Normalize user input to [min_perf, max_perf] */
if (per_cpu_limits) {
- cpu->min_perf = min_policy_perf;
- cpu->max_perf = max_policy_perf;
+ cpu->min_perf_ratio = min_policy_perf;
+ cpu->max_perf_ratio = max_policy_perf;
} else {
int32_t global_min, global_max;
/* Global limits are in percent of the maximum turbo P-state. */
- global_max = percent_ext_fp(global.max_perf_pct);
- global_min = percent_ext_fp(global.min_perf_pct);
- if (max_freq != cpu->pstate.turbo_freq) {
- int32_t turbo_factor;
-
- turbo_factor = div_ext_fp(cpu->pstate.turbo_pstate,
- cpu->pstate.max_pstate);
- global_min = mul_ext_fp(global_min, turbo_factor);
- global_max = mul_ext_fp(global_max, turbo_factor);
- }
+ global_max = DIV_ROUND_UP(turbo_max * global.max_perf_pct, 100);
+ global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100);
global_min = clamp_t(int32_t, global_min, 0, global_max);
- cpu->min_perf = max(min_policy_perf, global_min);
- cpu->min_perf = min(cpu->min_perf, max_policy_perf);
- cpu->max_perf = min(max_policy_perf, global_max);
- cpu->max_perf = max(min_policy_perf, cpu->max_perf);
+ pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu,
+ global_min, global_max);
- /* Make sure min_perf <= max_perf */
- cpu->min_perf = min(cpu->min_perf, cpu->max_perf);
- }
+ cpu->min_perf_ratio = max(min_policy_perf, global_min);
+ cpu->min_perf_ratio = min(cpu->min_perf_ratio, max_policy_perf);
+ cpu->max_perf_ratio = min(max_policy_perf, global_max);
+ cpu->max_perf_ratio = max(min_policy_perf, cpu->max_perf_ratio);
- cpu->max_perf = round_up(cpu->max_perf, EXT_FRAC_BITS);
- cpu->min_perf = round_up(cpu->min_perf, EXT_FRAC_BITS);
+ /* Make sure min_perf <= max_perf */
+ cpu->min_perf_ratio = min(cpu->min_perf_ratio,
+ cpu->max_perf_ratio);
- pr_debug("cpu:%d max_perf_pct:%d min_perf_pct:%d\n", policy->cpu,
- fp_ext_toint(cpu->max_perf * 100),
- fp_ext_toint(cpu->min_perf * 100));
+ }
+ pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu,
+ cpu->max_perf_ratio,
+ cpu->min_perf_ratio);
}
static int intel_pstate_set_policy(struct cpufreq_policy *policy)
@@ -2038,10 +2034,10 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
*/
intel_pstate_clear_update_util_hook(policy->cpu);
intel_pstate_max_within_limits(cpu);
+ } else {
+ intel_pstate_set_update_util_hook(policy->cpu);
}
- intel_pstate_set_update_util_hook(policy->cpu);
-
if (hwp_active)
intel_pstate_hwp_set(policy->cpu);
@@ -2114,8 +2110,8 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
cpu = all_cpu_data[policy->cpu];
- cpu->max_perf = int_ext_tofp(1);
- cpu->min_perf = 0;
+ cpu->max_perf_ratio = 0xFF;
+ cpu->min_perf_ratio = 0;
policy->min = cpu->pstate.min_pstate * cpu->pstate.scaling;
policy->max = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
@@ -2557,7 +2553,6 @@ static int __init intel_pstate_init(void)
} else {
hwp_active++;
intel_pstate.attr = hwp_cpufreq_attrs;
- pstate_funcs.update_util = intel_pstate_update_util_hwp;
goto hwp_cpu_matched;
}
} else {
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index 1b9bcd76c60e..c2dd43f3f5d8 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -127,7 +127,12 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
return PTR_ERR(priv.cpu_clk);
}
- clk_prepare_enable(priv.cpu_clk);
+ err = clk_prepare_enable(priv.cpu_clk);
+ if (err) {
+ dev_err(priv.dev, "Unable to prepare cpuclk\n");
+ return err;
+ }
+
kirkwood_freq_table[0].frequency = clk_get_rate(priv.cpu_clk) / 1000;
priv.ddr_clk = of_clk_get_by_name(np, "ddrclk");
@@ -137,7 +142,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
goto out_cpu;
}
- clk_prepare_enable(priv.ddr_clk);
+ err = clk_prepare_enable(priv.ddr_clk);
+ if (err) {
+ dev_err(priv.dev, "Unable to prepare ddrclk\n");
+ goto out_cpu;
+ }
kirkwood_freq_table[1].frequency = clk_get_rate(priv.ddr_clk) / 1000;
priv.powersave_clk = of_clk_get_by_name(np, "powersave");
@@ -146,7 +155,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
err = PTR_ERR(priv.powersave_clk);
goto out_ddr;
}
- clk_prepare_enable(priv.powersave_clk);
+ err = clk_prepare_enable(priv.powersave_clk);
+ if (err) {
+ dev_err(priv.dev, "Unable to prepare powersave clk\n");
+ goto out_ddr;
+ }
of_node_put(np);
np = NULL;
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
index 35dd4d7ffee0..b257fc7d5204 100644
--- a/drivers/cpufreq/pasemi-cpufreq.c
+++ b/drivers/cpufreq/pasemi-cpufreq.c
@@ -226,7 +226,7 @@ static int 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_BOOTING)
+ if (system_state >= SYSTEM_RUNNING)
return 0;
if (sdcasr_mapbase)
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
index ea7a4e1b68c2..8de2364b5995 100644
--- a/drivers/cpufreq/scpi-cpufreq.c
+++ b/drivers/cpufreq/scpi-cpufreq.c
@@ -30,46 +30,20 @@
static struct scpi_ops *scpi_ops;
-static struct scpi_dvfs_info *scpi_get_dvfs_info(struct device *cpu_dev)
-{
- int domain = topology_physical_package_id(cpu_dev->id);
-
- if (domain < 0)
- return ERR_PTR(-EINVAL);
- return scpi_ops->dvfs_get_info(domain);
-}
-
static int scpi_get_transition_latency(struct device *cpu_dev)
{
- struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
-
- if (IS_ERR(info))
- return PTR_ERR(info);
- return info->latency;
+ return scpi_ops->get_transition_latency(cpu_dev);
}
static int scpi_init_opp_table(const struct cpumask *cpumask)
{
- int idx, ret;
- struct scpi_opp *opp;
+ int ret;
struct device *cpu_dev = get_cpu_device(cpumask_first(cpumask));
- struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
-
- if (IS_ERR(info))
- return PTR_ERR(info);
-
- if (!info->opps)
- return -EIO;
- for (opp = info->opps, idx = 0; idx < info->count; idx++, opp++) {
- ret = dev_pm_opp_add(cpu_dev, opp->freq, opp->m_volt * 1000);
- if (ret) {
- dev_warn(cpu_dev, "failed to add opp %uHz %umV\n",
- opp->freq, opp->m_volt);
- while (idx-- > 0)
- dev_pm_opp_remove(cpu_dev, (--opp)->freq);
- return ret;
- }
+ ret = scpi_ops->add_opps_to_device(cpu_dev);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to add opps to the device\n");
+ return ret;
}
ret = dev_pm_opp_set_sharing_cpus(cpu_dev, cpumask);
diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c
index 992ce6f9abec..3779742f86e3 100644
--- a/drivers/cpufreq/sfi-cpufreq.c
+++ b/drivers/cpufreq/sfi-cpufreq.c
@@ -24,7 +24,7 @@
#include <asm/msr.h>
-struct cpufreq_frequency_table *freq_table;
+static struct cpufreq_frequency_table *freq_table;
static struct sfi_freq_table_entry *sfi_cpufreq_array;
static int num_freq_table_entries;