aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/cpuidle.h23
-rw-r--r--arch/arm/kernel/cpuidle.c133
-rw-r--r--arch/arm/mach-davinci/cpuidle.c1
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6q.c1
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sl.c1
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c1
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c1
-rw-r--r--arch/arm/mach-s3c64xx/cpuidle.c2
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra20.c1
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c1
-rw-r--r--arch/arm64/configs/defconfig2
-rw-r--r--arch/arm64/include/asm/cpuidle.h9
-rw-r--r--arch/arm64/kernel/cpuidle.c2
-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
-rw-r--r--drivers/cpuidle/Kconfig7
-rw-r--r--drivers/cpuidle/Kconfig.arm28
-rw-r--r--drivers/cpuidle/Kconfig.arm6413
-rw-r--r--drivers/cpuidle/Makefile5
-rw-r--r--drivers/cpuidle/cpuidle-arm.c (renamed from drivers/cpuidle/cpuidle-arm64.c)83
-rw-r--r--drivers/cpuidle/cpuidle-at91.c1
-rw-r--r--drivers/cpuidle/cpuidle-exynos.c1
-rw-r--r--drivers/cpuidle/cpuidle-kirkwood.c1
-rw-r--r--drivers/cpuidle/cpuidle-ux500.c1
-rw-r--r--drivers/cpuidle/cpuidle-zynq.c1
-rw-r--r--drivers/idle/intel_idle.c68
-rw-r--r--include/asm-generic/vmlinux.lds.h2
33 files changed, 544 insertions, 171 deletions
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
index af319ac4960c..0f8424924902 100644
--- a/arch/arm/include/asm/cpuidle.h
+++ b/arch/arm/include/asm/cpuidle.h
@@ -1,6 +1,8 @@
1#ifndef __ASM_ARM_CPUIDLE_H 1#ifndef __ASM_ARM_CPUIDLE_H
2#define __ASM_ARM_CPUIDLE_H 2#define __ASM_ARM_CPUIDLE_H
3 3
4#include <asm/proc-fns.h>
5
4#ifdef CONFIG_CPU_IDLE 6#ifdef CONFIG_CPU_IDLE
5extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, 7extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
6 struct cpuidle_driver *drv, int index); 8 struct cpuidle_driver *drv, int index);
@@ -25,4 +27,25 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
25 */ 27 */
26#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) 28#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX)
27 29
30struct device_node;
31
32struct cpuidle_ops {
33 int (*suspend)(int cpu, unsigned long arg);
34 int (*init)(struct device_node *, int cpu);
35};
36
37struct of_cpuidle_method {
38 const char *method;
39 struct cpuidle_ops *ops;
40};
41
42#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \
43 static const struct of_cpuidle_method __cpuidle_method_of_table_##name \
44 __used __section(__cpuidle_method_of_table) \
45 = { .method = _method, .ops = _ops }
46
47extern int arm_cpuidle_suspend(int index);
48
49extern int arm_cpuidle_init(int cpu);
50
28#endif 51#endif
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
index 89545f6c8403..318da33465f4 100644
--- a/arch/arm/kernel/cpuidle.c
+++ b/arch/arm/kernel/cpuidle.c
@@ -10,8 +10,28 @@
10 */ 10 */
11 11
12#include <linux/cpuidle.h> 12#include <linux/cpuidle.h>
13#include <asm/proc-fns.h> 13#include <linux/of.h>
14#include <linux/of_device.h>
15#include <asm/cpuidle.h>
14 16
17extern struct of_cpuidle_method __cpuidle_method_of_table[];
18
19static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel
20 __used __section(__cpuidle_method_of_table_end);
21
22static struct cpuidle_ops cpuidle_ops[NR_CPUS];
23
24/**
25 * arm_cpuidle_simple_enter() - a wrapper to cpu_do_idle()
26 * @dev: not used
27 * @drv: not used
28 * @index: not used
29 *
30 * A trivial wrapper to allow the cpu_do_idle function to be assigned as a
31 * cpuidle callback by matching the function signature.
32 *
33 * Returns the index passed as parameter
34 */
15int arm_cpuidle_simple_enter(struct cpuidle_device *dev, 35int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
16 struct cpuidle_driver *drv, int index) 36 struct cpuidle_driver *drv, int index)
17{ 37{
@@ -19,3 +39,114 @@ int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
19 39
20 return index; 40 return index;
21} 41}
42
43/**
44 * arm_cpuidle_suspend() - function to enter low power idle states
45 * @index: an integer used as an identifier for the low level PM callbacks
46 *
47 * This function calls the underlying arch specific low level PM code as
48 * registered at the init time.
49 *
50 * Returns -EOPNOTSUPP if no suspend callback is defined, the result of the
51 * callback otherwise.
52 */
53int arm_cpuidle_suspend(int index)
54{
55 int ret = -EOPNOTSUPP;
56 int cpu = smp_processor_id();
57
58 if (cpuidle_ops[cpu].suspend)
59 ret = cpuidle_ops[cpu].suspend(cpu, index);
60
61 return ret;
62}
63
64/**
65 * arm_cpuidle_get_ops() - find a registered cpuidle_ops by name
66 * @method: the method name
67 *
68 * Search in the __cpuidle_method_of_table array the cpuidle ops matching the
69 * method name.
70 *
71 * Returns a struct cpuidle_ops pointer, NULL if not found.
72 */
73static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
74{
75 struct of_cpuidle_method *m = __cpuidle_method_of_table;
76
77 for (; m->method; m++)
78 if (!strcmp(m->method, method))
79 return m->ops;
80
81 return NULL;
82}
83
84/**
85 * arm_cpuidle_read_ops() - Initialize the cpuidle ops with the device tree
86 * @dn: a pointer to a struct device node corresponding to a cpu node
87 * @cpu: the cpu identifier
88 *
89 * Get the method name defined in the 'enable-method' property, retrieve the
90 * associated cpuidle_ops and do a struct copy. This copy is needed because all
91 * cpuidle_ops are tagged __initdata and will be unloaded after the init
92 * process.
93 *
94 * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if
95 * no cpuidle_ops is registered for the 'enable-method'.
96 */
97static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu)
98{
99 const char *enable_method;
100 struct cpuidle_ops *ops;
101
102 enable_method = of_get_property(dn, "enable-method", NULL);
103 if (!enable_method)
104 return -ENOENT;
105
106 ops = arm_cpuidle_get_ops(enable_method);
107 if (!ops) {
108 pr_warn("%s: unsupported enable-method property: %s\n",
109 dn->full_name, enable_method);
110 return -EOPNOTSUPP;
111 }
112
113 cpuidle_ops[cpu] = *ops; /* structure copy */
114
115 pr_notice("cpuidle: enable-method property '%s'"
116 " found operations\n", enable_method);
117
118 return 0;
119}
120
121/**
122 * arm_cpuidle_init() - Initialize cpuidle_ops for a specific cpu
123 * @cpu: the cpu to be initialized
124 *
125 * Initialize the cpuidle ops with the device for the cpu and then call
126 * the cpu's idle initialization callback. This may fail if the underlying HW
127 * is not operational.
128 *
129 * Returns:
130 * 0 on success,
131 * -ENODEV if it fails to find the cpu node in the device tree,
132 * -EOPNOTSUPP if it does not find a registered cpuidle_ops for this cpu,
133 * -ENOENT if it fails to find an 'enable-method' property,
134 * -ENXIO if the HW reports a failure or a misconfiguration,
135 * -ENOMEM if the HW report an memory allocation failure
136 */
137int __init arm_cpuidle_init(int cpu)
138{
139 struct device_node *cpu_node = of_cpu_device_node_get(cpu);
140 int ret;
141
142 if (!cpu_node)
143 return -ENODEV;
144
145 ret = arm_cpuidle_read_ops(cpu_node, cpu);
146 if (!ret && cpuidle_ops[cpu].init)
147 ret = cpuidle_ops[cpu].init(cpu_node, cpu);
148
149 of_node_put(cpu_node);
150
151 return ret;
152}
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index e365c1bb1265..306ebc51599a 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -17,7 +17,6 @@
17#include <linux/cpuidle.h> 17#include <linux/cpuidle.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/export.h> 19#include <linux/export.h>
20#include <asm/proc-fns.h>
21#include <asm/cpuidle.h> 20#include <asm/cpuidle.h>
22 21
23#include <mach/cpuidle.h> 22#include <mach/cpuidle.h>
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c
index d76d08623f9f..8e21ccc1eda2 100644
--- a/arch/arm/mach-imx/cpuidle-imx6q.c
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -9,7 +9,6 @@
9#include <linux/cpuidle.h> 9#include <linux/cpuidle.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <asm/cpuidle.h> 11#include <asm/cpuidle.h>
12#include <asm/proc-fns.h>
13 12
14#include "common.h" 13#include "common.h"
15#include "cpuidle.h" 14#include "cpuidle.h"
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 7d92e6584551..5742a9fd1ef2 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -9,7 +9,6 @@
9#include <linux/cpuidle.h> 9#include <linux/cpuidle.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <asm/cpuidle.h> 11#include <asm/cpuidle.h>
12#include <asm/proc-fns.h>
13 12
14#include "common.h" 13#include "common.h"
15#include "cpuidle.h" 14#include "cpuidle.h"
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index 5a36722b089d..2c9f1a8bf245 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -10,7 +10,6 @@
10#include <linux/cpu_pm.h> 10#include <linux/cpu_pm.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <asm/cpuidle.h> 12#include <asm/cpuidle.h>
13#include <asm/proc-fns.h>
14#include <asm/suspend.h> 13#include <asm/suspend.h>
15 14
16#include "common.h" 15#include "common.h"
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 01e398a868bc..7622dbb05083 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -17,7 +17,6 @@
17#include <linux/clockchips.h> 17#include <linux/clockchips.h>
18 18
19#include <asm/cpuidle.h> 19#include <asm/cpuidle.h>
20#include <asm/proc-fns.h>
21 20
22#include "common.h" 21#include "common.h"
23#include "pm.h" 22#include "pm.h"
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
index 2eb072440dfa..93aa8cb70195 100644
--- a/arch/arm/mach-s3c64xx/cpuidle.c
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -16,7 +16,7 @@
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/time.h> 17#include <linux/time.h>
18 18
19#include <asm/proc-fns.h> 19#include <asm/cpuidle.h>
20 20
21#include <mach/map.h> 21#include <mach/map.h>
22 22
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index 4f25a7c7ca0f..e22b0d9fdc88 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -27,7 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28 28
29#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
30#include <asm/proc-fns.h>
31#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
32#include <asm/suspend.h> 31#include <asm/suspend.h>
33 32
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index f8815ed65d9d..a2400ab44daa 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -27,7 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28 28
29#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
30#include <asm/proc-fns.h>
31#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
32#include <asm/suspend.h> 31#include <asm/suspend.h>
33 32
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index be1f12a5a5f0..af6a452b1aac 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -48,7 +48,7 @@ CONFIG_CMDLINE="console=ttyAMA0"
48# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 48# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
49CONFIG_COMPAT=y 49CONFIG_COMPAT=y
50CONFIG_CPU_IDLE=y 50CONFIG_CPU_IDLE=y
51CONFIG_ARM64_CPUIDLE=y 51CONFIG_ARM_CPUIDLE=y
52CONFIG_NET=y 52CONFIG_NET=y
53CONFIG_PACKET=y 53CONFIG_PACKET=y
54CONFIG_UNIX=y 54CONFIG_UNIX=y
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
index c60643f14cda..141b2fcabaa6 100644
--- a/arch/arm64/include/asm/cpuidle.h
+++ b/arch/arm64/include/asm/cpuidle.h
@@ -4,10 +4,10 @@
4#include <asm/proc-fns.h> 4#include <asm/proc-fns.h>
5 5
6#ifdef CONFIG_CPU_IDLE 6#ifdef CONFIG_CPU_IDLE
7extern int cpu_init_idle(unsigned int cpu); 7extern int arm_cpuidle_init(unsigned int cpu);
8extern int cpu_suspend(unsigned long arg); 8extern int cpu_suspend(unsigned long arg);
9#else 9#else
10static inline int cpu_init_idle(unsigned int cpu) 10static inline int arm_cpuidle_init(unsigned int cpu)
11{ 11{
12 return -EOPNOTSUPP; 12 return -EOPNOTSUPP;
13} 13}
@@ -17,5 +17,8 @@ static inline int cpu_suspend(unsigned long arg)
17 return -EOPNOTSUPP; 17 return -EOPNOTSUPP;
18} 18}
19#endif 19#endif
20 20static inline int arm_cpuidle_suspend(int index)
21{
22 return cpu_suspend(index);
23}
21#endif 24#endif
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 5c0896647fd1..a78143a5c99f 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -15,7 +15,7 @@
15#include <asm/cpuidle.h> 15#include <asm/cpuidle.h>
16#include <asm/cpu_ops.h> 16#include <asm/cpu_ops.h>
17 17
18int cpu_init_idle(unsigned int cpu) 18int arm_cpuidle_init(unsigned int cpu)
19{ 19{
20 int ret = -EOPNOTSUPP; 20 int ret = -EOPNOTSUPP;
21 struct device_node *cpu_node = of_cpu_device_node_get(cpu); 21 struct device_node *cpu_node = of_cpu_device_node_get(cpu);
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");
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index c5029c1209b4..8c7930b5a65f 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -29,15 +29,10 @@ config DT_IDLE_STATES
29 bool 29 bool
30 30
31menu "ARM CPU Idle Drivers" 31menu "ARM CPU Idle Drivers"
32depends on ARM 32depends on ARM || ARM64
33source "drivers/cpuidle/Kconfig.arm" 33source "drivers/cpuidle/Kconfig.arm"
34endmenu 34endmenu
35 35
36menu "ARM64 CPU Idle Drivers"
37depends on ARM64
38source "drivers/cpuidle/Kconfig.arm64"
39endmenu
40
41menu "MIPS CPU Idle Drivers" 36menu "MIPS CPU Idle Drivers"
42depends on MIPS 37depends on MIPS
43source "drivers/cpuidle/Kconfig.mips" 38source "drivers/cpuidle/Kconfig.mips"
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 8e07c9419153..21340e0be73e 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -1,10 +1,20 @@
1# 1#
2# ARM CPU Idle drivers 2# ARM CPU Idle drivers
3# 3#
4config ARM_CPUIDLE
5 bool "Generic ARM/ARM64 CPU idle Driver"
6 select DT_IDLE_STATES
7 help
8 Select this to enable generic cpuidle driver for ARM.
9 It provides a generic idle driver whose idle states are configured
10 at run-time through DT nodes. The CPUidle suspend backend is
11 initialized by calling the CPU operations init idle hook
12 provided by architecture code.
13
4config ARM_BIG_LITTLE_CPUIDLE 14config ARM_BIG_LITTLE_CPUIDLE
5 bool "Support for ARM big.LITTLE processors" 15 bool "Support for ARM big.LITTLE processors"
6 depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS 16 depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
7 depends on MCPM 17 depends on MCPM && !ARM64
8 select ARM_CPU_SUSPEND 18 select ARM_CPU_SUSPEND
9 select CPU_IDLE_MULTIPLE_DRIVERS 19 select CPU_IDLE_MULTIPLE_DRIVERS
10 select DT_IDLE_STATES 20 select DT_IDLE_STATES
@@ -16,51 +26,51 @@ config ARM_BIG_LITTLE_CPUIDLE
16 26
17config ARM_CLPS711X_CPUIDLE 27config ARM_CLPS711X_CPUIDLE
18 bool "CPU Idle Driver for CLPS711X processors" 28 bool "CPU Idle Driver for CLPS711X processors"
19 depends on ARCH_CLPS711X || COMPILE_TEST 29 depends on ARCH_CLPS711X && !ARM64 || COMPILE_TEST
20 help 30 help
21 Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs. 31 Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs.
22 32
23config ARM_HIGHBANK_CPUIDLE 33config ARM_HIGHBANK_CPUIDLE
24 bool "CPU Idle Driver for Calxeda processors" 34 bool "CPU Idle Driver for Calxeda processors"
25 depends on ARM_PSCI 35 depends on ARM_PSCI && !ARM64
26 select ARM_CPU_SUSPEND 36 select ARM_CPU_SUSPEND
27 help 37 help
28 Select this to enable cpuidle on Calxeda processors. 38 Select this to enable cpuidle on Calxeda processors.
29 39
30config ARM_KIRKWOOD_CPUIDLE 40config ARM_KIRKWOOD_CPUIDLE
31 bool "CPU Idle Driver for Marvell Kirkwood SoCs" 41 bool "CPU Idle Driver for Marvell Kirkwood SoCs"
32 depends on MACH_KIRKWOOD 42 depends on MACH_KIRKWOOD && !ARM64
33 help 43 help
34 This adds the CPU Idle driver for Marvell Kirkwood SoCs. 44 This adds the CPU Idle driver for Marvell Kirkwood SoCs.
35 45
36config ARM_ZYNQ_CPUIDLE 46config ARM_ZYNQ_CPUIDLE
37 bool "CPU Idle Driver for Xilinx Zynq processors" 47 bool "CPU Idle Driver for Xilinx Zynq processors"
38 depends on ARCH_ZYNQ 48 depends on ARCH_ZYNQ && !ARM64
39 help 49 help
40 Select this to enable cpuidle on Xilinx Zynq processors. 50 Select this to enable cpuidle on Xilinx Zynq processors.
41 51
42config ARM_U8500_CPUIDLE 52config ARM_U8500_CPUIDLE
43 bool "Cpu Idle Driver for the ST-E u8500 processors" 53 bool "Cpu Idle Driver for the ST-E u8500 processors"
44 depends on ARCH_U8500 54 depends on ARCH_U8500 && !ARM64
45 help 55 help
46 Select this to enable cpuidle for ST-E u8500 processors 56 Select this to enable cpuidle for ST-E u8500 processors
47 57
48config ARM_AT91_CPUIDLE 58config ARM_AT91_CPUIDLE
49 bool "Cpu Idle Driver for the AT91 processors" 59 bool "Cpu Idle Driver for the AT91 processors"
50 default y 60 default y
51 depends on ARCH_AT91 61 depends on ARCH_AT91 && !ARM64
52 help 62 help
53 Select this to enable cpuidle for AT91 processors 63 Select this to enable cpuidle for AT91 processors
54 64
55config ARM_EXYNOS_CPUIDLE 65config ARM_EXYNOS_CPUIDLE
56 bool "Cpu Idle Driver for the Exynos processors" 66 bool "Cpu Idle Driver for the Exynos processors"
57 depends on ARCH_EXYNOS 67 depends on ARCH_EXYNOS && !ARM64
58 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP 68 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
59 help 69 help
60 Select this to enable cpuidle for Exynos processors 70 Select this to enable cpuidle for Exynos processors
61 71
62config ARM_MVEBU_V7_CPUIDLE 72config ARM_MVEBU_V7_CPUIDLE
63 bool "CPU Idle Driver for mvebu v7 family processors" 73 bool "CPU Idle Driver for mvebu v7 family processors"
64 depends on ARCH_MVEBU 74 depends on ARCH_MVEBU && !ARM64
65 help 75 help
66 Select this to enable cpuidle on Armada 370, 38x and XP processors. 76 Select this to enable cpuidle on Armada 370, 38x and XP processors.
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
deleted file mode 100644
index 6effb3656735..000000000000
--- a/drivers/cpuidle/Kconfig.arm64
+++ /dev/null
@@ -1,13 +0,0 @@
1#
2# ARM64 CPU Idle drivers
3#
4
5config ARM64_CPUIDLE
6 bool "Generic ARM64 CPU idle Driver"
7 select DT_IDLE_STATES
8 help
9 Select this to enable generic cpuidle driver for ARM64.
10 It provides a generic idle driver whose idle states are configured
11 at run-time through DT nodes. The CPUidle suspend backend is
12 initialized by calling the CPU operations init idle hook
13 provided by architecture code.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 4d177b916f75..3ba81b1dffad 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -17,16 +17,13 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o
17obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o 17obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
18obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o 18obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
19obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o 19obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o
20obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
20 21
21############################################################################### 22###############################################################################
22# MIPS drivers 23# MIPS drivers
23obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o 24obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o
24 25
25############################################################################### 26###############################################################################
26# ARM64 drivers
27obj-$(CONFIG_ARM64_CPUIDLE) += cpuidle-arm64.o
28
29###############################################################################
30# POWERPC drivers 27# POWERPC drivers
31obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o 28obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o
32obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o 29obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm.c
index 39a2c62716c3..545069d5fdfb 100644
--- a/drivers/cpuidle/cpuidle-arm64.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ARM64 generic CPU idle driver. 2 * ARM/ARM64 generic CPU idle driver.
3 * 3 *
4 * Copyright (C) 2014 ARM Ltd. 4 * Copyright (C) 2014 ARM Ltd.
5 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 5 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
@@ -9,7 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#define pr_fmt(fmt) "CPUidle arm64: " fmt 12#define pr_fmt(fmt) "CPUidle arm: " fmt
13 13
14#include <linux/cpuidle.h> 14#include <linux/cpuidle.h>
15#include <linux/cpumask.h> 15#include <linux/cpumask.h>
@@ -17,13 +17,14 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/slab.h>
20 21
21#include <asm/cpuidle.h> 22#include <asm/cpuidle.h>
22 23
23#include "dt_idle_states.h" 24#include "dt_idle_states.h"
24 25
25/* 26/*
26 * arm64_enter_idle_state - Programs CPU to enter the specified state 27 * arm_enter_idle_state - Programs CPU to enter the specified state
27 * 28 *
28 * dev: cpuidle device 29 * dev: cpuidle device
29 * drv: cpuidle driver 30 * drv: cpuidle driver
@@ -32,8 +33,8 @@
32 * Called from the CPUidle framework to program the device to the 33 * Called from the CPUidle framework to program the device to the
33 * specified target state selected by the governor. 34 * specified target state selected by the governor.
34 */ 35 */
35static int arm64_enter_idle_state(struct cpuidle_device *dev, 36static int arm_enter_idle_state(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv, int idx) 37 struct cpuidle_driver *drv, int idx)
37{ 38{
38 int ret; 39 int ret;
39 40
@@ -49,7 +50,7 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev,
49 * call the CPU ops suspend protocol with idle index as a 50 * call the CPU ops suspend protocol with idle index as a
50 * parameter. 51 * parameter.
51 */ 52 */
52 ret = cpu_suspend(idx); 53 arm_cpuidle_suspend(idx);
53 54
54 cpu_pm_exit(); 55 cpu_pm_exit();
55 } 56 }
@@ -57,8 +58,8 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev,
57 return ret ? -1 : idx; 58 return ret ? -1 : idx;
58} 59}
59 60
60static struct cpuidle_driver arm64_idle_driver = { 61static struct cpuidle_driver arm_idle_driver = {
61 .name = "arm64_idle", 62 .name = "arm_idle",
62 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
63 /* 64 /*
64 * State at index 0 is standby wfi and considered standard 65 * State at index 0 is standby wfi and considered standard
@@ -68,32 +69,33 @@ static struct cpuidle_driver arm64_idle_driver = {
68 * handler for idle state index 0. 69 * handler for idle state index 0.
69 */ 70 */
70 .states[0] = { 71 .states[0] = {
71 .enter = arm64_enter_idle_state, 72 .enter = arm_enter_idle_state,
72 .exit_latency = 1, 73 .exit_latency = 1,
73 .target_residency = 1, 74 .target_residency = 1,
74 .power_usage = UINT_MAX, 75 .power_usage = UINT_MAX,
75 .name = "WFI", 76 .name = "WFI",
76 .desc = "ARM64 WFI", 77 .desc = "ARM WFI",
77 } 78 }
78}; 79};
79 80
80static const struct of_device_id arm64_idle_state_match[] __initconst = { 81static const struct of_device_id arm_idle_state_match[] __initconst = {
81 { .compatible = "arm,idle-state", 82 { .compatible = "arm,idle-state",
82 .data = arm64_enter_idle_state }, 83 .data = arm_enter_idle_state },
83 { }, 84 { },
84}; 85};
85 86
86/* 87/*
87 * arm64_idle_init 88 * arm_idle_init
88 * 89 *
89 * Registers the arm64 specific cpuidle driver with the cpuidle 90 * Registers the arm specific cpuidle driver with the cpuidle
90 * framework. It relies on core code to parse the idle states 91 * framework. It relies on core code to parse the idle states
91 * and initialize them using driver data structures accordingly. 92 * and initialize them using driver data structures accordingly.
92 */ 93 */
93static int __init arm64_idle_init(void) 94static int __init arm_idle_init(void)
94{ 95{
95 int cpu, ret; 96 int cpu, ret;
96 struct cpuidle_driver *drv = &arm64_idle_driver; 97 struct cpuidle_driver *drv = &arm_idle_driver;
98 struct cpuidle_device *dev;
97 99
98 /* 100 /*
99 * Initialize idle states data, starting at index 1. 101 * Initialize idle states data, starting at index 1.
@@ -101,22 +103,61 @@ static int __init arm64_idle_init(void)
101 * let the driver initialization fail accordingly since there is no 103 * let the driver initialization fail accordingly since there is no
102 * reason to initialize the idle driver if only wfi is supported. 104 * reason to initialize the idle driver if only wfi is supported.
103 */ 105 */
104 ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1); 106 ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
105 if (ret <= 0) 107 if (ret <= 0)
106 return ret ? : -ENODEV; 108 return ret ? : -ENODEV;
107 109
110 ret = cpuidle_register_driver(drv);
111 if (ret) {
112 pr_err("Failed to register cpuidle driver\n");
113 return ret;
114 }
115
108 /* 116 /*
109 * Call arch CPU operations in order to initialize 117 * Call arch CPU operations in order to initialize
110 * idle states suspend back-end specific data 118 * idle states suspend back-end specific data
111 */ 119 */
112 for_each_possible_cpu(cpu) { 120 for_each_possible_cpu(cpu) {
113 ret = cpu_init_idle(cpu); 121 ret = arm_cpuidle_init(cpu);
122
123 /*
124 * Skip the cpuidle device initialization if the reported
125 * failure is a HW misconfiguration/breakage (-ENXIO).
126 */
127 if (ret == -ENXIO)
128 continue;
129
114 if (ret) { 130 if (ret) {
115 pr_err("CPU %d failed to init idle CPU ops\n", cpu); 131 pr_err("CPU %d failed to init idle CPU ops\n", cpu);
116 return ret; 132 goto out_fail;
133 }
134
135 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
136 if (!dev) {
137 pr_err("Failed to allocate cpuidle device\n");
138 goto out_fail;
139 }
140 dev->cpu = cpu;
141
142 ret = cpuidle_register_device(dev);
143 if (ret) {
144 pr_err("Failed to register cpuidle device for CPU %d\n",
145 cpu);
146 kfree(dev);
147 goto out_fail;
117 } 148 }
118 } 149 }
119 150
120 return cpuidle_register(drv, NULL); 151 return 0;
152out_fail:
153 while (--cpu >= 0) {
154 dev = per_cpu(cpuidle_devices, cpu);
155 cpuidle_unregister_device(dev);
156 kfree(dev);
157 }
158
159 cpuidle_unregister_driver(drv);
160
161 return ret;
121} 162}
122device_initcall(arm64_idle_init); 163device_initcall(arm_idle_init);
diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c
index aae7bfc1ea36..f2446c78d87c 100644
--- a/drivers/cpuidle/cpuidle-at91.c
+++ b/drivers/cpuidle/cpuidle-at91.c
@@ -19,7 +19,6 @@
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h> 22#include <asm/cpuidle.h>
24 23
25#define AT91_MAX_STATES 2 24#define AT91_MAX_STATES 2
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
index 26f5f29fdb03..0c06ea2f50bb 100644
--- a/drivers/cpuidle/cpuidle-exynos.c
+++ b/drivers/cpuidle/cpuidle-exynos.c
@@ -19,7 +19,6 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_data/cpuidle-exynos.h> 20#include <linux/platform_data/cpuidle-exynos.h>
21 21
22#include <asm/proc-fns.h>
23#include <asm/suspend.h> 22#include <asm/suspend.h>
24#include <asm/cpuidle.h> 23#include <asm/cpuidle.h>
25 24
diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c
index cea0a6c4b1db..d23d8f468c12 100644
--- a/drivers/cpuidle/cpuidle-kirkwood.c
+++ b/drivers/cpuidle/cpuidle-kirkwood.c
@@ -21,7 +21,6 @@
21#include <linux/cpuidle.h> 21#include <linux/cpuidle.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/export.h> 23#include <linux/export.h>
24#include <asm/proc-fns.h>
25#include <asm/cpuidle.h> 24#include <asm/cpuidle.h>
26 25
27#define KIRKWOOD_MAX_STATES 2 26#define KIRKWOOD_MAX_STATES 2
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c
index 66f81e410f0d..8bf895c0017d 100644
--- a/drivers/cpuidle/cpuidle-ux500.c
+++ b/drivers/cpuidle/cpuidle-ux500.c
@@ -19,7 +19,6 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/cpuidle.h> 21#include <asm/cpuidle.h>
22#include <asm/proc-fns.h>
23 22
24static atomic_t master = ATOMIC_INIT(0); 23static atomic_t master = ATOMIC_INIT(0);
25static DEFINE_SPINLOCK(master_lock); 24static DEFINE_SPINLOCK(master_lock);
diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c
index 002b8c9f98f5..543292b1d38e 100644
--- a/drivers/cpuidle/cpuidle-zynq.c
+++ b/drivers/cpuidle/cpuidle-zynq.c
@@ -28,7 +28,6 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpuidle.h> 29#include <linux/cpuidle.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <asm/proc-fns.h>
32#include <asm/cpuidle.h> 31#include <asm/cpuidle.h>
33 32
34#define ZYNQ_MAX_STATES 2 33#define ZYNQ_MAX_STATES 2
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0e58522780d..1fb52f4e5870 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -218,18 +218,10 @@ static struct cpuidle_state byt_cstates[] = {
218 .enter = &intel_idle, 218 .enter = &intel_idle,
219 .enter_freeze = intel_idle_freeze, }, 219 .enter_freeze = intel_idle_freeze, },
220 { 220 {
221 .name = "C1E-BYT",
222 .desc = "MWAIT 0x01",
223 .flags = MWAIT2flg(0x01),
224 .exit_latency = 15,
225 .target_residency = 30,
226 .enter = &intel_idle,
227 .enter_freeze = intel_idle_freeze, },
228 {
229 .name = "C6N-BYT", 221 .name = "C6N-BYT",
230 .desc = "MWAIT 0x58", 222 .desc = "MWAIT 0x58",
231 .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 223 .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED,
232 .exit_latency = 40, 224 .exit_latency = 300,
233 .target_residency = 275, 225 .target_residency = 275,
234 .enter = &intel_idle, 226 .enter = &intel_idle,
235 .enter_freeze = intel_idle_freeze, }, 227 .enter_freeze = intel_idle_freeze, },
@@ -237,7 +229,7 @@ static struct cpuidle_state byt_cstates[] = {
237 .name = "C6S-BYT", 229 .name = "C6S-BYT",
238 .desc = "MWAIT 0x52", 230 .desc = "MWAIT 0x52",
239 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 231 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
240 .exit_latency = 140, 232 .exit_latency = 500,
241 .target_residency = 560, 233 .target_residency = 560,
242 .enter = &intel_idle, 234 .enter = &intel_idle,
243 .enter_freeze = intel_idle_freeze, }, 235 .enter_freeze = intel_idle_freeze, },
@@ -246,7 +238,7 @@ static struct cpuidle_state byt_cstates[] = {
246 .desc = "MWAIT 0x60", 238 .desc = "MWAIT 0x60",
247 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 239 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
248 .exit_latency = 1200, 240 .exit_latency = 1200,
249 .target_residency = 1500, 241 .target_residency = 4000,
250 .enter = &intel_idle, 242 .enter = &intel_idle,
251 .enter_freeze = intel_idle_freeze, }, 243 .enter_freeze = intel_idle_freeze, },
252 { 244 {
@@ -261,6 +253,51 @@ static struct cpuidle_state byt_cstates[] = {
261 .enter = NULL } 253 .enter = NULL }
262}; 254};
263 255
256static struct cpuidle_state cht_cstates[] = {
257 {
258 .name = "C1-CHT",
259 .desc = "MWAIT 0x00",
260 .flags = MWAIT2flg(0x00),
261 .exit_latency = 1,
262 .target_residency = 1,
263 .enter = &intel_idle,
264 .enter_freeze = intel_idle_freeze, },
265 {
266 .name = "C6N-CHT",
267 .desc = "MWAIT 0x58",
268 .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED,
269 .exit_latency = 80,
270 .target_residency = 275,
271 .enter = &intel_idle,
272 .enter_freeze = intel_idle_freeze, },
273 {
274 .name = "C6S-CHT",
275 .desc = "MWAIT 0x52",
276 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
277 .exit_latency = 200,
278 .target_residency = 560,
279 .enter = &intel_idle,
280 .enter_freeze = intel_idle_freeze, },
281 {
282 .name = "C7-CHT",
283 .desc = "MWAIT 0x60",
284 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
285 .exit_latency = 1200,
286 .target_residency = 4000,
287 .enter = &intel_idle,
288 .enter_freeze = intel_idle_freeze, },
289 {
290 .name = "C7S-CHT",
291 .desc = "MWAIT 0x64",
292 .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED,
293 .exit_latency = 10000,
294 .target_residency = 20000,
295 .enter = &intel_idle,
296 .enter_freeze = intel_idle_freeze, },
297 {
298 .enter = NULL }
299};
300
264static struct cpuidle_state ivb_cstates[] = { 301static struct cpuidle_state ivb_cstates[] = {
265 { 302 {
266 .name = "C1-IVB", 303 .name = "C1-IVB",
@@ -748,6 +785,12 @@ static const struct idle_cpu idle_cpu_byt = {
748 .byt_auto_demotion_disable_flag = true, 785 .byt_auto_demotion_disable_flag = true,
749}; 786};
750 787
788static const struct idle_cpu idle_cpu_cht = {
789 .state_table = cht_cstates,
790 .disable_promotion_to_c1e = true,
791 .byt_auto_demotion_disable_flag = true,
792};
793
751static const struct idle_cpu idle_cpu_ivb = { 794static const struct idle_cpu idle_cpu_ivb = {
752 .state_table = ivb_cstates, 795 .state_table = ivb_cstates,
753 .disable_promotion_to_c1e = true, 796 .disable_promotion_to_c1e = true,
@@ -776,7 +819,7 @@ static const struct idle_cpu idle_cpu_avn = {
776#define ICPU(model, cpu) \ 819#define ICPU(model, cpu) \
777 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } 820 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
778 821
779static const struct x86_cpu_id intel_idle_ids[] = { 822static const struct x86_cpu_id intel_idle_ids[] __initconst = {
780 ICPU(0x1a, idle_cpu_nehalem), 823 ICPU(0x1a, idle_cpu_nehalem),
781 ICPU(0x1e, idle_cpu_nehalem), 824 ICPU(0x1e, idle_cpu_nehalem),
782 ICPU(0x1f, idle_cpu_nehalem), 825 ICPU(0x1f, idle_cpu_nehalem),
@@ -790,6 +833,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
790 ICPU(0x2d, idle_cpu_snb), 833 ICPU(0x2d, idle_cpu_snb),
791 ICPU(0x36, idle_cpu_atom), 834 ICPU(0x36, idle_cpu_atom),
792 ICPU(0x37, idle_cpu_byt), 835 ICPU(0x37, idle_cpu_byt),
836 ICPU(0x4c, idle_cpu_cht),
793 ICPU(0x3a, idle_cpu_ivb), 837 ICPU(0x3a, idle_cpu_ivb),
794 ICPU(0x3e, idle_cpu_ivt), 838 ICPU(0x3e, idle_cpu_ivt),
795 ICPU(0x3c, idle_cpu_hsw), 839 ICPU(0x3c, idle_cpu_hsw),
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ac78910d7416..91c09305106d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -167,6 +167,7 @@
167#define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu) 167#define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu)
168#define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) 168#define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
169#define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) 169#define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method)
170#define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
170#define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) 171#define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
171 172
172#define KERNEL_DTB() \ 173#define KERNEL_DTB() \
@@ -501,6 +502,7 @@
501 CLKSRC_OF_TABLES() \ 502 CLKSRC_OF_TABLES() \
502 IOMMU_OF_TABLES() \ 503 IOMMU_OF_TABLES() \
503 CPU_METHOD_OF_TABLES() \ 504 CPU_METHOD_OF_TABLES() \
505 CPUIDLE_METHOD_OF_TABLES() \
504 KERNEL_DTB() \ 506 KERNEL_DTB() \
505 IRQCHIP_OF_MATCH_TABLE() \ 507 IRQCHIP_OF_MATCH_TABLE() \
506 EARLYCON_OF_TABLES() 508 EARLYCON_OF_TABLES()