]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
sh: Use generic idle loop
authorThomas Gleixner <tglx@linutronix.de>
Thu, 21 Mar 2013 21:49:59 +0000 (22:49 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 8 Apr 2013 15:39:28 +0000 (17:39 +0200)
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: Paul Mundt <lethal@linux-sh.org>
Link: http://lkml.kernel.org/r/20130321215235.216323644@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/sh/Kconfig
arch/sh/kernel/idle.c
arch/sh/kernel/smp.c

index 5e859633ce69f13c9d2b1d1c1a5727ad986a9fab..853cbc971cdf1e0c4efa6425becc3d2043b45a87 100644 (file)
@@ -33,6 +33,8 @@ config SUPERH
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_SHOW
        select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_IDLE_LOOP
+       select GENERIC_IDLE_POLL_SETUP
        select GENERIC_CLOCKEVENTS
        select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
        select GENERIC_STRNCPY_FROM_USER
index 3d5a1b387cc0f48b23d569779769a39f735a0664..2ea4483fd7227c669796644bc47bd3e80b252222 100644 (file)
 
 static void (*sh_idle)(void);
 
-static int hlt_counter;
-
-static int __init nohlt_setup(char *__unused)
-{
-       hlt_counter = 1;
-       return 1;
-}
-__setup("nohlt", nohlt_setup);
-
-static int __init hlt_setup(char *__unused)
-{
-       hlt_counter = 0;
-       return 1;
-}
-__setup("hlt", hlt_setup);
-
-static inline int hlt_works(void)
-{
-       return !hlt_counter;
-}
-
-/*
- * On SMP it's slightly faster (but much more power-consuming!)
- * to poll the ->work.need_resched flag instead of waiting for the
- * cross-CPU IPI to arrive. Use this option with caution.
- */
-static void poll_idle(void)
+void default_idle(void)
 {
+       set_bl_bit();
        local_irq_enable();
-       while (!need_resched())
-               cpu_relax();
+       /* Isn't this racy ? */
+       cpu_sleep();
+       clear_bl_bit();
 }
 
-void default_idle(void)
+void arch_cpu_idle_dead(void)
 {
-       if (hlt_works()) {
-               clear_thread_flag(TIF_POLLING_NRFLAG);
-               smp_mb__after_clear_bit();
-
-               set_bl_bit();
-               if (!need_resched()) {
-                       local_irq_enable();
-                       cpu_sleep();
-               } else
-                       local_irq_enable();
-
-               set_thread_flag(TIF_POLLING_NRFLAG);
-               clear_bl_bit();
-       } else
-               poll_idle();
+       play_dead();
 }
 
-/*
- * The idle thread. There's no useful work to be done, so just try to conserve
- * power and have a low exit latency (ie sit in a loop waiting for somebody to
- * say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
 {
-       unsigned int cpu = smp_processor_id();
-
-       set_thread_flag(TIF_POLLING_NRFLAG);
-
-       /* endless idle loop with no priority at all */
-       while (1) {
-               tick_nohz_idle_enter();
-               rcu_idle_enter();
-
-               while (!need_resched()) {
-                       check_pgt_cache();
-                       rmb();
-
-                       if (cpu_is_offline(cpu))
-                               play_dead();
-
-                       local_irq_disable();
-                       /* Don't trace irqs off for idle */
-                       stop_critical_timings();
-                       if (cpuidle_idle_call())
-                               sh_idle();
-                       /*
-                        * Sanity check to ensure that sh_idle() returns
-                        * with IRQs enabled
-                        */
-                       WARN_ON(irqs_disabled());
-                       start_critical_timings();
-               }
-
-               rcu_idle_exit();
-               tick_nohz_idle_exit();
-               schedule_preempt_disabled();
-       }
+       if (cpuidle_idle_call())
+               sh_idle();
 }
 
 void __init select_idle_routine(void)
@@ -123,13 +49,8 @@ void __init select_idle_routine(void)
        /*
         * If a platform has set its own idle routine, leave it alone.
         */
-       if (sh_idle)
-               return;
-
-       if (hlt_works())
+       if (!sh_idle)
                sh_idle = default_idle;
-       else
-               sh_idle = poll_idle;
 }
 
 void stop_this_cpu(void *unused)
index 2062aa88af41cc696d1f5892782245c4d73190fa..45696451f0ea3ee3ec5452d78ddd2d55ab50d38c 100644 (file)
@@ -203,7 +203,7 @@ asmlinkage void __cpuinit start_secondary(void)
        set_cpu_online(cpu, true);
        per_cpu(cpu_state, cpu) = CPU_ONLINE;
 
-       cpu_idle();
+       cpu_startup_entry(CPUHP_ONLINE);
 }
 
 extern struct {