Browse Source

sh: Provide cpu_idle_wait() to fix up cpuidle/SMP build.

Crib the x86 cpu_idle_wait() implementation and shove it in with the
idle code, subsequently enabling ARCH_HAS_CPU_IDLE_WAIT.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Paul Mundt 16 years ago
parent
commit
2e046b9487
3 changed files with 26 additions and 1 deletions
  1. 3 0
      arch/sh/Kconfig
  2. 1 0
      arch/sh/include/asm/system.h
  3. 22 1
      arch/sh/kernel/idle.c

+ 3 - 0
arch/sh/Kconfig

@@ -151,6 +151,9 @@ config ARCH_NO_VIRT_TO_BUS
 config ARCH_HAS_DEFAULT_IDLE
 config ARCH_HAS_DEFAULT_IDLE
 	def_bool y
 	def_bool y
 
 
+config ARCH_HAS_CPU_IDLE_WAIT
+	def_bool y
+
 config IO_TRAPPED
 config IO_TRAPPED
 	bool
 	bool
 
 

+ 1 - 0
arch/sh/include/asm/system.h

@@ -154,6 +154,7 @@ extern struct dentry *sh_debugfs_root;
 
 
 void per_cpu_trap_init(void);
 void per_cpu_trap_init(void);
 void default_idle(void);
 void default_idle(void);
+void cpu_idle_wait(void);
 
 
 asmlinkage void break_point_trap(void);
 asmlinkage void break_point_trap(void);
 
 

+ 22 - 1
arch/sh/kernel/idle.c

@@ -1,7 +1,7 @@
 /*
 /*
  * The idle loop for all SuperH platforms.
  * The idle loop for all SuperH platforms.
  *
  *
- *  Copyright (C) 2002 - 2008  Paul Mundt
+ *  Copyright (C) 2002 - 2009  Paul Mundt
  *
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * License.  See the file "COPYING" in the main directory of this archive
@@ -15,6 +15,7 @@
 #include <linux/preempt.h>
 #include <linux/preempt.h>
 #include <linux/thread_info.h>
 #include <linux/thread_info.h>
 #include <linux/irqflags.h>
 #include <linux/irqflags.h>
+#include <linux/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/atomic.h>
@@ -79,3 +80,23 @@ void cpu_idle(void)
 		check_pgt_cache();
 		check_pgt_cache();
 	}
 	}
 }
 }
+
+static void do_nothing(void *unused)
+{
+}
+
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
+void cpu_idle_wait(void)
+{
+	smp_mb();
+	/* kick all the CPUs so that they exit out of pm_idle */
+	smp_call_function(do_nothing, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);