diff options
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/Kconfig | 8 | ||||
-rw-r--r-- | drivers/cpufreq/Kconfig.arm | 9 | ||||
-rw-r--r-- | drivers/cpufreq/Kconfig.powerpc | 9 | ||||
-rw-r--r-- | drivers/cpufreq/Makefile | 3 | ||||
-rw-r--r-- | drivers/cpufreq/hisi-acpu-cpufreq.c | 42 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 45 | ||||
-rw-r--r-- | drivers/cpufreq/powernv-cpufreq.c | 47 | ||||
-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. |
294 | endif | 294 | endif |
295 | 295 | ||
296 | config 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 | |||
296 | endif | 304 | endif |
297 | endmenu | 305 | endmenu |
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 | ||
111 | config 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 | |||
111 | config ARM_IMX6Q_CPUFREQ | 120 | config 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 | ||
26 | config 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 | |||
35 | config CPU_FREQ_PMAC | 26 | config 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 | |||
59 | arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o | 59 | arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o |
60 | obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o | 60 | obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o |
61 | obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o | 61 | obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o |
62 | obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o | ||
62 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o | 63 | obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o |
63 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o | 64 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o |
64 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o | 65 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o |
@@ -85,7 +86,7 @@ obj-$(CONFIG_CPU_FREQ_CBE) += ppc-cbe-cpufreq.o | |||
85 | ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o | 86 | ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o |
86 | obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o | 87 | obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o |
87 | obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o | 88 | obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o |
88 | obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o | 89 | obj-$(CONFIG_QORIQ_CPUFREQ) += qoriq-cpufreq.o |
89 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o | 90 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o |
90 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o | 91 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o |
91 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o | 92 | obj-$(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 | |||
28 | static 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 | } | ||
38 | module_init(hisi_acpu_cpufreq_driver_init); | ||
39 | |||
40 | MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>"); | ||
41 | MODULE_DESCRIPTION("Hisilicon acpu cpufreq driver"); | ||
42 | MODULE_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 | ||
617 | static 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 | |||
617 | static struct cpu_defaults core_params = { | 630 | static 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 | ||
667 | static 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 | |||
654 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | 684 | static 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 | }; |
870 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 901 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
@@ -1024,25 +1055,11 @@ static unsigned int force_load; | |||
1024 | 1055 | ||
1025 | static int intel_pstate_msrs_not_valid(void) | 1056 | static 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 | ||
38 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; | 42 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; |
39 | static bool rebooting; | 43 | static 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 | ||
301 | static 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[] = { | |||
69 | static u32 min_cpufreq; | 70 | static u32 min_cpufreq; |
70 | static const u32 *fmask; | 71 | static const u32 *fmask; |
71 | 72 | ||
72 | static DEFINE_PER_CPU(struct cpu_data *, cpu_data); | 73 | #if defined(CONFIG_ARM) |
74 | static int get_cpu_physical_id(int cpu) | ||
75 | { | ||
76 | return topology_core_id(cpu); | ||
77 | } | ||
78 | #else | ||
79 | static 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 */ | 85 | static u32 get_bus_freq(void) |
75 | static 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); |
78 | static inline const struct cpumask *cpu_core_mask(int cpu) | 98 | |
99 | return sysfreq; | ||
100 | } | ||
101 | |||
102 | static 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 */ | ||
123 | static 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 */ |
85 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, | 147 | static 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 | ||
134 | static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | 197 | static 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: | |||
221 | err_node: | 281 | err_node: |
222 | of_node_put(data->parent); | 282 | of_node_put(data->parent); |
223 | err_nomem2: | 283 | err_nomem2: |
224 | per_cpu(cpu_data, cpu) = NULL; | 284 | policy->driver_data = NULL; |
225 | kfree(data); | 285 | kfree(data); |
226 | err_np: | 286 | err_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 | ||
232 | static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) | 292 | static 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 | ||
247 | static int corenet_cpufreq_target(struct cpufreq_policy *policy, | 304 | static 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 | ||
257 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 314 | static 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 | ||
268 | static const struct of_device_id node_matches[] __initdata = { | 325 | static 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 | ||
278 | static int __init ppc_corenet_cpufreq_init(void) | 335 | static 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 | |||
314 | err_mask: | ||
315 | for_each_possible_cpu(cpu) | ||
316 | free_cpumask_var(per_cpu(cpu_mask, cpu)); | ||
317 | |||
318 | return -ENOMEM; | ||
319 | } | 363 | } |
320 | module_init(ppc_corenet_cpufreq_init); | 364 | module_init(qoriq_cpufreq_init); |
321 | 365 | ||
322 | static void __exit ppc_corenet_cpufreq_exit(void) | 366 | static 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 | } |
331 | module_exit(ppc_corenet_cpufreq_exit); | 370 | module_exit(qoriq_cpufreq_exit); |
332 | 371 | ||
333 | MODULE_LICENSE("GPL"); | 372 | MODULE_LICENSE("GPL"); |
334 | MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); | 373 | MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); |
335 | MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs"); | 374 | MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs"); |