aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/at91rm9200.c2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c2
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c2
-rw-r--r--arch/arm/mach-at91/cpuidle.c68
-rw-r--r--arch/arm/mach-at91/pm.c27
-rw-r--r--arch/arm/mach-at91/pm.h59
-rw-r--r--arch/arm/mach-at91/setup.c14
-rw-r--r--arch/arm/mach-davinci/Kconfig1
-rw-r--r--arch/arm/mach-exynos/common.c11
-rw-r--r--arch/arm/mach-exynos/common.h1
-rw-r--r--arch/arm/mach-exynos/cpuidle.c18
-rw-r--r--arch/arm/mach-exynos/mach-exynos4-dt.c2
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c10
-rw-r--r--arch/arm/mach-omap2/omap-pm.h2
-rw-r--r--arch/arm/mach-omap2/opp.c6
-rw-r--r--arch/arm/mach-omap2/pm.c8
-rw-r--r--arch/arm/mach-pxa/Kconfig3
-rw-r--r--arch/arm/mach-sa1100/generic.c81
-rw-r--r--arch/arm/mach-sa1100/generic.h7
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-vexpress/Kconfig12
-rw-r--r--arch/arm/mach-vexpress/Makefile3
-rw-r--r--arch/arm/mach-vexpress/spc.c366
-rw-r--r--arch/arm/mach-vexpress/spc.h2
-rw-r--r--arch/arm/mach-vexpress/tc2_pm.c7
-rw-r--r--arch/arm/mach-zynq/common.c6
-rw-r--r--arch/blackfin/Kconfig1
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/ia64/kernel/acpi.c38
-rw-r--r--arch/powerpc/kernel/smp.c12
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c43
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/include/asm/acpi.h1
-rw-r--r--arch/x86/include/asm/mpspec.h2
-rw-r--r--arch/x86/include/asm/msr.h22
-rw-r--r--arch/x86/kernel/acpi/boot.c90
-rw-r--r--arch/x86/kernel/acpi/sleep.c11
-rw-r--r--arch/x86/kernel/acpi/sleep.h2
-rw-r--r--arch/x86/kernel/acpi/wakeup_32.S2
-rw-r--r--arch/x86/kernel/acpi/wakeup_64.S2
-rw-r--r--arch/x86/kernel/apic/apic.c8
-rw-r--r--arch/x86/kernel/smpboot.c21
-rw-r--r--arch/x86/kernel/topology.c11
-rw-r--r--arch/x86/lib/msr-smp.c62
-rw-r--r--arch/x86/platform/olpc/olpc-xo15-sci.c9
51 files changed, 681 insertions, 396 deletions
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 3b0a9538093c..c1b737097c95 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -98,7 +98,6 @@ obj-y += leds.o
98# Power Management 98# Power Management
99obj-$(CONFIG_PM) += pm.o 99obj-$(CONFIG_PM) += pm.o
100obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o 100obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o
101obj-$(CONFIG_CPU_IDLE) += cpuidle.o
102 101
103ifeq ($(CONFIG_PM_DEBUG),y) 102ifeq ($(CONFIG_PM_DEBUG),y)
104CFLAGS_pm.o += -DDEBUG 103CFLAGS_pm.o += -DDEBUG
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 4aad93d54d6f..25805f2f6010 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -27,6 +27,7 @@
27#include "generic.h" 27#include "generic.h"
28#include "clock.h" 28#include "clock.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
30#include "pm.h"
30 31
31/* -------------------------------------------------------------------- 32/* --------------------------------------------------------------------
32 * Clocks 33 * Clocks
@@ -327,6 +328,7 @@ static void __init at91rm9200_ioremap_registers(void)
327{ 328{
328 at91rm9200_ioremap_st(AT91RM9200_BASE_ST); 329 at91rm9200_ioremap_st(AT91RM9200_BASE_ST);
329 at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256); 330 at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256);
331 at91_pm_set_standby(at91rm9200_standby);
330} 332}
331 333
332static void __init at91rm9200_initialize(void) 334static void __init at91rm9200_initialize(void)
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 5de6074b4f4f..f8629a3fa245 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -28,6 +28,7 @@
28#include "generic.h" 28#include "generic.h"
29#include "clock.h" 29#include "clock.h"
30#include "sam9_smc.h" 30#include "sam9_smc.h"
31#include "pm.h"
31 32
32/* -------------------------------------------------------------------- 33/* --------------------------------------------------------------------
33 * Clocks 34 * Clocks
@@ -342,6 +343,7 @@ static void __init at91sam9260_ioremap_registers(void)
342 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); 343 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
343 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); 344 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
344 at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX); 345 at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX);
346 at91_pm_set_standby(at91sam9_sdram_standby);
345} 347}
346 348
347static void __init at91sam9260_initialize(void) 349static void __init at91sam9260_initialize(void)
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 0e0793241ab7..1f3867a17a28 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -27,6 +27,7 @@
27#include "generic.h" 27#include "generic.h"
28#include "clock.h" 28#include "clock.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
30#include "pm.h"
30 31
31/* -------------------------------------------------------------------- 32/* --------------------------------------------------------------------
32 * Clocks 33 * Clocks
@@ -284,6 +285,7 @@ static void __init at91sam9261_ioremap_registers(void)
284 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); 285 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
285 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); 286 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
286 at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX); 287 at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX);
288 at91_pm_set_standby(at91sam9_sdram_standby);
287} 289}
288 290
289static void __init at91sam9261_initialize(void) 291static void __init at91sam9261_initialize(void)
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 6ce7d1850893..90d455d294a1 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -26,6 +26,7 @@
26#include "generic.h" 26#include "generic.h"
27#include "clock.h" 27#include "clock.h"
28#include "sam9_smc.h" 28#include "sam9_smc.h"
29#include "pm.h"
29 30
30/* -------------------------------------------------------------------- 31/* --------------------------------------------------------------------
31 * Clocks 32 * Clocks
@@ -321,6 +322,7 @@ static void __init at91sam9263_ioremap_registers(void)
321 at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); 322 at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0);
322 at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); 323 at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
323 at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX); 324 at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX);
325 at91_pm_set_standby(at91sam9_sdram_standby);
324} 326}
325 327
326static void __init at91sam9263_initialize(void) 328static void __init at91sam9263_initialize(void)
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 474ee04d24b9..e9bf0b8f40eb 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -26,6 +26,7 @@
26#include "generic.h" 26#include "generic.h"
27#include "clock.h" 27#include "clock.h"
28#include "sam9_smc.h" 28#include "sam9_smc.h"
29#include "pm.h"
29 30
30/* -------------------------------------------------------------------- 31/* --------------------------------------------------------------------
31 * Clocks 32 * Clocks
@@ -370,6 +371,7 @@ static void __init at91sam9g45_ioremap_registers(void)
370 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); 371 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
371 at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); 372 at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC);
372 at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX); 373 at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX);
374 at91_pm_set_standby(at91_ddr_standby);
373} 375}
374 376
375static void __init at91sam9g45_initialize(void) 377static void __init at91sam9g45_initialize(void)
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index d4ec0d9a9872..88995af09c04 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -27,6 +27,7 @@
27#include "generic.h" 27#include "generic.h"
28#include "clock.h" 28#include "clock.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
30#include "pm.h"
30 31
31/* -------------------------------------------------------------------- 32/* --------------------------------------------------------------------
32 * Clocks 33 * Clocks
@@ -287,6 +288,7 @@ static void __init at91sam9rl_ioremap_registers(void)
287 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); 288 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
288 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); 289 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
289 at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX); 290 at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX);
291 at91_pm_set_standby(at91sam9_sdram_standby);
290} 292}
291 293
292static void __init at91sam9rl_initialize(void) 294static void __init at91sam9rl_initialize(void)
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
deleted file mode 100644
index 4ec6a6d9b9be..000000000000
--- a/arch/arm/mach-at91/cpuidle.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * based on arch/arm/mach-kirkwood/cpuidle.c
3 *
4 * CPU idle support for AT91 SoC
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 *
10 * The cpu idle uses wait-for-interrupt and RAM self refresh in order
11 * to implement two idle states -
12 * #1 wait-for-interrupt
13 * #2 wait-for-interrupt and RAM self refresh
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/cpuidle.h>
20#include <linux/io.h>
21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
24#include <mach/cpu.h>
25
26#include "pm.h"
27
28#define AT91_MAX_STATES 2
29
30/* Actual code that puts the SoC in different idle states */
31static int at91_enter_idle(struct cpuidle_device *dev,
32 struct cpuidle_driver *drv,
33 int index)
34{
35 if (cpu_is_at91rm9200())
36 at91rm9200_standby();
37 else if (cpu_is_at91sam9g45())
38 at91sam9g45_standby();
39 else if (cpu_is_at91sam9263())
40 at91sam9263_standby();
41 else
42 at91sam9_standby();
43
44 return index;
45}
46
47static struct cpuidle_driver at91_idle_driver = {
48 .name = "at91_idle",
49 .owner = THIS_MODULE,
50 .states[0] = ARM_CPUIDLE_WFI_STATE,
51 .states[1] = {
52 .enter = at91_enter_idle,
53 .exit_latency = 10,
54 .target_residency = 10000,
55 .flags = CPUIDLE_FLAG_TIME_VALID,
56 .name = "RAM_SR",
57 .desc = "WFI and DDR Self Refresh",
58 },
59 .state_count = AT91_MAX_STATES,
60};
61
62/* Initialize CPU idle by registering the idle states */
63static int __init at91_init_cpuidle(void)
64{
65 return cpuidle_register(&at91_idle_driver, NULL);
66}
67
68device_initcall(at91_init_cpuidle);
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 15afb5d9271f..9986542e8060 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -39,6 +39,8 @@
39#include "at91_rstc.h" 39#include "at91_rstc.h"
40#include "at91_shdwc.h" 40#include "at91_shdwc.h"
41 41
42static void (*at91_pm_standby)(void);
43
42static void __init show_reset_status(void) 44static void __init show_reset_status(void)
43{ 45{
44 static char reset[] __initdata = "reset"; 46 static char reset[] __initdata = "reset";
@@ -266,14 +268,8 @@ static int at91_pm_enter(suspend_state_t state)
266 * For ARM 926 based chips, this requirement is weaker 268 * For ARM 926 based chips, this requirement is weaker
267 * as at91sam9 can access a RAM in self-refresh mode. 269 * as at91sam9 can access a RAM in self-refresh mode.
268 */ 270 */
269 if (cpu_is_at91rm9200()) 271 if (at91_pm_standby)
270 at91rm9200_standby(); 272 at91_pm_standby();
271 else if (cpu_is_at91sam9g45())
272 at91sam9g45_standby();
273 else if (cpu_is_at91sam9263())
274 at91sam9263_standby();
275 else
276 at91sam9_standby();
277 break; 273 break;
278 274
279 case PM_SUSPEND_ON: 275 case PM_SUSPEND_ON:
@@ -314,6 +310,18 @@ static const struct platform_suspend_ops at91_pm_ops = {
314 .end = at91_pm_end, 310 .end = at91_pm_end,
315}; 311};
316 312
313static struct platform_device at91_cpuidle_device = {
314 .name = "cpuidle-at91",
315};
316
317void at91_pm_set_standby(void (*at91_standby)(void))
318{
319 if (at91_standby) {
320 at91_cpuidle_device.dev.platform_data = at91_standby;
321 at91_pm_standby = at91_standby;
322 }
323}
324
317static int __init at91_pm_init(void) 325static int __init at91_pm_init(void)
318{ 326{
319#ifdef CONFIG_AT91_SLOW_CLOCK 327#ifdef CONFIG_AT91_SLOW_CLOCK
@@ -325,6 +333,9 @@ static int __init at91_pm_init(void)
325 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ 333 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
326 if (cpu_is_at91rm9200()) 334 if (cpu_is_at91rm9200())
327 at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); 335 at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
336
337 if (at91_cpuidle_device.dev.platform_data)
338 platform_device_register(&at91_cpuidle_device);
328 339
329 suspend_set_ops(&at91_pm_ops); 340 suspend_set_ops(&at91_pm_ops);
330 341
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 2f5908f0b8c5..3ed190ce062b 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -11,9 +11,13 @@
11#ifndef __ARCH_ARM_MACH_AT91_PM 11#ifndef __ARCH_ARM_MACH_AT91_PM
12#define __ARCH_ARM_MACH_AT91_PM 12#define __ARCH_ARM_MACH_AT91_PM
13 13
14#include <asm/proc-fns.h>
15
14#include <mach/at91_ramc.h> 16#include <mach/at91_ramc.h>
15#include <mach/at91rm9200_sdramc.h> 17#include <mach/at91rm9200_sdramc.h>
16 18
19extern void at91_pm_set_standby(void (*at91_standby)(void));
20
17/* 21/*
18 * The AT91RM9200 goes into self-refresh mode with this command, and will 22 * The AT91RM9200 goes into self-refresh mode with this command, and will
19 * terminate self-refresh automatically on the next SDRAM access. 23 * terminate self-refresh automatically on the next SDRAM access.
@@ -45,16 +49,18 @@ static inline void at91rm9200_standby(void)
45/* We manage both DDRAM/SDRAM controllers, we need more than one value to 49/* We manage both DDRAM/SDRAM controllers, we need more than one value to
46 * remember. 50 * remember.
47 */ 51 */
48static inline void at91sam9g45_standby(void) 52static inline void at91_ddr_standby(void)
49{ 53{
50 /* Those two values allow us to delay self-refresh activation 54 /* Those two values allow us to delay self-refresh activation
51 * to the maximum. */ 55 * to the maximum. */
52 u32 lpr0, lpr1; 56 u32 lpr0, lpr1 = 0;
53 u32 saved_lpr0, saved_lpr1; 57 u32 saved_lpr0, saved_lpr1 = 0;
54 58
55 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); 59 if (at91_ramc_base[1]) {
56 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; 60 saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
57 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; 61 lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
62 lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
63 }
58 64
59 saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); 65 saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
60 lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; 66 lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
@@ -62,25 +68,29 @@ static inline void at91sam9g45_standby(void)
62 68
63 /* self-refresh mode now */ 69 /* self-refresh mode now */
64 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); 70 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
65 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); 71 if (at91_ramc_base[1])
72 at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
66 73
67 cpu_do_idle(); 74 cpu_do_idle();
68 75
69 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); 76 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
70 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); 77 if (at91_ramc_base[1])
78 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
71} 79}
72 80
73/* We manage both DDRAM/SDRAM controllers, we need more than one value to 81/* We manage both DDRAM/SDRAM controllers, we need more than one value to
74 * remember. 82 * remember.
75 */ 83 */
76static inline void at91sam9263_standby(void) 84static inline void at91sam9_sdram_standby(void)
77{ 85{
78 u32 lpr0, lpr1; 86 u32 lpr0, lpr1 = 0;
79 u32 saved_lpr0, saved_lpr1; 87 u32 saved_lpr0, saved_lpr1 = 0;
80 88
81 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); 89 if (at91_ramc_base[1]) {
82 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; 90 saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
83 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; 91 lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
92 lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
93 }
84 94
85 saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR); 95 saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR);
86 lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB; 96 lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB;
@@ -88,27 +98,14 @@ static inline void at91sam9263_standby(void)
88 98
89 /* self-refresh mode now */ 99 /* self-refresh mode now */
90 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0); 100 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
91 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); 101 if (at91_ramc_base[1])
102 at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
92 103
93 cpu_do_idle(); 104 cpu_do_idle();
94 105
95 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0); 106 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
96 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); 107 if (at91_ramc_base[1])
97} 108 at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
98
99static inline void at91sam9_standby(void)
100{
101 u32 saved_lpr, lpr;
102
103 saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
104
105 lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
106 at91_ramc_write(0, AT91_SDRAMC_LPR, lpr |
107 AT91_SDRAMC_LPCB_SELF_REFRESH);
108
109 cpu_do_idle();
110
111 at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr);
112} 109}
113 110
114#endif 111#endif
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index b17fbcf4d9e8..094b3459c288 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -23,6 +23,7 @@
23#include "at91_shdwc.h" 23#include "at91_shdwc.h"
24#include "soc.h" 24#include "soc.h"
25#include "generic.h" 25#include "generic.h"
26#include "pm.h"
26 27
27struct at91_init_soc __initdata at91_boot_soc; 28struct at91_init_soc __initdata at91_boot_soc;
28 29
@@ -376,15 +377,16 @@ static void at91_dt_rstc(void)
376} 377}
377 378
378static struct of_device_id ramc_ids[] = { 379static struct of_device_id ramc_ids[] = {
379 { .compatible = "atmel,at91rm9200-sdramc" }, 380 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
380 { .compatible = "atmel,at91sam9260-sdramc" }, 381 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
381 { .compatible = "atmel,at91sam9g45-ddramc" }, 382 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
382 { /*sentinel*/ } 383 { /*sentinel*/ }
383}; 384};
384 385
385static void at91_dt_ramc(void) 386static void at91_dt_ramc(void)
386{ 387{
387 struct device_node *np; 388 struct device_node *np;
389 const struct of_device_id *of_id;
388 390
389 np = of_find_matching_node(NULL, ramc_ids); 391 np = of_find_matching_node(NULL, ramc_ids);
390 if (!np) 392 if (!np)
@@ -396,6 +398,12 @@ static void at91_dt_ramc(void)
396 /* the controller may have 2 banks */ 398 /* the controller may have 2 banks */
397 at91_ramc_base[1] = of_iomap(np, 1); 399 at91_ramc_base[1] = of_iomap(np, 1);
398 400
401 of_id = of_match_node(ramc_ids, np);
402 if (!of_id)
403 pr_warn("AT91: ramc no standby function available\n");
404 else
405 at91_pm_set_standby(of_id->data);
406
399 of_node_put(np); 407 of_node_put(np);
400} 408}
401 409
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index e026b19b23ea..a075b3e0c5c7 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -40,7 +40,6 @@ config ARCH_DAVINCI_DA850
40 bool "DA850/OMAP-L138/AM18x based system" 40 bool "DA850/OMAP-L138/AM18x based system"
41 select ARCH_DAVINCI_DA8XX 41 select ARCH_DAVINCI_DA8XX
42 select ARCH_HAS_CPUFREQ 42 select ARCH_HAS_CPUFREQ
43 select CPU_FREQ_TABLE
44 select CP_INTC 43 select CP_INTC
45 44
46config ARCH_DAVINCI_DA8XX 45config ARCH_DAVINCI_DA8XX
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index a4e7ba828810..61d2906ccefb 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -28,6 +28,7 @@
28#include <linux/of_address.h> 28#include <linux/of_address.h>
29#include <linux/irqchip/arm-gic.h> 29#include <linux/irqchip/arm-gic.h>
30#include <linux/irqchip/chained_irq.h> 30#include <linux/irqchip/chained_irq.h>
31#include <linux/platform_device.h>
31 32
32#include <asm/proc-fns.h> 33#include <asm/proc-fns.h>
33#include <asm/exception.h> 34#include <asm/exception.h>
@@ -292,6 +293,16 @@ void exynos5_restart(enum reboot_mode mode, const char *cmd)
292 __raw_writel(val, addr); 293 __raw_writel(val, addr);
293} 294}
294 295
296static struct platform_device exynos_cpuidle = {
297 .name = "exynos_cpuidle",
298 .id = -1,
299};
300
301void __init exynos_cpuidle_init(void)
302{
303 platform_device_register(&exynos_cpuidle);
304}
305
295void __init exynos_init_late(void) 306void __init exynos_init_late(void)
296{ 307{
297 if (of_machine_is_compatible("samsung,exynos5440")) 308 if (of_machine_is_compatible("samsung,exynos5440"))
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index f0fa2050d08d..ff9b6a9419b0 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -21,6 +21,7 @@ struct map_desc;
21void exynos_init_io(void); 21void exynos_init_io(void);
22void exynos4_restart(enum reboot_mode mode, const char *cmd); 22void exynos4_restart(enum reboot_mode mode, const char *cmd);
23void exynos5_restart(enum reboot_mode mode, const char *cmd); 23void exynos5_restart(enum reboot_mode mode, const char *cmd);
24void exynos_cpuidle_init(void);
24void exynos_init_late(void); 25void exynos_init_late(void);
25 26
26void exynos_firmware_init(void); 27void exynos_firmware_init(void);
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index ac139226d63c..ddbfe8709fe7 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -15,6 +15,7 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/platform_device.h>
18 19
19#include <asm/proc-fns.h> 20#include <asm/proc-fns.h>
20#include <asm/smp_scu.h> 21#include <asm/smp_scu.h>
@@ -192,7 +193,7 @@ static void __init exynos5_core_down_clk(void)
192 __raw_writel(tmp, EXYNOS5_PWR_CTRL2); 193 __raw_writel(tmp, EXYNOS5_PWR_CTRL2);
193} 194}
194 195
195static int __init exynos4_init_cpuidle(void) 196static int exynos_cpuidle_probe(struct platform_device *pdev)
196{ 197{
197 int cpu_id, ret; 198 int cpu_id, ret;
198 struct cpuidle_device *device; 199 struct cpuidle_device *device;
@@ -205,7 +206,7 @@ static int __init exynos4_init_cpuidle(void)
205 206
206 ret = cpuidle_register_driver(&exynos4_idle_driver); 207 ret = cpuidle_register_driver(&exynos4_idle_driver);
207 if (ret) { 208 if (ret) {
208 printk(KERN_ERR "CPUidle failed to register driver\n"); 209 dev_err(&pdev->dev, "failed to register cpuidle driver\n");
209 return ret; 210 return ret;
210 } 211 }
211 212
@@ -219,11 +220,20 @@ static int __init exynos4_init_cpuidle(void)
219 220
220 ret = cpuidle_register_device(device); 221 ret = cpuidle_register_device(device);
221 if (ret) { 222 if (ret) {
222 printk(KERN_ERR "CPUidle register device failed\n"); 223 dev_err(&pdev->dev, "failed to register cpuidle device\n");
223 return ret; 224 return ret;
224 } 225 }
225 } 226 }
226 227
227 return 0; 228 return 0;
228} 229}
229device_initcall(exynos4_init_cpuidle); 230
231static struct platform_driver exynos_cpuidle_driver = {
232 .probe = exynos_cpuidle_probe,
233 .driver = {
234 .name = "exynos_cpuidle",
235 .owner = THIS_MODULE,
236 },
237};
238
239module_platform_driver(exynos_cpuidle_driver);
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 4b8f6e2ca163..4603e6bd424b 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -21,6 +21,8 @@
21 21
22static void __init exynos4_dt_machine_init(void) 22static void __init exynos4_dt_machine_init(void)
23{ 23{
24 exynos_cpuidle_init();
25
24 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 26 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
25} 27}
26 28
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 7976ab333192..1fe075a70c1e 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -43,6 +43,8 @@ static void __init exynos5_dt_machine_init(void)
43 } 43 }
44 } 44 }
45 45
46 exynos_cpuidle_init();
47
46 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 48 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
47} 49}
48 50
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 0f9f24116daa..d0cfb225ec9a 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -22,7 +22,7 @@
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/of_irq.h> 23#include <linux/of_irq.h>
24#include <linux/of_platform.h> 24#include <linux/of_platform.h>
25#include <linux/opp.h> 25#include <linux/pm_opp.h>
26#include <linux/phy.h> 26#include <linux/phy.h>
27#include <linux/reboot.h> 27#include <linux/reboot.h>
28#include <linux/regmap.h> 28#include <linux/regmap.h>
@@ -176,7 +176,7 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
176 val = readl_relaxed(base + OCOTP_CFG3); 176 val = readl_relaxed(base + OCOTP_CFG3);
177 val >>= OCOTP_CFG3_SPEED_SHIFT; 177 val >>= OCOTP_CFG3_SPEED_SHIFT;
178 if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) 178 if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
179 if (opp_disable(cpu_dev, 1200000000)) 179 if (dev_pm_opp_disable(cpu_dev, 1200000000))
180 pr_warn("failed to disable 1.2 GHz OPP\n"); 180 pr_warn("failed to disable 1.2 GHz OPP\n");
181 181
182put_node: 182put_node:
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 8b9cd0690ce7..a516c1bda141 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -25,7 +25,7 @@
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/gpio_keys.h> 27#include <linux/gpio_keys.h>
28#include <linux/opp.h> 28#include <linux/pm_opp.h>
29#include <linux/cpu.h> 29#include <linux/cpu.h>
30 30
31#include <linux/mtd/mtd.h> 31#include <linux/mtd/mtd.h>
@@ -516,11 +516,11 @@ static int __init beagle_opp_init(void)
516 return -ENODEV; 516 return -ENODEV;
517 } 517 }
518 /* Enable MPU 1GHz and lower opps */ 518 /* Enable MPU 1GHz and lower opps */
519 r = opp_enable(mpu_dev, 800000000); 519 r = dev_pm_opp_enable(mpu_dev, 800000000);
520 /* TODO: MPU 1GHz needs SR and ABB */ 520 /* TODO: MPU 1GHz needs SR and ABB */
521 521
522 /* Enable IVA 800MHz and lower opps */ 522 /* Enable IVA 800MHz and lower opps */
523 r |= opp_enable(iva_dev, 660000000); 523 r |= dev_pm_opp_enable(iva_dev, 660000000);
524 /* TODO: DSP 800MHz needs SR and ABB */ 524 /* TODO: DSP 800MHz needs SR and ABB */
525 if (r) { 525 if (r) {
526 pr_err("%s: failed to enable higher opp %d\n", 526 pr_err("%s: failed to enable higher opp %d\n",
@@ -529,8 +529,8 @@ static int __init beagle_opp_init(void)
529 * Cleanup - disable the higher freqs - we dont care 529 * Cleanup - disable the higher freqs - we dont care
530 * about the results 530 * about the results
531 */ 531 */
532 opp_disable(mpu_dev, 800000000); 532 dev_pm_opp_disable(mpu_dev, 800000000);
533 opp_disable(iva_dev, 660000000); 533 dev_pm_opp_disable(iva_dev, 660000000);
534 } 534 }
535 } 535 }
536 return 0; 536 return 0;
diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h
index 67faa7b8fe92..1d777e63e05c 100644
--- a/arch/arm/mach-omap2/omap-pm.h
+++ b/arch/arm/mach-omap2/omap-pm.h
@@ -17,7 +17,7 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/opp.h> 20#include <linux/pm_opp.h>
21 21
22/* 22/*
23 * agent_id values for use with omap_pm_set_min_bus_tput(): 23 * agent_id values for use with omap_pm_set_min_bus_tput():
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
index 82fd8c72f750..a358a07e18f2 100644
--- a/arch/arm/mach-omap2/opp.c
+++ b/arch/arm/mach-omap2/opp.c
@@ -18,7 +18,7 @@
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/opp.h> 21#include <linux/pm_opp.h>
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23 23
24#include "omap_device.h" 24#include "omap_device.h"
@@ -85,14 +85,14 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
85 dev = &oh->od->pdev->dev; 85 dev = &oh->od->pdev->dev;
86 } 86 }
87 87
88 r = opp_add(dev, opp_def->freq, opp_def->u_volt); 88 r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt);
89 if (r) { 89 if (r) {
90 dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", 90 dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n",
91 __func__, opp_def->freq, 91 __func__, opp_def->freq,
92 opp_def->hwmod_name, i, r); 92 opp_def->hwmod_name, i, r);
93 } else { 93 } else {
94 if (!opp_def->default_available) 94 if (!opp_def->default_available)
95 r = opp_disable(dev, opp_def->freq); 95 r = dev_pm_opp_disable(dev, opp_def->freq);
96 if (r) 96 if (r)
97 dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", 97 dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n",
98 __func__, opp_def->freq, 98 __func__, opp_def->freq,
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 360b2daf54dd..e1b41416fbf1 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/opp.h> 16#include <linux/pm_opp.h>
17#include <linux/export.h> 17#include <linux/export.h>
18#include <linux/suspend.h> 18#include <linux/suspend.h>
19#include <linux/cpu.h> 19#include <linux/cpu.h>
@@ -131,7 +131,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
131{ 131{
132 struct voltagedomain *voltdm; 132 struct voltagedomain *voltdm;
133 struct clk *clk; 133 struct clk *clk;
134 struct opp *opp; 134 struct dev_pm_opp *opp;
135 unsigned long freq, bootup_volt; 135 unsigned long freq, bootup_volt;
136 struct device *dev; 136 struct device *dev;
137 137
@@ -172,7 +172,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
172 clk_put(clk); 172 clk_put(clk);
173 173
174 rcu_read_lock(); 174 rcu_read_lock();
175 opp = opp_find_freq_ceil(dev, &freq); 175 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
176 if (IS_ERR(opp)) { 176 if (IS_ERR(opp)) {
177 rcu_read_unlock(); 177 rcu_read_unlock();
178 pr_err("%s: unable to find boot up OPP for vdd_%s\n", 178 pr_err("%s: unable to find boot up OPP for vdd_%s\n",
@@ -180,7 +180,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
180 goto exit; 180 goto exit;
181 } 181 }
182 182
183 bootup_volt = opp_get_voltage(opp); 183 bootup_volt = dev_pm_opp_get_voltage(opp);
184 rcu_read_unlock(); 184 rcu_read_unlock();
185 if (!bootup_volt) { 185 if (!bootup_volt) {
186 pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n", 186 pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n",
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index a8427115ee07..96100dbf5a2e 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -615,14 +615,12 @@ endmenu
615config PXA25x 615config PXA25x
616 bool 616 bool
617 select CPU_XSCALE 617 select CPU_XSCALE
618 select CPU_FREQ_TABLE if CPU_FREQ
619 help 618 help
620 Select code specific to PXA21x/25x/26x variants 619 Select code specific to PXA21x/25x/26x variants
621 620
622config PXA27x 621config PXA27x
623 bool 622 bool
624 select CPU_XSCALE 623 select CPU_XSCALE
625 select CPU_FREQ_TABLE if CPU_FREQ
626 help 624 help
627 Select code specific to PXA27x variants 625 Select code specific to PXA27x variants
628 626
@@ -635,7 +633,6 @@ config CPU_PXA26x
635config PXA3xx 633config PXA3xx
636 bool 634 bool
637 select CPU_XSC3 635 select CPU_XSC3
638 select CPU_FREQ_TABLE if CPU_FREQ
639 help 636 help
640 Select code specific to PXA3xx variants 637 Select code specific to PXA3xx variants
641 638
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index f25b6119e028..d4ea142c4edd 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -42,74 +42,31 @@ EXPORT_SYMBOL(reset_status);
42/* 42/*
43 * This table is setup for a 3.6864MHz Crystal. 43 * This table is setup for a 3.6864MHz Crystal.
44 */ 44 */
45static const unsigned short cclk_frequency_100khz[NR_FREQS] = { 45struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
46 590, /* 59.0 MHz */ 46 { .frequency = 59000, /* 59.0 MHz */},
47 737, /* 73.7 MHz */ 47 { .frequency = 73700, /* 73.7 MHz */},
48 885, /* 88.5 MHz */ 48 { .frequency = 88500, /* 88.5 MHz */},
49 1032, /* 103.2 MHz */ 49 { .frequency = 103200, /* 103.2 MHz */},
50 1180, /* 118.0 MHz */ 50 { .frequency = 118000, /* 118.0 MHz */},
51 1327, /* 132.7 MHz */ 51 { .frequency = 132700, /* 132.7 MHz */},
52 1475, /* 147.5 MHz */ 52 { .frequency = 147500, /* 147.5 MHz */},
53 1622, /* 162.2 MHz */ 53 { .frequency = 162200, /* 162.2 MHz */},
54 1769, /* 176.9 MHz */ 54 { .frequency = 176900, /* 176.9 MHz */},
55 1917, /* 191.7 MHz */ 55 { .frequency = 191700, /* 191.7 MHz */},
56 2064, /* 206.4 MHz */ 56 { .frequency = 206400, /* 206.4 MHz */},
57 2212, /* 221.2 MHz */ 57 { .frequency = 221200, /* 221.2 MHz */},
58 2359, /* 235.9 MHz */ 58 { .frequency = 235900, /* 235.9 MHz */},
59 2507, /* 250.7 MHz */ 59 { .frequency = 250700, /* 250.7 MHz */},
60 2654, /* 265.4 MHz */ 60 { .frequency = 265400, /* 265.4 MHz */},
61 2802 /* 280.2 MHz */ 61 { .frequency = 280200, /* 280.2 MHz */},
62 { .frequency = CPUFREQ_TABLE_END, },
62}; 63};
63 64
64/* rounds up(!) */
65unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
66{
67 int i;
68
69 khz /= 100;
70
71 for (i = 0; i < NR_FREQS; i++)
72 if (cclk_frequency_100khz[i] >= khz)
73 break;
74
75 return i;
76}
77
78unsigned int sa11x0_ppcr_to_freq(unsigned int idx)
79{
80 unsigned int freq = 0;
81 if (idx < NR_FREQS)
82 freq = cclk_frequency_100khz[idx] * 100;
83 return freq;
84}
85
86
87/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
88 * this platform, anyway.
89 */
90int sa11x0_verify_speed(struct cpufreq_policy *policy)
91{
92 unsigned int tmp;
93 if (policy->cpu)
94 return -EINVAL;
95
96 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
97
98 /* make sure that at least one frequency is within the policy */
99 tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100;
100 if (tmp > policy->max)
101 policy->max = tmp;
102
103 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
104
105 return 0;
106}
107
108unsigned int sa11x0_getspeed(unsigned int cpu) 65unsigned int sa11x0_getspeed(unsigned int cpu)
109{ 66{
110 if (cpu) 67 if (cpu)
111 return 0; 68 return 0;
112 return cclk_frequency_100khz[PPCR & 0xf] * 100; 69 return sa11x0_freq_table[PPCR & 0xf].frequency;
113} 70}
114 71
115/* 72/*
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 9a33695c9492..0d92e119b36b 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -3,6 +3,7 @@
3 * 3 *
4 * Author: Nicolas Pitre 4 * Author: Nicolas Pitre
5 */ 5 */
6#include <linux/cpufreq.h>
6#include <linux/reboot.h> 7#include <linux/reboot.h>
7 8
8extern void sa1100_timer_init(void); 9extern void sa1100_timer_init(void);
@@ -19,12 +20,8 @@ extern void sa11x0_init_late(void);
19extern void sa1110_mb_enable(void); 20extern void sa1110_mb_enable(void);
20extern void sa1110_mb_disable(void); 21extern void sa1110_mb_disable(void);
21 22
22struct cpufreq_policy; 23extern struct cpufreq_frequency_table sa11x0_freq_table[];
23
24extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
25extern int sa11x0_verify_speed(struct cpufreq_policy *policy);
26extern unsigned int sa11x0_getspeed(unsigned int cpu); 24extern unsigned int sa11x0_getspeed(unsigned int cpu);
27extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
28 25
29struct flash_platform_data; 26struct flash_platform_data;
30struct resource; 27struct resource;
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index c67f8ad5ccd5..0034d2cd6973 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -29,7 +29,6 @@ if ARCH_U8500
29 29
30config UX500_SOC_DB8500 30config UX500_SOC_DB8500
31 bool 31 bool
32 select CPU_FREQ_TABLE if CPU_FREQ
33 select MFD_DB8500_PRCMU 32 select MFD_DB8500_PRCMU
34 select PINCTRL_DB8500 33 select PINCTRL_DB8500
35 select PINCTRL_DB8540 34 select PINCTRL_DB8540
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index cbbb81e0e509..4a70be485ff8 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -65,10 +65,22 @@ config ARCH_VEXPRESS_DCSCB
65 This is needed to provide CPU and cluster power management 65 This is needed to provide CPU and cluster power management
66 on RTSM implementing big.LITTLE. 66 on RTSM implementing big.LITTLE.
67 67
68config ARCH_VEXPRESS_SPC
69 bool "Versatile Express Serial Power Controller (SPC)"
70 select ARCH_HAS_CPUFREQ
71 select ARCH_HAS_OPP
72 select PM_OPP
73 help
74 The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
75 block called Serial Power Controller (SPC) that provides the interface
76 between the dual cluster test-chip and the M3 microcontroller that
77 carries out power management.
78
68config ARCH_VEXPRESS_TC2_PM 79config ARCH_VEXPRESS_TC2_PM
69 bool "Versatile Express TC2 power management" 80 bool "Versatile Express TC2 power management"
70 depends on MCPM 81 depends on MCPM
71 select ARM_CCI 82 select ARM_CCI
83 select ARCH_VEXPRESS_SPC
72 help 84 help
73 Support for CPU and cluster power management on Versatile Express 85 Support for CPU and cluster power management on Versatile Express
74 with a TC2 (A15x2 A7x3) big.LITTLE core tile. 86 with a TC2 (A15x2 A7x3) big.LITTLE core tile.
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 505e64ab3eae..0997e0b7494c 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -8,7 +8,8 @@ obj-y := v2m.o
8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
9obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o 9obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
10CFLAGS_dcscb.o += -march=armv7-a 10CFLAGS_dcscb.o += -march=armv7-a
11obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o spc.o 11obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
12obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
12CFLAGS_tc2_pm.o += -march=armv7-a 13CFLAGS_tc2_pm.o += -march=armv7-a
13obj-$(CONFIG_SMP) += platsmp.o 14obj-$(CONFIG_SMP) += platsmp.o
14obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 15obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
index eefb029197ca..033d34dcbd3f 100644
--- a/arch/arm/mach-vexpress/spc.c
+++ b/arch/arm/mach-vexpress/spc.c
@@ -17,14 +17,31 @@
17 * GNU General Public License for more details. 17 * GNU General Public License for more details.
18 */ 18 */
19 19
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22#include <linux/cpu.h>
23#include <linux/delay.h>
20#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/interrupt.h>
21#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/platform_device.h>
28#include <linux/pm_opp.h>
22#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/semaphore.h>
23 31
24#include <asm/cacheflush.h> 32#include <asm/cacheflush.h>
25 33
26#define SPCLOG "vexpress-spc: " 34#define SPCLOG "vexpress-spc: "
27 35
36#define PERF_LVL_A15 0x00
37#define PERF_REQ_A15 0x04
38#define PERF_LVL_A7 0x08
39#define PERF_REQ_A7 0x0c
40#define COMMS 0x10
41#define COMMS_REQ 0x14
42#define PWC_STATUS 0x18
43#define PWC_FLAG 0x1c
44
28/* SPC wake-up IRQs status and mask */ 45/* SPC wake-up IRQs status and mask */
29#define WAKE_INT_MASK 0x24 46#define WAKE_INT_MASK 0x24
30#define WAKE_INT_RAW 0x28 47#define WAKE_INT_RAW 0x28
@@ -36,12 +53,45 @@
36#define A15_BX_ADDR0 0x68 53#define A15_BX_ADDR0 0x68
37#define A7_BX_ADDR0 0x78 54#define A7_BX_ADDR0 0x78
38 55
56/* SPC system config interface registers */
57#define SYSCFG_WDATA 0x70
58#define SYSCFG_RDATA 0x74
59
60/* A15/A7 OPP virtual register base */
61#define A15_PERFVAL_BASE 0xC10
62#define A7_PERFVAL_BASE 0xC30
63
64/* Config interface control bits */
65#define SYSCFG_START (1 << 31)
66#define SYSCFG_SCC (6 << 20)
67#define SYSCFG_STAT (14 << 20)
68
39/* wake-up interrupt masks */ 69/* wake-up interrupt masks */
40#define GBL_WAKEUP_INT_MSK (0x3 << 10) 70#define GBL_WAKEUP_INT_MSK (0x3 << 10)
41 71
42/* TC2 static dual-cluster configuration */ 72/* TC2 static dual-cluster configuration */
43#define MAX_CLUSTERS 2 73#define MAX_CLUSTERS 2
44 74
75/*
76 * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS
77 * operation, the operation could start just before jiffie is about
78 * to be incremented. So setting timeout value of 20ms = 2jiffies@100Hz
79 */
80#define TIMEOUT_US 20000
81
82#define MAX_OPPS 8
83#define CA15_DVFS 0
84#define CA7_DVFS 1
85#define SPC_SYS_CFG 2
86#define STAT_COMPLETE(type) ((1 << 0) << (type << 2))
87#define STAT_ERR(type) ((1 << 1) << (type << 2))
88#define RESPONSE_MASK(type) (STAT_COMPLETE(type) | STAT_ERR(type))
89
90struct ve_spc_opp {
91 unsigned long freq;
92 unsigned long u_volt;
93};
94
45struct ve_spc_drvdata { 95struct ve_spc_drvdata {
46 void __iomem *baseaddr; 96 void __iomem *baseaddr;
47 /* 97 /*
@@ -49,6 +99,12 @@ struct ve_spc_drvdata {
49 * It corresponds to A15 processors MPIDR[15:8] bitfield 99 * It corresponds to A15 processors MPIDR[15:8] bitfield
50 */ 100 */
51 u32 a15_clusid; 101 u32 a15_clusid;
102 uint32_t cur_rsp_mask;
103 uint32_t cur_rsp_stat;
104 struct semaphore sem;
105 struct completion done;
106 struct ve_spc_opp *opps[MAX_CLUSTERS];
107 int num_opps[MAX_CLUSTERS];
52}; 108};
53 109
54static struct ve_spc_drvdata *info; 110static struct ve_spc_drvdata *info;
@@ -157,8 +213,197 @@ void ve_spc_powerdown(u32 cluster, bool enable)
157 writel_relaxed(enable, info->baseaddr + pwdrn_reg); 213 writel_relaxed(enable, info->baseaddr + pwdrn_reg);
158} 214}
159 215
160int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid) 216static int ve_spc_get_performance(int cluster, u32 *freq)
217{
218 struct ve_spc_opp *opps = info->opps[cluster];
219 u32 perf_cfg_reg = 0;
220 u32 perf;
221
222 perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7;
223
224 perf = readl_relaxed(info->baseaddr + perf_cfg_reg);
225 if (perf >= info->num_opps[cluster])
226 return -EINVAL;
227
228 opps += perf;
229 *freq = opps->freq;
230
231 return 0;
232}
233
234/* find closest match to given frequency in OPP table */
235static int ve_spc_round_performance(int cluster, u32 freq)
236{
237 int idx, max_opp = info->num_opps[cluster];
238 struct ve_spc_opp *opps = info->opps[cluster];
239 u32 fmin = 0, fmax = ~0, ftmp;
240
241 freq /= 1000; /* OPP entries in kHz */
242 for (idx = 0; idx < max_opp; idx++, opps++) {
243 ftmp = opps->freq;
244 if (ftmp >= freq) {
245 if (ftmp <= fmax)
246 fmax = ftmp;
247 } else {
248 if (ftmp >= fmin)
249 fmin = ftmp;
250 }
251 }
252 if (fmax != ~0)
253 return fmax * 1000;
254 else
255 return fmin * 1000;
256}
257
258static int ve_spc_find_performance_index(int cluster, u32 freq)
259{
260 int idx, max_opp = info->num_opps[cluster];
261 struct ve_spc_opp *opps = info->opps[cluster];
262
263 for (idx = 0; idx < max_opp; idx++, opps++)
264 if (opps->freq == freq)
265 break;
266 return (idx == max_opp) ? -EINVAL : idx;
267}
268
269static int ve_spc_waitforcompletion(int req_type)
270{
271 int ret = wait_for_completion_interruptible_timeout(
272 &info->done, usecs_to_jiffies(TIMEOUT_US));
273 if (ret == 0)
274 ret = -ETIMEDOUT;
275 else if (ret > 0)
276 ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO;
277 return ret;
278}
279
280static int ve_spc_set_performance(int cluster, u32 freq)
281{
282 u32 perf_cfg_reg, perf_stat_reg;
283 int ret, perf, req_type;
284
285 if (cluster_is_a15(cluster)) {
286 req_type = CA15_DVFS;
287 perf_cfg_reg = PERF_LVL_A15;
288 perf_stat_reg = PERF_REQ_A15;
289 } else {
290 req_type = CA7_DVFS;
291 perf_cfg_reg = PERF_LVL_A7;
292 perf_stat_reg = PERF_REQ_A7;
293 }
294
295 perf = ve_spc_find_performance_index(cluster, freq);
296
297 if (perf < 0)
298 return perf;
299
300 if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
301 return -ETIME;
302
303 init_completion(&info->done);
304 info->cur_rsp_mask = RESPONSE_MASK(req_type);
305
306 writel(perf, info->baseaddr + perf_cfg_reg);
307 ret = ve_spc_waitforcompletion(req_type);
308
309 info->cur_rsp_mask = 0;
310 up(&info->sem);
311
312 return ret;
313}
314
315static int ve_spc_read_sys_cfg(int func, int offset, uint32_t *data)
316{
317 int ret;
318
319 if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
320 return -ETIME;
321
322 init_completion(&info->done);
323 info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG);
324
325 /* Set the control value */
326 writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS);
327 ret = ve_spc_waitforcompletion(SPC_SYS_CFG);
328
329 if (ret == 0)
330 *data = readl(info->baseaddr + SYSCFG_RDATA);
331
332 info->cur_rsp_mask = 0;
333 up(&info->sem);
334
335 return ret;
336}
337
338static irqreturn_t ve_spc_irq_handler(int irq, void *data)
339{
340 struct ve_spc_drvdata *drv_data = data;
341 uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS);
342
343 if (info->cur_rsp_mask & status) {
344 info->cur_rsp_stat = status;
345 complete(&drv_data->done);
346 }
347
348 return IRQ_HANDLED;
349}
350
351/*
352 * +--------------------------+
353 * | 31 20 | 19 0 |
354 * +--------------------------+
355 * | u_volt | freq(kHz) |
356 * +--------------------------+
357 */
358#define MULT_FACTOR 20
359#define VOLT_SHIFT 20
360#define FREQ_MASK (0xFFFFF)
361static int ve_spc_populate_opps(uint32_t cluster)
161{ 362{
363 uint32_t data = 0, off, ret, idx;
364 struct ve_spc_opp *opps;
365
366 opps = kzalloc(sizeof(*opps) * MAX_OPPS, GFP_KERNEL);
367 if (!opps)
368 return -ENOMEM;
369
370 info->opps[cluster] = opps;
371
372 off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE;
373 for (idx = 0; idx < MAX_OPPS; idx++, off += 4, opps++) {
374 ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
375 if (!ret) {
376 opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
377 opps->u_volt = data >> VOLT_SHIFT;
378 } else {
379 break;
380 }
381 }
382 info->num_opps[cluster] = idx;
383
384 return ret;
385}
386
387static int ve_init_opp_table(struct device *cpu_dev)
388{
389 int cluster = topology_physical_package_id(cpu_dev->id);
390 int idx, ret = 0, max_opp = info->num_opps[cluster];
391 struct ve_spc_opp *opps = info->opps[cluster];
392
393 for (idx = 0; idx < max_opp; idx++, opps++) {
394 ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt);
395 if (ret) {
396 dev_warn(cpu_dev, "failed to add opp %lu %lu\n",
397 opps->freq, opps->u_volt);
398 return ret;
399 }
400 }
401 return ret;
402}
403
404int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq)
405{
406 int ret;
162 info = kzalloc(sizeof(*info), GFP_KERNEL); 407 info = kzalloc(sizeof(*info), GFP_KERNEL);
163 if (!info) { 408 if (!info) {
164 pr_err(SPCLOG "unable to allocate mem\n"); 409 pr_err(SPCLOG "unable to allocate mem\n");
@@ -168,6 +413,25 @@ int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid)
168 info->baseaddr = baseaddr; 413 info->baseaddr = baseaddr;
169 info->a15_clusid = a15_clusid; 414 info->a15_clusid = a15_clusid;
170 415
416 if (irq <= 0) {
417 pr_err(SPCLOG "Invalid IRQ %d\n", irq);
418 kfree(info);
419 return -EINVAL;
420 }
421
422 init_completion(&info->done);
423
424 readl_relaxed(info->baseaddr + PWC_STATUS);
425
426 ret = request_irq(irq, ve_spc_irq_handler, IRQF_TRIGGER_HIGH
427 | IRQF_ONESHOT, "vexpress-spc", info);
428 if (ret) {
429 pr_err(SPCLOG "IRQ %d request failed\n", irq);
430 kfree(info);
431 return -ENODEV;
432 }
433
434 sema_init(&info->sem, 1);
171 /* 435 /*
172 * Multi-cluster systems may need this data when non-coherent, during 436 * Multi-cluster systems may need this data when non-coherent, during
173 * cluster power-up/power-down. Make sure driver info reaches main 437 * cluster power-up/power-down. Make sure driver info reaches main
@@ -178,3 +442,103 @@ int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid)
178 442
179 return 0; 443 return 0;
180} 444}
445
446struct clk_spc {
447 struct clk_hw hw;
448 int cluster;
449};
450
451#define to_clk_spc(spc) container_of(spc, struct clk_spc, hw)
452static unsigned long spc_recalc_rate(struct clk_hw *hw,
453 unsigned long parent_rate)
454{
455 struct clk_spc *spc = to_clk_spc(hw);
456 u32 freq;
457
458 if (ve_spc_get_performance(spc->cluster, &freq))
459 return -EIO;
460
461 return freq * 1000;
462}
463
464static long spc_round_rate(struct clk_hw *hw, unsigned long drate,
465 unsigned long *parent_rate)
466{
467 struct clk_spc *spc = to_clk_spc(hw);
468
469 return ve_spc_round_performance(spc->cluster, drate);
470}
471
472static int spc_set_rate(struct clk_hw *hw, unsigned long rate,
473 unsigned long parent_rate)
474{
475 struct clk_spc *spc = to_clk_spc(hw);
476
477 return ve_spc_set_performance(spc->cluster, rate / 1000);
478}
479
480static struct clk_ops clk_spc_ops = {
481 .recalc_rate = spc_recalc_rate,
482 .round_rate = spc_round_rate,
483 .set_rate = spc_set_rate,
484};
485
486static struct clk *ve_spc_clk_register(struct device *cpu_dev)
487{
488 struct clk_init_data init;
489 struct clk_spc *spc;
490
491 spc = kzalloc(sizeof(*spc), GFP_KERNEL);
492 if (!spc) {
493 pr_err("could not allocate spc clk\n");
494 return ERR_PTR(-ENOMEM);
495 }
496
497 spc->hw.init = &init;
498 spc->cluster = topology_physical_package_id(cpu_dev->id);
499
500 init.name = dev_name(cpu_dev);
501 init.ops = &clk_spc_ops;
502 init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
503 init.num_parents = 0;
504
505 return devm_clk_register(cpu_dev, &spc->hw);
506}
507
508static int __init ve_spc_clk_init(void)
509{
510 int cpu;
511 struct clk *clk;
512
513 if (!info)
514 return 0; /* Continue only if SPC is initialised */
515
516 if (ve_spc_populate_opps(0) || ve_spc_populate_opps(1)) {
517 pr_err("failed to build OPP table\n");
518 return -ENODEV;
519 }
520
521 for_each_possible_cpu(cpu) {
522 struct device *cpu_dev = get_cpu_device(cpu);
523 if (!cpu_dev) {
524 pr_warn("failed to get cpu%d device\n", cpu);
525 continue;
526 }
527 clk = ve_spc_clk_register(cpu_dev);
528 if (IS_ERR(clk)) {
529 pr_warn("failed to register cpu%d clock\n", cpu);
530 continue;
531 }
532 if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
533 pr_warn("failed to register cpu%d clock lookup\n", cpu);
534 continue;
535 }
536
537 if (ve_init_opp_table(cpu_dev))
538 pr_warn("failed to initialise cpu%d opp table\n", cpu);
539 }
540
541 platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
542 return 0;
543}
544module_init(ve_spc_clk_init);
diff --git a/arch/arm/mach-vexpress/spc.h b/arch/arm/mach-vexpress/spc.h
index 5f7e4a446a17..dbd44c3720f9 100644
--- a/arch/arm/mach-vexpress/spc.h
+++ b/arch/arm/mach-vexpress/spc.h
@@ -15,7 +15,7 @@
15#ifndef __SPC_H_ 15#ifndef __SPC_H_
16#define __SPC_H_ 16#define __SPC_H_
17 17
18int __init ve_spc_init(void __iomem *base, u32 a15_clusid); 18int __init ve_spc_init(void __iomem *base, u32 a15_clusid, int irq);
19void ve_spc_global_wakeup_irq(bool set); 19void ve_spc_global_wakeup_irq(bool set);
20void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set); 20void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
21void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr); 21void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c
index 4eb92ebfd953..05a364c5077a 100644
--- a/arch/arm/mach-vexpress/tc2_pm.c
+++ b/arch/arm/mach-vexpress/tc2_pm.c
@@ -16,6 +16,7 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/of_irq.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <linux/errno.h> 21#include <linux/errno.h>
21#include <linux/irqchip/arm-gic.h> 22#include <linux/irqchip/arm-gic.h>
@@ -267,7 +268,7 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
267 268
268static int __init tc2_pm_init(void) 269static int __init tc2_pm_init(void)
269{ 270{
270 int ret; 271 int ret, irq;
271 void __iomem *scc; 272 void __iomem *scc;
272 u32 a15_cluster_id, a7_cluster_id, sys_info; 273 u32 a15_cluster_id, a7_cluster_id, sys_info;
273 struct device_node *np; 274 struct device_node *np;
@@ -292,13 +293,15 @@ static int __init tc2_pm_init(void)
292 tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf; 293 tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf;
293 tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf; 294 tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf;
294 295
296 irq = irq_of_parse_and_map(np, 0);
297
295 /* 298 /*
296 * A subset of the SCC registers is also used to communicate 299 * A subset of the SCC registers is also used to communicate
297 * with the SPC (power controller). We need to be able to 300 * with the SPC (power controller). We need to be able to
298 * drive it very early in the boot process to power up 301 * drive it very early in the boot process to power up
299 * processors, so we initialize the SPC driver here. 302 * processors, so we initialize the SPC driver here.
300 */ 303 */
301 ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id); 304 ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq);
302 if (ret) 305 if (ret)
303 return ret; 306 return ret;
304 307
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 5f252569c689..9a7bd137c8fd 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -44,6 +44,10 @@ static struct of_device_id zynq_of_bus_ids[] __initdata = {
44 {} 44 {}
45}; 45};
46 46
47static struct platform_device zynq_cpuidle_device = {
48 .name = "cpuidle-zynq",
49};
50
47/** 51/**
48 * zynq_init_machine - System specific initialization, intended to be 52 * zynq_init_machine - System specific initialization, intended to be
49 * called from board specific initialization. 53 * called from board specific initialization.
@@ -56,6 +60,8 @@ static void __init zynq_init_machine(void)
56 l2x0_of_init(0x02060000, 0xF0F0FFFF); 60 l2x0_of_init(0x02060000, 0xF0F0FFFF);
57 61
58 of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL); 62 of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL);
63
64 platform_device_register(&zynq_cpuidle_device);
59} 65}
60 66
61static void __init zynq_timer_init(void) 67static void __init zynq_timer_init(void)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 74314bd8be39..e887b57c3176 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -1440,7 +1440,6 @@ source "drivers/cpufreq/Kconfig"
1440config BFIN_CPU_FREQ 1440config BFIN_CPU_FREQ
1441 bool 1441 bool
1442 depends on CPU_FREQ 1442 depends on CPU_FREQ
1443 select CPU_FREQ_TABLE
1444 default y 1443 default y
1445 1444
1446config CPU_VOLTAGE 1445config CPU_VOLTAGE
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 02380bed189c..9c957c81c688 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -130,13 +130,11 @@ config SVINTO_SIM
130 130
131config ETRAXFS 131config ETRAXFS
132 bool "ETRAX-FS-V32" 132 bool "ETRAX-FS-V32"
133 select CPU_FREQ_TABLE if CPU_FREQ
134 help 133 help
135 Support CRIS V32. 134 Support CRIS V32.
136 135
137config CRIS_MACH_ARTPEC3 136config CRIS_MACH_ARTPEC3
138 bool "ARTPEC-3" 137 bool "ARTPEC-3"
139 select CPU_FREQ_TABLE if CPU_FREQ
140 help 138 help
141 Support Axis ARTPEC-3. 139 Support Axis ARTPEC-3.
142 140
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 5eb71d22c3d5..59d52e3aef12 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -882,40 +882,10 @@ __init void prefill_possible_map(void)
882 set_cpu_possible(i, true); 882 set_cpu_possible(i, true);
883} 883}
884 884
885static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) 885static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
886{ 886{
887 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
888 union acpi_object *obj;
889 struct acpi_madt_local_sapic *lsapic;
890 cpumask_t tmp_map; 887 cpumask_t tmp_map;
891 int cpu, physid; 888 int cpu;
892
893 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
894 return -EINVAL;
895
896 if (!buffer.length || !buffer.pointer)
897 return -EINVAL;
898
899 obj = buffer.pointer;
900 if (obj->type != ACPI_TYPE_BUFFER)
901 {
902 kfree(buffer.pointer);
903 return -EINVAL;
904 }
905
906 lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer;
907
908 if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) ||
909 (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))) {
910 kfree(buffer.pointer);
911 return -EINVAL;
912 }
913
914 physid = ((lsapic->id << 8) | (lsapic->eid));
915
916 kfree(buffer.pointer);
917 buffer.length = ACPI_ALLOCATE_BUFFER;
918 buffer.pointer = NULL;
919 889
920 cpumask_complement(&tmp_map, cpu_present_mask); 890 cpumask_complement(&tmp_map, cpu_present_mask);
921 cpu = cpumask_first(&tmp_map); 891 cpu = cpumask_first(&tmp_map);
@@ -934,9 +904,9 @@ static int _acpi_map_lsapic(acpi_handle handle, int *pcpu)
934} 904}
935 905
936/* wrapper to silence section mismatch warning */ 906/* wrapper to silence section mismatch warning */
937int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) 907int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
938{ 908{
939 return _acpi_map_lsapic(handle, pcpu); 909 return _acpi_map_lsapic(handle, physid, pcpu);
940} 910}
941EXPORT_SYMBOL(acpi_map_lsapic); 911EXPORT_SYMBOL(acpi_map_lsapic);
942 912
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 8e59abc237d7..930cd8af3503 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -844,18 +844,6 @@ void __cpu_die(unsigned int cpu)
844 smp_ops->cpu_die(cpu); 844 smp_ops->cpu_die(cpu);
845} 845}
846 846
847static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex);
848
849void cpu_hotplug_driver_lock()
850{
851 mutex_lock(&powerpc_cpu_hotplug_driver_mutex);
852}
853
854void cpu_hotplug_driver_unlock()
855{
856 mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
857}
858
859void cpu_die(void) 847void cpu_die(void)
860{ 848{
861 if (ppc_md.cpu_die) 849 if (ppc_md.cpu_die)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 7cfdaae1721a..a8fe5aa3d34f 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -404,46 +404,38 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
404 unsigned long drc_index; 404 unsigned long drc_index;
405 int rc; 405 int rc;
406 406
407 cpu_hotplug_driver_lock();
408 rc = strict_strtoul(buf, 0, &drc_index); 407 rc = strict_strtoul(buf, 0, &drc_index);
409 if (rc) { 408 if (rc)
410 rc = -EINVAL; 409 return -EINVAL;
411 goto out;
412 }
413 410
414 parent = of_find_node_by_path("/cpus"); 411 parent = of_find_node_by_path("/cpus");
415 if (!parent) { 412 if (!parent)
416 rc = -ENODEV; 413 return -ENODEV;
417 goto out;
418 }
419 414
420 dn = dlpar_configure_connector(drc_index, parent); 415 dn = dlpar_configure_connector(drc_index, parent);
421 if (!dn) { 416 if (!dn)
422 rc = -EINVAL; 417 return -EINVAL;
423 goto out;
424 }
425 418
426 of_node_put(parent); 419 of_node_put(parent);
427 420
428 rc = dlpar_acquire_drc(drc_index); 421 rc = dlpar_acquire_drc(drc_index);
429 if (rc) { 422 if (rc) {
430 dlpar_free_cc_nodes(dn); 423 dlpar_free_cc_nodes(dn);
431 rc = -EINVAL; 424 return -EINVAL;
432 goto out;
433 } 425 }
434 426
435 rc = dlpar_attach_node(dn); 427 rc = dlpar_attach_node(dn);
436 if (rc) { 428 if (rc) {
437 dlpar_release_drc(drc_index); 429 dlpar_release_drc(drc_index);
438 dlpar_free_cc_nodes(dn); 430 dlpar_free_cc_nodes(dn);
439 goto out; 431 return rc;
440 } 432 }
441 433
442 rc = dlpar_online_cpu(dn); 434 rc = dlpar_online_cpu(dn);
443out: 435 if (rc)
444 cpu_hotplug_driver_unlock(); 436 return rc;
445 437
446 return rc ? rc : count; 438 return count;
447} 439}
448 440
449static int dlpar_offline_cpu(struct device_node *dn) 441static int dlpar_offline_cpu(struct device_node *dn)
@@ -516,30 +508,27 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
516 return -EINVAL; 508 return -EINVAL;
517 } 509 }
518 510
519 cpu_hotplug_driver_lock();
520 rc = dlpar_offline_cpu(dn); 511 rc = dlpar_offline_cpu(dn);
521 if (rc) { 512 if (rc) {
522 of_node_put(dn); 513 of_node_put(dn);
523 rc = -EINVAL; 514 return -EINVAL;
524 goto out;
525 } 515 }
526 516
527 rc = dlpar_release_drc(*drc_index); 517 rc = dlpar_release_drc(*drc_index);
528 if (rc) { 518 if (rc) {
529 of_node_put(dn); 519 of_node_put(dn);
530 goto out; 520 return rc;
531 } 521 }
532 522
533 rc = dlpar_detach_node(dn); 523 rc = dlpar_detach_node(dn);
534 if (rc) { 524 if (rc) {
535 dlpar_acquire_drc(*drc_index); 525 dlpar_acquire_drc(*drc_index);
536 goto out; 526 return rc;
537 } 527 }
538 528
539 of_node_put(dn); 529 of_node_put(dn);
540out: 530
541 cpu_hotplug_driver_unlock(); 531 return count;
542 return rc ? rc : count;
543} 532}
544 533
545static int __init pseries_dlpar_init(void) 534static int __init pseries_dlpar_init(void)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 725e1573ea85..14dc9c797abb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -255,10 +255,6 @@ config ARCH_HWEIGHT_CFLAGS
255 default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 255 default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
256 default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 256 default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
257 257
258config ARCH_CPU_PROBE_RELEASE
259 def_bool y
260 depends on HOTPLUG_CPU
261
262config ARCH_SUPPORTS_UPROBES 258config ARCH_SUPPORTS_UPROBES
263 def_bool y 259 def_bool y
264 260
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index b1977bad5435..c8c1e700c26e 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -26,6 +26,7 @@
26#include <acpi/pdc_intel.h> 26#include <acpi/pdc_intel.h>
27 27
28#include <asm/numa.h> 28#include <asm/numa.h>
29#include <asm/fixmap.h>
29#include <asm/processor.h> 30#include <asm/processor.h>
30#include <asm/mmu.h> 31#include <asm/mmu.h>
31#include <asm/mpspec.h> 32#include <asm/mpspec.h>
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 626cf70082d7..3142a94c7b4b 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -94,7 +94,7 @@ static inline void early_reserve_e820_mpc_new(void) { }
94#define default_get_smp_config x86_init_uint_noop 94#define default_get_smp_config x86_init_uint_noop
95#endif 95#endif
96 96
97void generic_processor_info(int apicid, int version); 97int generic_processor_info(int apicid, int version);
98#ifdef CONFIG_ACPI 98#ifdef CONFIG_ACPI
99extern void mp_register_ioapic(int id, u32 address, u32 gsi_base); 99extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
100extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, 100extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index cb7502852acb..e139b13f2a33 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -218,10 +218,14 @@ void msrs_free(struct msr *msrs);
218#ifdef CONFIG_SMP 218#ifdef CONFIG_SMP
219int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); 219int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
220int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); 220int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
221int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
222int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
221void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); 223void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
222void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); 224void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
223int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); 225int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
224int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); 226int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
227int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
228int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
225int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); 229int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
226int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); 230int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
227#else /* CONFIG_SMP */ 231#else /* CONFIG_SMP */
@@ -235,6 +239,16 @@ static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
235 wrmsr(msr_no, l, h); 239 wrmsr(msr_no, l, h);
236 return 0; 240 return 0;
237} 241}
242static inline int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
243{
244 rdmsrl(msr_no, *q);
245 return 0;
246}
247static inline int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
248{
249 wrmsrl(msr_no, q);
250 return 0;
251}
238static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no, 252static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
239 struct msr *msrs) 253 struct msr *msrs)
240{ 254{
@@ -254,6 +268,14 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
254{ 268{
255 return wrmsr_safe(msr_no, l, h); 269 return wrmsr_safe(msr_no, l, h);
256} 270}
271static inline int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
272{
273 return rdmsrl_safe(msr_no, q);
274}
275static inline int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
276{
277 return wrmsrl_safe(msr_no, q);
278}
257static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) 279static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
258{ 280{
259 return rdmsr_safe_regs(regs); 281 return rdmsr_safe_regs(regs);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 40c76604199f..6c0b43bd024b 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -189,24 +189,31 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
189 return 0; 189 return 0;
190} 190}
191 191
192static void acpi_register_lapic(int id, u8 enabled) 192/**
193 * acpi_register_lapic - register a local apic and generates a logic cpu number
194 * @id: local apic id to register
195 * @enabled: this cpu is enabled or not
196 *
197 * Returns the logic cpu number which maps to the local apic
198 */
199static int acpi_register_lapic(int id, u8 enabled)
193{ 200{
194 unsigned int ver = 0; 201 unsigned int ver = 0;
195 202
196 if (id >= MAX_LOCAL_APIC) { 203 if (id >= MAX_LOCAL_APIC) {
197 printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); 204 printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
198 return; 205 return -EINVAL;
199 } 206 }
200 207
201 if (!enabled) { 208 if (!enabled) {
202 ++disabled_cpus; 209 ++disabled_cpus;
203 return; 210 return -EINVAL;
204 } 211 }
205 212
206 if (boot_cpu_physical_apicid != -1U) 213 if (boot_cpu_physical_apicid != -1U)
207 ver = apic_version[boot_cpu_physical_apicid]; 214 ver = apic_version[boot_cpu_physical_apicid];
208 215
209 generic_processor_info(id, ver); 216 return generic_processor_info(id, ver);
210} 217}
211 218
212static int __init 219static int __init
@@ -614,84 +621,27 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
614#endif 621#endif
615} 622}
616 623
617static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) 624static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
618{ 625{
619 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
620 union acpi_object *obj;
621 struct acpi_madt_local_apic *lapic;
622 cpumask_var_t tmp_map, new_map;
623 u8 physid;
624 int cpu; 626 int cpu;
625 int retval = -ENOMEM;
626
627 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
628 return -EINVAL;
629
630 if (!buffer.length || !buffer.pointer)
631 return -EINVAL;
632
633 obj = buffer.pointer;
634 if (obj->type != ACPI_TYPE_BUFFER ||
635 obj->buffer.length < sizeof(*lapic)) {
636 kfree(buffer.pointer);
637 return -EINVAL;
638 }
639 627
640 lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; 628 cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED);
641 629 if (cpu < 0) {
642 if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || 630 pr_info(PREFIX "Unable to map lapic to logical cpu number\n");
643 !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { 631 return cpu;
644 kfree(buffer.pointer);
645 return -EINVAL;
646 }
647
648 physid = lapic->id;
649
650 kfree(buffer.pointer);
651 buffer.length = ACPI_ALLOCATE_BUFFER;
652 buffer.pointer = NULL;
653 lapic = NULL;
654
655 if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL))
656 goto out;
657
658 if (!alloc_cpumask_var(&new_map, GFP_KERNEL))
659 goto free_tmp_map;
660
661 cpumask_copy(tmp_map, cpu_present_mask);
662 acpi_register_lapic(physid, ACPI_MADT_ENABLED);
663
664 /*
665 * If acpi_register_lapic successfully generates a new logical cpu
666 * number, then the following will get us exactly what was mapped
667 */
668 cpumask_andnot(new_map, cpu_present_mask, tmp_map);
669 if (cpumask_empty(new_map)) {
670 printk ("Unable to map lapic to logical cpu number\n");
671 retval = -EINVAL;
672 goto free_new_map;
673 } 632 }
674 633
675 acpi_processor_set_pdc(handle); 634 acpi_processor_set_pdc(handle);
676
677 cpu = cpumask_first(new_map);
678 acpi_map_cpu2node(handle, cpu, physid); 635 acpi_map_cpu2node(handle, cpu, physid);
679 636
680 *pcpu = cpu; 637 *pcpu = cpu;
681 retval = 0; 638 return 0;
682
683free_new_map:
684 free_cpumask_var(new_map);
685free_tmp_map:
686 free_cpumask_var(tmp_map);
687out:
688 return retval;
689} 639}
690 640
691/* wrapper to silence section mismatch warning */ 641/* wrapper to silence section mismatch warning */
692int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) 642int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
693{ 643{
694 return _acpi_map_lsapic(handle, pcpu); 644 return _acpi_map_lsapic(handle, physid, pcpu);
695} 645}
696EXPORT_SYMBOL(acpi_map_lsapic); 646EXPORT_SYMBOL(acpi_map_lsapic);
697 647
@@ -745,7 +695,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table)
745#ifdef CONFIG_HPET_TIMER 695#ifdef CONFIG_HPET_TIMER
746#include <asm/hpet.h> 696#include <asm/hpet.h>
747 697
748static struct __initdata resource *hpet_res; 698static struct resource *hpet_res __initdata;
749 699
750static int __init acpi_parse_hpet(struct acpi_table_header *table) 700static int __init acpi_parse_hpet(struct acpi_table_header *table)
751{ 701{
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 33120100ff5e..3a2ae4c88948 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -26,6 +26,17 @@ static char temp_stack[4096];
26#endif 26#endif
27 27
28/** 28/**
29 * x86_acpi_enter_sleep_state - enter sleep state
30 * @state: Sleep state to enter.
31 *
32 * Wrapper around acpi_enter_sleep_state() to be called by assmebly.
33 */
34acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state)
35{
36 return acpi_enter_sleep_state(state);
37}
38
39/**
29 * x86_acpi_suspend_lowlevel - save kernel state 40 * x86_acpi_suspend_lowlevel - save kernel state
30 * 41 *
31 * Create an identity mapped page table and copy the wakeup routine to 42 * Create an identity mapped page table and copy the wakeup routine to
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h
index c9c2c982d5e4..65c7b606b606 100644
--- a/arch/x86/kernel/acpi/sleep.h
+++ b/arch/x86/kernel/acpi/sleep.h
@@ -17,3 +17,5 @@ extern void wakeup_long64(void);
17extern void do_suspend_lowlevel(void); 17extern void do_suspend_lowlevel(void);
18 18
19extern int x86_acpi_suspend_lowlevel(void); 19extern int x86_acpi_suspend_lowlevel(void);
20
21acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state);
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
index d1daa66ab162..665c6b7d2ea9 100644
--- a/arch/x86/kernel/acpi/wakeup_32.S
+++ b/arch/x86/kernel/acpi/wakeup_32.S
@@ -73,7 +73,7 @@ ENTRY(do_suspend_lowlevel)
73 call save_processor_state 73 call save_processor_state
74 call save_registers 74 call save_registers
75 pushl $3 75 pushl $3
76 call acpi_enter_sleep_state 76 call x86_acpi_enter_sleep_state
77 addl $4, %esp 77 addl $4, %esp
78 78
79# In case of S3 failure, we'll emerge here. Jump 79# In case of S3 failure, we'll emerge here. Jump
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index 8ea5164cbd04..ae693b51ed8e 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -73,7 +73,7 @@ ENTRY(do_suspend_lowlevel)
73 addq $8, %rsp 73 addq $8, %rsp
74 movl $3, %edi 74 movl $3, %edi
75 xorl %eax, %eax 75 xorl %eax, %eax
76 call acpi_enter_sleep_state 76 call x86_acpi_enter_sleep_state
77 /* in case something went wrong, restore the machine status and go on */ 77 /* in case something went wrong, restore the machine status and go on */
78 jmp resume_point 78 jmp resume_point
79 79
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index a7eb82d9b012..ed165d657380 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2107,7 +2107,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
2107 apic_write(APIC_LVT1, value); 2107 apic_write(APIC_LVT1, value);
2108} 2108}
2109 2109
2110void generic_processor_info(int apicid, int version) 2110int generic_processor_info(int apicid, int version)
2111{ 2111{
2112 int cpu, max = nr_cpu_ids; 2112 int cpu, max = nr_cpu_ids;
2113 bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, 2113 bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
@@ -2127,7 +2127,7 @@ void generic_processor_info(int apicid, int version)
2127 " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); 2127 " Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
2128 2128
2129 disabled_cpus++; 2129 disabled_cpus++;
2130 return; 2130 return -ENODEV;
2131 } 2131 }
2132 2132
2133 if (num_processors >= nr_cpu_ids) { 2133 if (num_processors >= nr_cpu_ids) {
@@ -2138,7 +2138,7 @@ void generic_processor_info(int apicid, int version)
2138 " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); 2138 " Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
2139 2139
2140 disabled_cpus++; 2140 disabled_cpus++;
2141 return; 2141 return -EINVAL;
2142 } 2142 }
2143 2143
2144 num_processors++; 2144 num_processors++;
@@ -2183,6 +2183,8 @@ void generic_processor_info(int apicid, int version)
2183#endif 2183#endif
2184 set_cpu_possible(cpu, true); 2184 set_cpu_possible(cpu, true);
2185 set_cpu_present(cpu, true); 2185 set_cpu_present(cpu, true);
2186
2187 return cpu;
2186} 2188}
2187 2189
2188int hard_smp_processor_id(void) 2190int hard_smp_processor_id(void)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 2a165580fa16..85dc05a3aa02 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -81,27 +81,6 @@
81/* State of each CPU */ 81/* State of each CPU */
82DEFINE_PER_CPU(int, cpu_state) = { 0 }; 82DEFINE_PER_CPU(int, cpu_state) = { 0 };
83 83
84#ifdef CONFIG_HOTPLUG_CPU
85/*
86 * We need this for trampoline_base protection from concurrent accesses when
87 * off- and onlining cores wildly.
88 */
89static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
90
91void cpu_hotplug_driver_lock(void)
92{
93 mutex_lock(&x86_cpu_hotplug_driver_mutex);
94}
95
96void cpu_hotplug_driver_unlock(void)
97{
98 mutex_unlock(&x86_cpu_hotplug_driver_mutex);
99}
100
101ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
102ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
103#endif
104
105/* Number of siblings per CPU package */ 84/* Number of siblings per CPU package */
106int smp_num_siblings = 1; 85int smp_num_siblings = 1;
107EXPORT_SYMBOL(smp_num_siblings); 86EXPORT_SYMBOL(smp_num_siblings);
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 6e60b5fe2244..649b010da00b 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -65,29 +65,32 @@ int __ref _debug_hotplug_cpu(int cpu, int action)
65 if (!cpu_is_hotpluggable(cpu)) 65 if (!cpu_is_hotpluggable(cpu))
66 return -EINVAL; 66 return -EINVAL;
67 67
68 cpu_hotplug_driver_lock(); 68 lock_device_hotplug();
69 69
70 switch (action) { 70 switch (action) {
71 case 0: 71 case 0:
72 ret = cpu_down(cpu); 72 ret = cpu_down(cpu);
73 if (!ret) { 73 if (!ret) {
74 pr_info("CPU %u is now offline\n", cpu); 74 pr_info("CPU %u is now offline\n", cpu);
75 dev->offline = true;
75 kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 76 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
76 } else 77 } else
77 pr_debug("Can't offline CPU%d.\n", cpu); 78 pr_debug("Can't offline CPU%d.\n", cpu);
78 break; 79 break;
79 case 1: 80 case 1:
80 ret = cpu_up(cpu); 81 ret = cpu_up(cpu);
81 if (!ret) 82 if (!ret) {
83 dev->offline = false;
82 kobject_uevent(&dev->kobj, KOBJ_ONLINE); 84 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
83 else 85 } else {
84 pr_debug("Can't online CPU%d.\n", cpu); 86 pr_debug("Can't online CPU%d.\n", cpu);
87 }
85 break; 88 break;
86 default: 89 default:
87 ret = -EINVAL; 90 ret = -EINVAL;
88 } 91 }
89 92
90 cpu_hotplug_driver_unlock(); 93 unlock_device_hotplug();
91 94
92 return ret; 95 return ret;
93} 96}
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
index a6b1b86d2253..518532e6a3fa 100644
--- a/arch/x86/lib/msr-smp.c
+++ b/arch/x86/lib/msr-smp.c
@@ -47,6 +47,21 @@ int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
47} 47}
48EXPORT_SYMBOL(rdmsr_on_cpu); 48EXPORT_SYMBOL(rdmsr_on_cpu);
49 49
50int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
51{
52 int err;
53 struct msr_info rv;
54
55 memset(&rv, 0, sizeof(rv));
56
57 rv.msr_no = msr_no;
58 err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
59 *q = rv.reg.q;
60
61 return err;
62}
63EXPORT_SYMBOL(rdmsrl_on_cpu);
64
50int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) 65int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
51{ 66{
52 int err; 67 int err;
@@ -63,6 +78,22 @@ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
63} 78}
64EXPORT_SYMBOL(wrmsr_on_cpu); 79EXPORT_SYMBOL(wrmsr_on_cpu);
65 80
81int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
82{
83 int err;
84 struct msr_info rv;
85
86 memset(&rv, 0, sizeof(rv));
87
88 rv.msr_no = msr_no;
89 rv.reg.q = q;
90
91 err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
92
93 return err;
94}
95EXPORT_SYMBOL(wrmsrl_on_cpu);
96
66static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no, 97static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
67 struct msr *msrs, 98 struct msr *msrs,
68 void (*msr_func) (void *info)) 99 void (*msr_func) (void *info))
@@ -159,6 +190,37 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
159} 190}
160EXPORT_SYMBOL(wrmsr_safe_on_cpu); 191EXPORT_SYMBOL(wrmsr_safe_on_cpu);
161 192
193int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
194{
195 int err;
196 struct msr_info rv;
197
198 memset(&rv, 0, sizeof(rv));
199
200 rv.msr_no = msr_no;
201 rv.reg.q = q;
202
203 err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
204
205 return err ? err : rv.err;
206}
207EXPORT_SYMBOL(wrmsrl_safe_on_cpu);
208
209int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
210{
211 int err;
212 struct msr_info rv;
213
214 memset(&rv, 0, sizeof(rv));
215
216 rv.msr_no = msr_no;
217 err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
218 *q = rv.reg.q;
219
220 return err ? err : rv.err;
221}
222EXPORT_SYMBOL(rdmsrl_safe_on_cpu);
223
162/* 224/*
163 * These variants are significantly slower, but allows control over 225 * These variants are significantly slower, but allows control over
164 * the entire 32-bit GPR set. 226 * the entire 32-bit GPR set.
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c
index fef7d0ba7e3a..649a12befba9 100644
--- a/arch/x86/platform/olpc/olpc-xo15-sci.c
+++ b/arch/x86/platform/olpc/olpc-xo15-sci.c
@@ -40,16 +40,9 @@ static bool lid_wake_on_close;
40 */ 40 */
41static int set_lid_wake_behavior(bool wake_on_close) 41static int set_lid_wake_behavior(bool wake_on_close)
42{ 42{
43 struct acpi_object_list arg_list;
44 union acpi_object arg;
45 acpi_status status; 43 acpi_status status;
46 44
47 arg_list.count = 1; 45 status = acpi_execute_simple_method(NULL, "\\_SB.PCI0.LID.LIDW", wake_on_close);
48 arg_list.pointer = &arg;
49 arg.type = ACPI_TYPE_INTEGER;
50 arg.integer.value = wake_on_close;
51
52 status = acpi_evaluate_object(NULL, "\\_SB.PCI0.LID.LIDW", &arg_list, NULL);
53 if (ACPI_FAILURE(status)) { 46 if (ACPI_FAILURE(status)) {
54 pr_warning(PFX "failed to set lid behavior\n"); 47 pr_warning(PFX "failed to set lid behavior\n");
55 return 1; 48 return 1;