Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] sh: machine_halt()/machine_power_off() cleanups

machine_halt() managed to trigger the soft lockup detection due to not
disabling interrupts before going to sleep, so correct that.

machine_power_off() should be using pm_power_off, which lets us drop the
board-specific hacks from here.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Paul Mundt and committed by
Linus Torvalds
a3310bbd 6c80a1f8

+26 -28
+26 -28
arch/sh/kernel/process.c
··· 15 15 #include <linux/unistd.h> 16 16 #include <linux/mm.h> 17 17 #include <linux/elfcore.h> 18 - #include <linux/slab.h> 19 18 #include <linux/a.out.h> 19 + #include <linux/slab.h> 20 + #include <linux/pm.h> 20 21 #include <linux/ptrace.h> 21 22 #include <linux/platform.h> 22 23 #include <linux/kallsyms.h> 24 + #include <linux/kexec.h> 23 25 24 26 #include <asm/io.h> 25 27 #include <asm/uaccess.h> 26 28 #include <asm/mmu_context.h> 27 29 #include <asm/elf.h> 28 - #if defined(CONFIG_SH_HS7751RVOIP) 29 - #include <asm/hs7751rvoip/hs7751rvoip.h> 30 - #elif defined(CONFIG_SH_RTS7751R2D) 31 - #include <asm/rts7751r2d/rts7751r2d.h> 32 - #endif 33 30 34 31 static int hlt_counter=0; 35 32 36 33 int ubc_usercnt = 0; 37 34 38 35 #define HARD_IDLE_TIMEOUT (HZ / 3) 36 + 37 + void (*pm_idle)(void); 38 + 39 + void (*pm_power_off)(void); 40 + EXPORT_SYMBOL(pm_power_off); 39 41 40 42 void disable_hlt(void) 41 43 { ··· 53 51 54 52 EXPORT_SYMBOL(enable_hlt); 55 53 54 + void default_idle(void) 55 + { 56 + if (!hlt_counter) 57 + cpu_sleep(); 58 + else 59 + cpu_relax(); 60 + } 61 + 56 62 void cpu_idle(void) 57 63 { 58 64 /* endless idle loop with no priority at all */ 59 65 while (1) { 60 - if (hlt_counter) { 61 - while (!need_resched()) 62 - cpu_relax(); 63 - } else { 64 - while (!need_resched()) 65 - cpu_sleep(); 66 - } 66 + void (*idle)(void) = pm_idle; 67 + 68 + if (!idle) 69 + idle = default_idle; 70 + 71 + while (!need_resched()) 72 + idle(); 67 73 68 74 preempt_enable_no_resched(); 69 75 schedule(); ··· 98 88 99 89 void machine_halt(void) 100 90 { 101 - #if defined(CONFIG_SH_HS7751RVOIP) 102 - unsigned short value; 91 + local_irq_disable(); 103 92 104 - value = ctrl_inw(PA_OUTPORTR); 105 - ctrl_outw((value & 0xffdf), PA_OUTPORTR); 106 - #elif defined(CONFIG_SH_RTS7751R2D) 107 - ctrl_outw(0x0001, PA_POWOFF); 108 - #endif 109 93 while (1) 110 94 cpu_sleep(); 111 95 } 112 96 113 97 void machine_power_off(void) 114 98 { 115 - #if defined(CONFIG_SH_HS7751RVOIP) 116 - unsigned short value; 117 - 118 - value = ctrl_inw(PA_OUTPORTR); 119 - ctrl_outw((value & 0xffdf), PA_OUTPORTR); 120 - #elif defined(CONFIG_SH_RTS7751R2D) 121 - ctrl_outw(0x0001, PA_POWOFF); 122 - #endif 99 + if (pm_power_off) 100 + pm_power_off(); 123 101 } 124 102 125 103 void show_regs(struct pt_regs * regs)