diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2013-04-11 15:38:50 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-04-13 15:36:27 -0400 |
commit | 87fa05aeb3a5e8e21b1a5510eef6983650eff092 (patch) | |
tree | 8d1cdcf61ffee47cf1ed7898ae6219f05096529c /arch/sparc | |
parent | 781b0e870c72be8a24c074073547e74e7b9bffd6 (diff) |
sparc: Use generic idle loop
Add generic cpu_idle support
sparc32:
- replace call to cpu_idle() with cpu_startup_entry()
- add arch_cpu_idle()
sparc64:
- smp_callin() now include cpu_startup_entry() call so we can
skip calling cpu_idle from assembler
- add arch_cpu_idle() and arch_cpu_idle_dead()
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>
Cc: torvalds@linux-foundation.org
Cc: rusty@rustcorp.com.au
Cc: paulmck@linux.vnet.ibm.com
Cc: peterz@infradead.org
Cc: magnus.damm@gmail.com
Acked-by: David Miller <davem@davemloft.net>
Link: http://lkml.kernel.org/r/20130411193850.GA2330@merkur.ravnborg.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/hvtramp.S | 3 | ||||
-rw-r--r-- | arch/sparc/kernel/process_32.c | 21 | ||||
-rw-r--r-- | arch/sparc/kernel/process_64.c | 49 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_32.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/trampoline_64.S | 3 |
7 files changed, 24 insertions, 57 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 3d361f236308..ee5eacc5a649 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -37,6 +37,7 @@ config SPARC | |||
37 | select GENERIC_SMP_IDLE_THREAD | 37 | select GENERIC_SMP_IDLE_THREAD |
38 | select GENERIC_CMOS_UPDATE | 38 | select GENERIC_CMOS_UPDATE |
39 | select GENERIC_CLOCKEVENTS | 39 | select GENERIC_CLOCKEVENTS |
40 | select GENERIC_IDLE_LOOP | ||
40 | select GENERIC_STRNCPY_FROM_USER | 41 | select GENERIC_STRNCPY_FROM_USER |
41 | select GENERIC_STRNLEN_USER | 42 | select GENERIC_STRNLEN_USER |
42 | select MODULES_USE_ELF_RELA | 43 | select MODULES_USE_ELF_RELA |
diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S index 9365432904d6..605c960b2fa6 100644 --- a/arch/sparc/kernel/hvtramp.S +++ b/arch/sparc/kernel/hvtramp.S | |||
@@ -128,8 +128,7 @@ hv_cpu_startup: | |||
128 | 128 | ||
129 | call smp_callin | 129 | call smp_callin |
130 | nop | 130 | nop |
131 | call cpu_idle | 131 | |
132 | mov 0, %o0 | ||
133 | call cpu_panic | 132 | call cpu_panic |
134 | nop | 133 | nop |
135 | 134 | ||
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 62eede13831a..c85241006e32 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -64,23 +64,12 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); | |||
64 | struct task_struct *last_task_used_math = NULL; | 64 | struct task_struct *last_task_used_math = NULL; |
65 | struct thread_info *current_set[NR_CPUS]; | 65 | struct thread_info *current_set[NR_CPUS]; |
66 | 66 | ||
67 | /* | 67 | /* Idle loop support. */ |
68 | * the idle loop on a Sparc... ;) | 68 | void arch_cpu_idle(void) |
69 | */ | ||
70 | void cpu_idle(void) | ||
71 | { | 69 | { |
72 | set_thread_flag(TIF_POLLING_NRFLAG); | 70 | if (sparc_idle) |
73 | 71 | (*sparc_idle)(); | |
74 | /* endless idle loop with no priority at all */ | 72 | local_irq_enable(); |
75 | for (;;) { | ||
76 | while (!need_resched()) { | ||
77 | if (sparc_idle) | ||
78 | (*sparc_idle)(); | ||
79 | else | ||
80 | cpu_relax(); | ||
81 | } | ||
82 | schedule_preempt_disabled(); | ||
83 | } | ||
84 | } | 73 | } |
85 | 74 | ||
86 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ | 75 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index cdb80b2adbe0..9fbf0d14a361 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -52,20 +52,17 @@ | |||
52 | 52 | ||
53 | #include "kstack.h" | 53 | #include "kstack.h" |
54 | 54 | ||
55 | static void sparc64_yield(int cpu) | 55 | /* Idle loop support on sparc64. */ |
56 | void arch_cpu_idle(void) | ||
56 | { | 57 | { |
57 | if (tlb_type != hypervisor) { | 58 | if (tlb_type != hypervisor) { |
58 | touch_nmi_watchdog(); | 59 | touch_nmi_watchdog(); |
59 | return; | 60 | } else { |
60 | } | ||
61 | |||
62 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
63 | smp_mb__after_clear_bit(); | ||
64 | |||
65 | while (!need_resched() && !cpu_is_offline(cpu)) { | ||
66 | unsigned long pstate; | 61 | unsigned long pstate; |
67 | 62 | ||
68 | /* Disable interrupts. */ | 63 | /* The sun4v sleeping code requires that we have PSTATE.IE cleared over |
64 | * the cpu sleep hypervisor call. | ||
65 | */ | ||
69 | __asm__ __volatile__( | 66 | __asm__ __volatile__( |
70 | "rdpr %%pstate, %0\n\t" | 67 | "rdpr %%pstate, %0\n\t" |
71 | "andn %0, %1, %0\n\t" | 68 | "andn %0, %1, %0\n\t" |
@@ -73,7 +70,7 @@ static void sparc64_yield(int cpu) | |||
73 | : "=&r" (pstate) | 70 | : "=&r" (pstate) |
74 | : "i" (PSTATE_IE)); | 71 | : "i" (PSTATE_IE)); |
75 | 72 | ||
76 | if (!need_resched() && !cpu_is_offline(cpu)) | 73 | if (!need_resched() && !cpu_is_offline(smp_processor_id())) |
77 | sun4v_cpu_yield(); | 74 | sun4v_cpu_yield(); |
78 | 75 | ||
79 | /* Re-enable interrupts. */ | 76 | /* Re-enable interrupts. */ |
@@ -84,36 +81,16 @@ static void sparc64_yield(int cpu) | |||
84 | : "=&r" (pstate) | 81 | : "=&r" (pstate) |
85 | : "i" (PSTATE_IE)); | 82 | : "i" (PSTATE_IE)); |
86 | } | 83 | } |
87 | 84 | local_irq_enable(); | |
88 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
89 | } | 85 | } |
90 | 86 | ||
91 | /* The idle loop on sparc64. */ | ||
92 | void cpu_idle(void) | ||
93 | { | ||
94 | int cpu = smp_processor_id(); | ||
95 | |||
96 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
97 | |||
98 | while(1) { | ||
99 | tick_nohz_idle_enter(); | ||
100 | rcu_idle_enter(); | ||
101 | |||
102 | while (!need_resched() && !cpu_is_offline(cpu)) | ||
103 | sparc64_yield(cpu); | ||
104 | |||
105 | rcu_idle_exit(); | ||
106 | tick_nohz_idle_exit(); | ||
107 | |||
108 | #ifdef CONFIG_HOTPLUG_CPU | 87 | #ifdef CONFIG_HOTPLUG_CPU |
109 | if (cpu_is_offline(cpu)) { | 88 | void arch_cpu_idle_dead() |
110 | sched_preempt_enable_no_resched(); | 89 | { |
111 | cpu_play_dead(); | 90 | sched_preempt_enable_no_resched(); |
112 | } | 91 | cpu_play_dead(); |
113 | #endif | ||
114 | schedule_preempt_disabled(); | ||
115 | } | ||
116 | } | 92 | } |
93 | #endif | ||
117 | 94 | ||
118 | #ifdef CONFIG_COMPAT | 95 | #ifdef CONFIG_COMPAT |
119 | static void show_regwindow32(struct pt_regs *regs) | 96 | static void show_regwindow32(struct pt_regs *regs) |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 9e7e6d718367..e3f2b81c23f1 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -369,7 +369,7 @@ void __cpuinit sparc_start_secondary(void *arg) | |||
369 | local_irq_enable(); | 369 | local_irq_enable(); |
370 | 370 | ||
371 | wmb(); | 371 | wmb(); |
372 | cpu_idle(); | 372 | cpu_startup_entry(CPUHP_ONLINE); |
373 | 373 | ||
374 | /* We should never reach here! */ | 374 | /* We should never reach here! */ |
375 | BUG(); | 375 | BUG(); |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 537eb66abd06..c025ffce7a40 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -127,6 +127,8 @@ void __cpuinit smp_callin(void) | |||
127 | 127 | ||
128 | /* idle thread is expected to have preempt disabled */ | 128 | /* idle thread is expected to have preempt disabled */ |
129 | preempt_disable(); | 129 | preempt_disable(); |
130 | |||
131 | cpu_startup_entry(CPUHP_ONLINE); | ||
130 | } | 132 | } |
131 | 133 | ||
132 | void cpu_panic(void) | 134 | void cpu_panic(void) |
diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S index da1b781b5e65..2e973a26fbda 100644 --- a/arch/sparc/kernel/trampoline_64.S +++ b/arch/sparc/kernel/trampoline_64.S | |||
@@ -407,8 +407,7 @@ after_lock_tlb: | |||
407 | 407 | ||
408 | call smp_callin | 408 | call smp_callin |
409 | nop | 409 | nop |
410 | call cpu_idle | 410 | |
411 | mov 0, %o0 | ||
412 | call cpu_panic | 411 | call cpu_panic |
413 | nop | 412 | nop |
414 | 1: b,a,pt %xcc, 1b | 413 | 1: b,a,pt %xcc, 1b |