aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig8
-rw-r--r--drivers/cpufreq/Kconfig.arm9
-rw-r--r--drivers/cpufreq/Kconfig.powerpc9
-rw-r--r--drivers/cpufreq/Makefile3
-rw-r--r--drivers/cpufreq/hisi-acpu-cpufreq.c42
-rw-r--r--drivers/cpufreq/intel_pstate.c45
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c47
-rw-r--r--drivers/cpufreq/qoriq-cpufreq.c (renamed from drivers/cpufreq/ppc-corenet-cpufreq.c)163
8 files changed, 239 insertions, 87 deletions
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index a171fef2c2b6..659879a56dba 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -293,5 +293,13 @@ config SH_CPU_FREQ
293 If unsure, say N. 293 If unsure, say N.
294endif 294endif
295 295
296config QORIQ_CPUFREQ
297 tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
298 depends on OF && COMMON_CLK && (PPC_E500MC || ARM)
299 select CLK_QORIQ
300 help
301 This adds the CPUFreq driver support for Freescale QorIQ SoCs
302 which are capable of changing the CPU's frequency dynamically.
303
296endif 304endif
297endmenu 305endmenu
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 1b06fc4640e2..4f3dbc8cf729 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -108,6 +108,15 @@ config ARM_HIGHBANK_CPUFREQ
108 108
109 If in doubt, say N. 109 If in doubt, say N.
110 110
111config ARM_HISI_ACPU_CPUFREQ
112 tristate "Hisilicon ACPU CPUfreq driver"
113 depends on ARCH_HISI && CPUFREQ_DT
114 select PM_OPP
115 help
116 This enables the hisilicon ACPU CPUfreq driver.
117
118 If in doubt, say N.
119
111config ARM_IMX6Q_CPUFREQ 120config ARM_IMX6Q_CPUFREQ
112 tristate "Freescale i.MX6 cpufreq support" 121 tristate "Freescale i.MX6 cpufreq support"
113 depends on ARCH_MXC 122 depends on ARCH_MXC
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index 7ea24413cee6..3a0595b41eab 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -23,15 +23,6 @@ config CPU_FREQ_MAPLE
23 This adds support for frequency switching on Maple 970FX 23 This adds support for frequency switching on Maple 970FX
24 Evaluation Board and compatible boards (IBM JS2x blades). 24 Evaluation Board and compatible boards (IBM JS2x blades).
25 25
26config PPC_CORENET_CPUFREQ
27 tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
28 depends on PPC_E500MC && OF && COMMON_CLK
29 select CLK_QORIQ
30 help
31 This adds the CPUFreq driver support for Freescale e500mc,
32 e5500 and e6500 series SoCs which are capable of changing
33 the CPU's frequency dynamically.
34
35config CPU_FREQ_PMAC 26config CPU_FREQ_PMAC
36 bool "Support for Apple PowerBooks" 27 bool "Support for Apple PowerBooks"
37 depends on ADB_PMU && PPC32 28 depends on ADB_PMU && PPC32
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 82a1821471fd..cdce92ae2e8b 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -59,6 +59,7 @@ arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
59arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o 59arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
60obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o 60obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
61obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o 61obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
62obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o
62obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o 63obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
63obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o 64obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
64obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o 65obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
@@ -85,7 +86,7 @@ obj-$(CONFIG_CPU_FREQ_CBE) += ppc-cbe-cpufreq.o
85ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o 86ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
86obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o 87obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o
87obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o 88obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o
88obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o 89obj-$(CONFIG_QORIQ_CPUFREQ) += qoriq-cpufreq.o
89obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o 90obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o
90obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o 91obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o
91obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o 92obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o
diff --git a/drivers/cpufreq/hisi-acpu-cpufreq.c b/drivers/cpufreq/hisi-acpu-cpufreq.c
new file mode 100644
index 000000000000..026d5b2224de
--- /dev/null
+++ b/drivers/cpufreq/hisi-acpu-cpufreq.c
@@ -0,0 +1,42 @@
1/*
2 * Hisilicon Platforms Using ACPU CPUFreq Support
3 *
4 * Copyright (c) 2015 Hisilicon Limited.
5 * Copyright (c) 2015 Linaro Limited.
6 *
7 * Leo Yan <leo.yan@linaro.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14 * kind, whether express or implied; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/err.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/platform_device.h>
27
28static int __init hisi_acpu_cpufreq_driver_init(void)
29{
30 struct platform_device *pdev;
31
32 if (!of_machine_is_compatible("hisilicon,hi6220"))
33 return -ENODEV;
34
35 pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
36 return PTR_ERR_OR_ZERO(pdev);
37}
38module_init(hisi_acpu_cpufreq_driver_init);
39
40MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
41MODULE_DESCRIPTION("Hisilicon acpu cpufreq driver");
42MODULE_LICENSE("GPL v2");
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 872c5772c5d3..c5b81beccc8e 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -614,6 +614,19 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate)
614 wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); 614 wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val);
615} 615}
616 616
617static int knl_get_turbo_pstate(void)
618{
619 u64 value;
620 int nont, ret;
621
622 rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
623 nont = core_get_max_pstate();
624 ret = (((value) >> 8) & 0xFF);
625 if (ret <= nont)
626 ret = nont;
627 return ret;
628}
629
617static struct cpu_defaults core_params = { 630static struct cpu_defaults core_params = {
618 .pid_policy = { 631 .pid_policy = {
619 .sample_rate_ms = 10, 632 .sample_rate_ms = 10,
@@ -651,6 +664,23 @@ static struct cpu_defaults byt_params = {
651 }, 664 },
652}; 665};
653 666
667static struct cpu_defaults knl_params = {
668 .pid_policy = {
669 .sample_rate_ms = 10,
670 .deadband = 0,
671 .setpoint = 97,
672 .p_gain_pct = 20,
673 .d_gain_pct = 0,
674 .i_gain_pct = 0,
675 },
676 .funcs = {
677 .get_max = core_get_max_pstate,
678 .get_min = core_get_min_pstate,
679 .get_turbo = knl_get_turbo_pstate,
680 .set = core_set_pstate,
681 },
682};
683
654static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) 684static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
655{ 685{
656 int max_perf = cpu->pstate.turbo_pstate; 686 int max_perf = cpu->pstate.turbo_pstate;
@@ -865,6 +895,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
865 ICPU(0x4e, core_params), 895 ICPU(0x4e, core_params),
866 ICPU(0x4f, core_params), 896 ICPU(0x4f, core_params),
867 ICPU(0x56, core_params), 897 ICPU(0x56, core_params),
898 ICPU(0x57, knl_params),
868 {} 899 {}
869}; 900};
870MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); 901MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
@@ -1024,25 +1055,11 @@ static unsigned int force_load;
1024 1055
1025static int intel_pstate_msrs_not_valid(void) 1056static int intel_pstate_msrs_not_valid(void)
1026{ 1057{
1027 /* Check that all the msr's we are using are valid. */
1028 u64 aperf, mperf, tmp;
1029
1030 rdmsrl(MSR_IA32_APERF, aperf);
1031 rdmsrl(MSR_IA32_MPERF, mperf);
1032
1033 if (!pstate_funcs.get_max() || 1058 if (!pstate_funcs.get_max() ||
1034 !pstate_funcs.get_min() || 1059 !pstate_funcs.get_min() ||
1035 !pstate_funcs.get_turbo()) 1060 !pstate_funcs.get_turbo())
1036 return -ENODEV; 1061 return -ENODEV;
1037 1062
1038 rdmsrl(MSR_IA32_APERF, tmp);
1039 if (!(tmp - aperf))
1040 return -ENODEV;
1041
1042 rdmsrl(MSR_IA32_MPERF, tmp);
1043 if (!(tmp - mperf))
1044 return -ENODEV;
1045
1046 return 0; 1063 return 0;
1047} 1064}
1048 1065
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 2dfd4fdb5a52..ebef0d8279c7 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -34,9 +34,13 @@
34#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ 34#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
35 35
36#define POWERNV_MAX_PSTATES 256 36#define POWERNV_MAX_PSTATES 256
37#define PMSR_PSAFE_ENABLE (1UL << 30)
38#define PMSR_SPR_EM_DISABLE (1UL << 31)
39#define PMSR_MAX(x) ((x >> 32) & 0xFF)
40#define PMSR_LP(x) ((x >> 48) & 0xFF)
37 41
38static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; 42static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
39static bool rebooting; 43static bool rebooting, throttled;
40 44
41/* 45/*
42 * Note: The set of pstates consists of contiguous integers, the 46 * Note: The set of pstates consists of contiguous integers, the
@@ -294,6 +298,44 @@ static inline unsigned int get_nominal_index(void)
294 return powernv_pstate_info.max - powernv_pstate_info.nominal; 298 return powernv_pstate_info.max - powernv_pstate_info.nominal;
295} 299}
296 300
301static void powernv_cpufreq_throttle_check(unsigned int cpu)
302{
303 unsigned long pmsr;
304 int pmsr_pmax, pmsr_lp;
305
306 pmsr = get_pmspr(SPRN_PMSR);
307
308 /* Check for Pmax Capping */
309 pmsr_pmax = (s8)PMSR_MAX(pmsr);
310 if (pmsr_pmax != powernv_pstate_info.max) {
311 throttled = true;
312 pr_info("CPU %d Pmax is reduced to %d\n", cpu, pmsr_pmax);
313 pr_info("Max allowed Pstate is capped\n");
314 }
315
316 /*
317 * Check for Psafe by reading LocalPstate
318 * or check if Psafe_mode_active is set in PMSR.
319 */
320 pmsr_lp = (s8)PMSR_LP(pmsr);
321 if ((pmsr_lp < powernv_pstate_info.min) ||
322 (pmsr & PMSR_PSAFE_ENABLE)) {
323 throttled = true;
324 pr_info("Pstate set to safe frequency\n");
325 }
326
327 /* Check if SPR_EM_DISABLE is set in PMSR */
328 if (pmsr & PMSR_SPR_EM_DISABLE) {
329 throttled = true;
330 pr_info("Frequency Control disabled from OS\n");
331 }
332
333 if (throttled) {
334 pr_info("PMSR = %16lx\n", pmsr);
335 pr_crit("CPU Frequency could be throttled\n");
336 }
337}
338
297/* 339/*
298 * powernv_cpufreq_target_index: Sets the frequency corresponding to 340 * powernv_cpufreq_target_index: Sets the frequency corresponding to
299 * the cpufreq table entry indexed by new_index on the cpus in the 341 * the cpufreq table entry indexed by new_index on the cpus in the
@@ -307,6 +349,9 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
307 if (unlikely(rebooting) && new_index != get_nominal_index()) 349 if (unlikely(rebooting) && new_index != get_nominal_index())
308 return 0; 350 return 0;
309 351
352 if (!throttled)
353 powernv_cpufreq_throttle_check(smp_processor_id());
354
310 freq_data.pstate_id = powernv_freqs[new_index].driver_data; 355 freq_data.pstate_id = powernv_freqs[new_index].driver_data;
311 356
312 /* 357 /*
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
index 7cb4b766cf94..88b21ae0d6b0 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright 2013 Freescale Semiconductor, Inc. 2 * Copyright 2013 Freescale Semiconductor, Inc.
3 * 3 *
4 * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs. 4 * CPU Frequency Scaling driver for Freescale QorIQ SoCs.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -20,12 +20,13 @@
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/smp.h> 22#include <linux/smp.h>
23#include <sysdev/fsl_soc.h>
24 23
24#if !defined(CONFIG_ARM)
25#include <asm/smp.h> /* for get_hard_smp_processor_id() in UP configs */ 25#include <asm/smp.h> /* for get_hard_smp_processor_id() in UP configs */
26#endif
26 27
27/** 28/**
28 * struct cpu_data - per CPU data struct 29 * struct cpu_data
29 * @parent: the parent node of cpu clock 30 * @parent: the parent node of cpu clock
30 * @table: frequency table 31 * @table: frequency table
31 */ 32 */
@@ -69,17 +70,78 @@ static const struct soc_data sdata[] = {
69static u32 min_cpufreq; 70static u32 min_cpufreq;
70static const u32 *fmask; 71static const u32 *fmask;
71 72
72static DEFINE_PER_CPU(struct cpu_data *, cpu_data); 73#if defined(CONFIG_ARM)
74static int get_cpu_physical_id(int cpu)
75{
76 return topology_core_id(cpu);
77}
78#else
79static int get_cpu_physical_id(int cpu)
80{
81 return get_hard_smp_processor_id(cpu);
82}
83#endif
73 84
74/* cpumask in a cluster */ 85static u32 get_bus_freq(void)
75static DEFINE_PER_CPU(cpumask_var_t, cpu_mask); 86{
87 struct device_node *soc;
88 u32 sysfreq;
89
90 soc = of_find_node_by_type(NULL, "soc");
91 if (!soc)
92 return 0;
93
94 if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
95 sysfreq = 0;
76 96
77#ifndef CONFIG_SMP 97 of_node_put(soc);
78static inline const struct cpumask *cpu_core_mask(int cpu) 98
99 return sysfreq;
100}
101
102static struct device_node *cpu_to_clk_node(int cpu)
79{ 103{
80 return cpumask_of(0); 104 struct device_node *np, *clk_np;
105
106 if (!cpu_present(cpu))
107 return NULL;
108
109 np = of_get_cpu_node(cpu, NULL);
110 if (!np)
111 return NULL;
112
113 clk_np = of_parse_phandle(np, "clocks", 0);
114 if (!clk_np)
115 return NULL;
116
117 of_node_put(np);
118
119 return clk_np;
120}
121
122/* traverse cpu nodes to get cpu mask of sharing clock wire */
123static void set_affected_cpus(struct cpufreq_policy *policy)
124{
125 struct device_node *np, *clk_np;
126 struct cpumask *dstp = policy->cpus;
127 int i;
128
129 np = cpu_to_clk_node(policy->cpu);
130 if (!np)
131 return;
132
133 for_each_present_cpu(i) {
134 clk_np = cpu_to_clk_node(i);
135 if (!clk_np)
136 continue;
137
138 if (clk_np == np)
139 cpumask_set_cpu(i, dstp);
140
141 of_node_put(clk_np);
142 }
143 of_node_put(np);
81} 144}
82#endif
83 145
84/* reduce the duplicated frequencies in frequency table */ 146/* reduce the duplicated frequencies in frequency table */
85static void freq_table_redup(struct cpufreq_frequency_table *freq_table, 147static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
@@ -107,6 +169,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
107 int i, j, ind; 169 int i, j, ind;
108 unsigned int freq, max_freq; 170 unsigned int freq, max_freq;
109 struct cpufreq_frequency_table table; 171 struct cpufreq_frequency_table table;
172
110 for (i = 0; i < count - 1; i++) { 173 for (i = 0; i < count - 1; i++) {
111 max_freq = freq_table[i].frequency; 174 max_freq = freq_table[i].frequency;
112 ind = i; 175 ind = i;
@@ -131,7 +194,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
131 } 194 }
132} 195}
133 196
134static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) 197static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
135{ 198{
136 struct device_node *np; 199 struct device_node *np;
137 int i, count, ret; 200 int i, count, ret;
@@ -147,10 +210,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
147 return -ENODEV; 210 return -ENODEV;
148 211
149 data = kzalloc(sizeof(*data), GFP_KERNEL); 212 data = kzalloc(sizeof(*data), GFP_KERNEL);
150 if (!data) { 213 if (!data)
151 pr_err("%s: no memory\n", __func__);
152 goto err_np; 214 goto err_np;
153 }
154 215
155 policy->clk = of_clk_get(np, 0); 216 policy->clk = of_clk_get(np, 0);
156 if (IS_ERR(policy->clk)) { 217 if (IS_ERR(policy->clk)) {
@@ -172,7 +233,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
172 } 233 }
173 234
174 if (fmask) 235 if (fmask)
175 mask = fmask[get_hard_smp_processor_id(cpu)]; 236 mask = fmask[get_cpu_physical_id(cpu)];
176 else 237 else
177 mask = 0x0; 238 mask = 0x0;
178 239
@@ -203,13 +264,12 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
203 data->table = table; 264 data->table = table;
204 265
205 /* update ->cpus if we have cluster, no harm if not */ 266 /* update ->cpus if we have cluster, no harm if not */
206 cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu)); 267 set_affected_cpus(policy);
207 for_each_cpu(i, per_cpu(cpu_mask, cpu)) 268 policy->driver_data = data;
208 per_cpu(cpu_data, i) = data;
209 269
210 /* Minimum transition latency is 12 platform clocks */ 270 /* Minimum transition latency is 12 platform clocks */
211 u64temp = 12ULL * NSEC_PER_SEC; 271 u64temp = 12ULL * NSEC_PER_SEC;
212 do_div(u64temp, fsl_get_sys_freq()); 272 do_div(u64temp, get_bus_freq());
213 policy->cpuinfo.transition_latency = u64temp + 1; 273 policy->cpuinfo.transition_latency = u64temp + 1;
214 274
215 of_node_put(np); 275 of_node_put(np);
@@ -221,7 +281,7 @@ err_nomem1:
221err_node: 281err_node:
222 of_node_put(data->parent); 282 of_node_put(data->parent);
223err_nomem2: 283err_nomem2:
224 per_cpu(cpu_data, cpu) = NULL; 284 policy->driver_data = NULL;
225 kfree(data); 285 kfree(data);
226err_np: 286err_np:
227 of_node_put(np); 287 of_node_put(np);
@@ -229,43 +289,40 @@ err_np:
229 return -ENODEV; 289 return -ENODEV;
230} 290}
231 291
232static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) 292static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
233{ 293{
234 struct cpu_data *data = per_cpu(cpu_data, policy->cpu); 294 struct cpu_data *data = policy->driver_data;
235 unsigned int cpu;
236 295
237 of_node_put(data->parent); 296 of_node_put(data->parent);
238 kfree(data->table); 297 kfree(data->table);
239 kfree(data); 298 kfree(data);
240 299 policy->driver_data = NULL;
241 for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
242 per_cpu(cpu_data, cpu) = NULL;
243 300
244 return 0; 301 return 0;
245} 302}
246 303
247static int corenet_cpufreq_target(struct cpufreq_policy *policy, 304static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
248 unsigned int index) 305 unsigned int index)
249{ 306{
250 struct clk *parent; 307 struct clk *parent;
251 struct cpu_data *data = per_cpu(cpu_data, policy->cpu); 308 struct cpu_data *data = policy->driver_data;
252 309
253 parent = of_clk_get(data->parent, data->table[index].driver_data); 310 parent = of_clk_get(data->parent, data->table[index].driver_data);
254 return clk_set_parent(policy->clk, parent); 311 return clk_set_parent(policy->clk, parent);
255} 312}
256 313
257static struct cpufreq_driver ppc_corenet_cpufreq_driver = { 314static struct cpufreq_driver qoriq_cpufreq_driver = {
258 .name = "ppc_cpufreq", 315 .name = "qoriq_cpufreq",
259 .flags = CPUFREQ_CONST_LOOPS, 316 .flags = CPUFREQ_CONST_LOOPS,
260 .init = corenet_cpufreq_cpu_init, 317 .init = qoriq_cpufreq_cpu_init,
261 .exit = __exit_p(corenet_cpufreq_cpu_exit), 318 .exit = __exit_p(qoriq_cpufreq_cpu_exit),
262 .verify = cpufreq_generic_frequency_table_verify, 319 .verify = cpufreq_generic_frequency_table_verify,
263 .target_index = corenet_cpufreq_target, 320 .target_index = qoriq_cpufreq_target,
264 .get = cpufreq_generic_get, 321 .get = cpufreq_generic_get,
265 .attr = cpufreq_generic_attr, 322 .attr = cpufreq_generic_attr,
266}; 323};
267 324
268static const struct of_device_id node_matches[] __initdata = { 325static const struct of_device_id node_matches[] __initconst = {
269 { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], }, 326 { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
270 { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], }, 327 { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
271 { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, 328 { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
@@ -275,61 +332,43 @@ static const struct of_device_id node_matches[] __initdata = {
275 {} 332 {}
276}; 333};
277 334
278static int __init ppc_corenet_cpufreq_init(void) 335static int __init qoriq_cpufreq_init(void)
279{ 336{
280 int ret; 337 int ret;
281 struct device_node *np; 338 struct device_node *np;
282 const struct of_device_id *match; 339 const struct of_device_id *match;
283 const struct soc_data *data; 340 const struct soc_data *data;
284 unsigned int cpu;
285 341
286 np = of_find_matching_node(NULL, node_matches); 342 np = of_find_matching_node(NULL, node_matches);
287 if (!np) 343 if (!np)
288 return -ENODEV; 344 return -ENODEV;
289 345
290 for_each_possible_cpu(cpu) {
291 if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
292 goto err_mask;
293 cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
294 }
295
296 match = of_match_node(node_matches, np); 346 match = of_match_node(node_matches, np);
297 data = match->data; 347 data = match->data;
298 if (data) { 348 if (data) {
299 if (data->flag) 349 if (data->flag)
300 fmask = data->freq_mask; 350 fmask = data->freq_mask;
301 min_cpufreq = fsl_get_sys_freq(); 351 min_cpufreq = get_bus_freq();
302 } else { 352 } else {
303 min_cpufreq = fsl_get_sys_freq() / 2; 353 min_cpufreq = get_bus_freq() / 2;
304 } 354 }
305 355
306 of_node_put(np); 356 of_node_put(np);
307 357
308 ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver); 358 ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
309 if (!ret) 359 if (!ret)
310 pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n"); 360 pr_info("Freescale QorIQ CPU frequency scaling driver\n");
311 361
312 return ret; 362 return ret;
313
314err_mask:
315 for_each_possible_cpu(cpu)
316 free_cpumask_var(per_cpu(cpu_mask, cpu));
317
318 return -ENOMEM;
319} 363}
320module_init(ppc_corenet_cpufreq_init); 364module_init(qoriq_cpufreq_init);
321 365
322static void __exit ppc_corenet_cpufreq_exit(void) 366static void __exit qoriq_cpufreq_exit(void)
323{ 367{
324 unsigned int cpu; 368 cpufreq_unregister_driver(&qoriq_cpufreq_driver);
325
326 for_each_possible_cpu(cpu)
327 free_cpumask_var(per_cpu(cpu_mask, cpu));
328
329 cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
330} 369}
331module_exit(ppc_corenet_cpufreq_exit); 370module_exit(qoriq_cpufreq_exit);
332 371
333MODULE_LICENSE("GPL"); 372MODULE_LICENSE("GPL");
334MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); 373MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
335MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs"); 374MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");