diff options
-rw-r--r-- | arch/powerpc/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 4 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-powernv.c | 34 |
3 files changed, 39 insertions, 1 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 957bf344c0f5..b84142000a4d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -130,6 +130,8 @@ config PPC | |||
130 | select GENERIC_CMOS_UPDATE | 130 | select GENERIC_CMOS_UPDATE |
131 | select GENERIC_TIME_VSYSCALL_OLD | 131 | select GENERIC_TIME_VSYSCALL_OLD |
132 | select GENERIC_CLOCKEVENTS | 132 | select GENERIC_CLOCKEVENTS |
133 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP | ||
134 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | ||
133 | select GENERIC_STRNCPY_FROM_USER | 135 | select GENERIC_STRNCPY_FROM_USER |
134 | select GENERIC_STRNLEN_USER | 136 | select GENERIC_STRNLEN_USER |
135 | select HAVE_MOD_ARCH_SPECIFIC | 137 | select HAVE_MOD_ARCH_SPECIFIC |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index df2989b0d4c0..122a580f7322 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/timex.h> | 42 | #include <linux/timex.h> |
43 | #include <linux/kernel_stat.h> | 43 | #include <linux/kernel_stat.h> |
44 | #include <linux/time.h> | 44 | #include <linux/time.h> |
45 | #include <linux/clockchips.h> | ||
45 | #include <linux/init.h> | 46 | #include <linux/init.h> |
46 | #include <linux/profile.h> | 47 | #include <linux/profile.h> |
47 | #include <linux/cpu.h> | 48 | #include <linux/cpu.h> |
@@ -106,7 +107,7 @@ struct clock_event_device decrementer_clockevent = { | |||
106 | .irq = 0, | 107 | .irq = 0, |
107 | .set_next_event = decrementer_set_next_event, | 108 | .set_next_event = decrementer_set_next_event, |
108 | .set_mode = decrementer_set_mode, | 109 | .set_mode = decrementer_set_mode, |
109 | .features = CLOCK_EVT_FEAT_ONESHOT, | 110 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP, |
110 | }; | 111 | }; |
111 | EXPORT_SYMBOL(decrementer_clockevent); | 112 | EXPORT_SYMBOL(decrementer_clockevent); |
112 | 113 | ||
@@ -944,6 +945,7 @@ void __init time_init(void) | |||
944 | clocksource_init(); | 945 | clocksource_init(); |
945 | 946 | ||
946 | init_decrementer_clockevent(); | 947 | init_decrementer_clockevent(); |
948 | tick_setup_hrtimer_broadcast(); | ||
947 | } | 949 | } |
948 | 950 | ||
949 | 951 | ||
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 78fd174c57e8..4fb97cef82fd 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/cpuidle.h> | 11 | #include <linux/cpuidle.h> |
12 | #include <linux/cpu.h> | 12 | #include <linux/cpu.h> |
13 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
14 | #include <linux/clockchips.h> | ||
14 | 15 | ||
15 | #include <asm/machdep.h> | 16 | #include <asm/machdep.h> |
16 | #include <asm/firmware.h> | 17 | #include <asm/firmware.h> |
@@ -49,6 +50,32 @@ static int nap_loop(struct cpuidle_device *dev, | |||
49 | return index; | 50 | return index; |
50 | } | 51 | } |
51 | 52 | ||
53 | static int fastsleep_loop(struct cpuidle_device *dev, | ||
54 | struct cpuidle_driver *drv, | ||
55 | int index) | ||
56 | { | ||
57 | unsigned long old_lpcr = mfspr(SPRN_LPCR); | ||
58 | unsigned long new_lpcr; | ||
59 | |||
60 | if (unlikely(system_state < SYSTEM_RUNNING)) | ||
61 | return index; | ||
62 | |||
63 | new_lpcr = old_lpcr; | ||
64 | new_lpcr &= ~(LPCR_MER | LPCR_PECE); /* lpcr[mer] must be 0 */ | ||
65 | |||
66 | /* exit powersave upon external interrupt, but not decrementer | ||
67 | * interrupt. | ||
68 | */ | ||
69 | new_lpcr |= LPCR_PECE0; | ||
70 | |||
71 | mtspr(SPRN_LPCR, new_lpcr); | ||
72 | power7_sleep(); | ||
73 | |||
74 | mtspr(SPRN_LPCR, old_lpcr); | ||
75 | |||
76 | return index; | ||
77 | } | ||
78 | |||
52 | /* | 79 | /* |
53 | * States for dedicated partition case. | 80 | * States for dedicated partition case. |
54 | */ | 81 | */ |
@@ -67,6 +94,13 @@ static struct cpuidle_state powernv_states[] = { | |||
67 | .exit_latency = 10, | 94 | .exit_latency = 10, |
68 | .target_residency = 100, | 95 | .target_residency = 100, |
69 | .enter = &nap_loop }, | 96 | .enter = &nap_loop }, |
97 | { /* Fastsleep */ | ||
98 | .name = "fastsleep", | ||
99 | .desc = "fastsleep", | ||
100 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
101 | .exit_latency = 10, | ||
102 | .target_residency = 100, | ||
103 | .enter = &fastsleep_loop }, | ||
70 | }; | 104 | }; |
71 | 105 | ||
72 | static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n, | 106 | static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n, |