aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/process.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-05-14 06:39:48 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-05-21 01:34:25 -0400
commitf3a9022fd187de41a04de9c5b44ff40e68c6d661 (patch)
tree352fd4f2bc35469721a218093bf4e65a6c1d9209 /arch/sh/kernel/process.c
parent69d87daa18aced7f494bc1d5a977b063bbbdffbd (diff)
sh: sr.bl toggling around idle sleep.
As pointed out by Saito-san, without the sr.bl manipulation we can occasionally hit delays in the idle loop due to interrupt handling, so ensure that interrupts are blocked before going to sleep. At the same time, we throw in TIF_POLLING_NRFLAG for the !hlt_counter case (primarily used by the ST-40 parts). Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r--arch/sh/kernel/process.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6b4f5748d0be..a11e2aa73cbc 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -26,8 +26,6 @@
26static int hlt_counter; 26static int hlt_counter;
27int ubc_usercnt = 0; 27int ubc_usercnt = 0;
28 28
29#define HARD_IDLE_TIMEOUT (HZ / 3)
30
31void (*pm_idle)(void); 29void (*pm_idle)(void);
32void (*pm_power_off)(void); 30void (*pm_power_off)(void);
33EXPORT_SYMBOL(pm_power_off); 31EXPORT_SYMBOL(pm_power_off);
@@ -44,16 +42,39 @@ void enable_hlt(void)
44} 42}
45EXPORT_SYMBOL(enable_hlt); 43EXPORT_SYMBOL(enable_hlt);
46 44
45static int __init nohlt_setup(char *__unused)
46{
47 hlt_counter = 1;
48 return 1;
49}
50__setup("nohlt", nohlt_setup);
51
52static int __init hlt_setup(char *__unused)
53{
54 hlt_counter = 0;
55 return 1;
56}
57__setup("hlt", hlt_setup);
58
47void default_idle(void) 59void default_idle(void)
48{ 60{
49 if (!hlt_counter) 61 if (!hlt_counter) {
50 cpu_sleep(); 62 clear_thread_flag(TIF_POLLING_NRFLAG);
51 else 63 smp_mb__after_clear_bit();
52 cpu_relax(); 64 set_bl_bit();
65 while (!need_resched())
66 cpu_sleep();
67 clear_bl_bit();
68 set_thread_flag(TIF_POLLING_NRFLAG);
69 } else
70 while (!need_resched())
71 cpu_relax();
53} 72}
54 73
55void cpu_idle(void) 74void cpu_idle(void)
56{ 75{
76 set_thread_flag(TIF_POLLING_NRFLAG);
77
57 /* endless idle loop with no priority at all */ 78 /* endless idle loop with no priority at all */
58 while (1) { 79 while (1) {
59 void (*idle)(void) = pm_idle; 80 void (*idle)(void) = pm_idle;