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, |
