diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-03-21 17:49:56 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-04-08 11:39:27 -0400 |
commit | 799fef06123f86ff69cf754f996219e6ad1678f8 (patch) | |
tree | 818cf29ad50eb765309500194b3792804af28612 | |
parent | fad48ad63dd14656e3b571d42f700a1f2cadd036 (diff) |
powerpc: Use generic idle loop
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Link: http://lkml.kernel.org/r/20130321215235.026838003@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/powerpc/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle.c | 89 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp.c | 2 |
3 files changed, 31 insertions, 61 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index ea5bb045983a..19de32c52da5 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -133,6 +133,7 @@ config PPC | |||
133 | select HAVE_ARCH_JUMP_LABEL | 133 | select HAVE_ARCH_JUMP_LABEL |
134 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 134 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
135 | select GENERIC_SMP_IDLE_THREAD | 135 | select GENERIC_SMP_IDLE_THREAD |
136 | select GENERIC_IDLE_LOOP | ||
136 | select GENERIC_CMOS_UPDATE | 137 | select GENERIC_CMOS_UPDATE |
137 | select GENERIC_TIME_VSYSCALL_OLD | 138 | select GENERIC_TIME_VSYSCALL_OLD |
138 | select GENERIC_CLOCKEVENTS | 139 | select GENERIC_CLOCKEVENTS |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index ea78761aa169..939ea7ef0dc8 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -33,11 +33,6 @@ | |||
33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
34 | #include <asm/smp.h> | 34 | #include <asm/smp.h> |
35 | 35 | ||
36 | #ifdef CONFIG_HOTPLUG_CPU | ||
37 | #define cpu_should_die() cpu_is_offline(smp_processor_id()) | ||
38 | #else | ||
39 | #define cpu_should_die() 0 | ||
40 | #endif | ||
41 | 36 | ||
42 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; | 37 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; |
43 | EXPORT_SYMBOL(cpuidle_disable); | 38 | EXPORT_SYMBOL(cpuidle_disable); |
@@ -50,64 +45,38 @@ static int __init powersave_off(char *arg) | |||
50 | } | 45 | } |
51 | __setup("powersave=off", powersave_off); | 46 | __setup("powersave=off", powersave_off); |
52 | 47 | ||
53 | /* | 48 | #ifdef CONFIG_HOTPLUG_CPU |
54 | * The body of the idle task. | 49 | void arch_cpu_idle_dead(void) |
55 | */ | ||
56 | void cpu_idle(void) | ||
57 | { | 50 | { |
58 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | sched_preempt_enable_no_resched(); |
59 | while (1) { | 52 | cpu_die(); |
60 | tick_nohz_idle_enter(); | 53 | } |
61 | rcu_idle_enter(); | 54 | #endif |
62 | |||
63 | while (!need_resched() && !cpu_should_die()) { | ||
64 | ppc64_runlatch_off(); | ||
65 | |||
66 | if (ppc_md.power_save) { | ||
67 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
68 | /* | ||
69 | * smp_mb is so clearing of TIF_POLLING_NRFLAG | ||
70 | * is ordered w.r.t. need_resched() test. | ||
71 | */ | ||
72 | smp_mb(); | ||
73 | local_irq_disable(); | ||
74 | |||
75 | /* Don't trace irqs off for idle */ | ||
76 | stop_critical_timings(); | ||
77 | |||
78 | /* check again after disabling irqs */ | ||
79 | if (!need_resched() && !cpu_should_die()) | ||
80 | ppc_md.power_save(); | ||
81 | |||
82 | start_critical_timings(); | ||
83 | |||
84 | /* Some power_save functions return with | ||
85 | * interrupts enabled, some don't. | ||
86 | */ | ||
87 | if (irqs_disabled()) | ||
88 | local_irq_enable(); | ||
89 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
90 | |||
91 | } else { | ||
92 | /* | ||
93 | * Go into low thread priority and possibly | ||
94 | * low power mode. | ||
95 | */ | ||
96 | HMT_low(); | ||
97 | HMT_very_low(); | ||
98 | } | ||
99 | } | ||
100 | 55 | ||
101 | HMT_medium(); | 56 | void arch_cpu_idle(void) |
102 | ppc64_runlatch_on(); | 57 | { |
103 | rcu_idle_exit(); | 58 | ppc64_runlatch_off(); |
104 | tick_nohz_idle_exit(); | 59 | |
105 | if (cpu_should_die()) { | 60 | if (ppc_md.power_save) { |
106 | sched_preempt_enable_no_resched(); | 61 | ppc_md.power_save(); |
107 | cpu_die(); | 62 | /* |
108 | } | 63 | * Some power_save functions return with |
109 | schedule_preempt_disabled(); | 64 | * interrupts enabled, some don't. |
65 | */ | ||
66 | if (irqs_disabled()) | ||
67 | local_irq_enable(); | ||
68 | } else { | ||
69 | local_irq_enable(); | ||
70 | /* | ||
71 | * Go into low thread priority and possibly | ||
72 | * low power mode. | ||
73 | */ | ||
74 | HMT_low(); | ||
75 | HMT_very_low(); | ||
110 | } | 76 | } |
77 | |||
78 | HMT_medium(); | ||
79 | ppc64_runlatch_on(); | ||
111 | } | 80 | } |
112 | 81 | ||
113 | int powersave_nap; | 82 | int powersave_nap; |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 76bd9da8cb71..ee7ac5e6e28a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -669,7 +669,7 @@ __cpuinit void start_secondary(void *unused) | |||
669 | 669 | ||
670 | local_irq_enable(); | 670 | local_irq_enable(); |
671 | 671 | ||
672 | cpu_idle(); | 672 | cpu_startup_entry(CPUHP_ONLINE); |
673 | 673 | ||
674 | BUG(); | 674 | BUG(); |
675 | } | 675 | } |