diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2013-03-21 22:49:38 +0100 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2013-04-08 17:39:24 +0200 | 
| commit | f7b861b7a6d9d1838cbbb5f4053e61578b86d134 (patch) | |
| tree | 07a20a48c6577f92ad702e93ccb308a6d12632db | |
| parent | a123322d8afcfb5f86e0cc0062024084658aeeb2 (diff) | |
| download | olio-linux-3.10-f7b861b7a6d9d1838cbbb5f4053e61578b86d134.tar.xz olio-linux-3.10-f7b861b7a6d9d1838cbbb5f4053e61578b86d134.zip  | |
arm: Use generic idle loop
Use the generic idle loop and replace enable/disable_hlt with the
respective core functions.
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: Russell King <linux@arm.linux.org.uk>
Tested-by: Kevin Hilman <khilman@linaro.org> # OMAP
Link: http://lkml.kernel.org/r/20130321215233.826238797@linutronix.de
| -rw-r--r-- | arch/arm/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/include/asm/system_misc.h | 3 | ||||
| -rw-r--r-- | arch/arm/kernel/process.c | 96 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-gemini/idle.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-gemini/irq.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-ixp4xx/common.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-omap1/pm.c | 6 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 7 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/pm.c | 5 | ||||
| -rw-r--r-- | arch/arm/mach-orion5x/board-dt.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-orion5x/common.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-shark/core.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/suspend.c | 6 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/dev.c | 3 | 
15 files changed, 57 insertions, 92 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1cacda426a0..128551fcc6d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -15,6 +15,8 @@ config ARM  	select GENERIC_IRQ_SHOW  	select GENERIC_PCI_IOMAP  	select GENERIC_SMP_IDLE_THREAD +	select GENERIC_IDLE_LOOP +	select GENERIC_IDLE_POLL_SETUP  	select GENERIC_STRNCPY_FROM_USER  	select GENERIC_STRNLEN_USER  	select HARDIRQS_SW_RESEND diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h index 5a85f148b60..21a23e378bb 100644 --- a/arch/arm/include/asm/system_misc.h +++ b/arch/arm/include/asm/system_misc.h @@ -21,9 +21,6 @@ extern void (*arm_pm_idle)(void);  extern unsigned int user_debug; -extern void disable_hlt(void); -extern void enable_hlt(void); -  #endif /* !__ASSEMBLY__ */  #endif /* __ASM_ARM_SYSTEM_MISC_H */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 92884c86189..c9a5e2ce8aa 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -57,34 +57,6 @@ static const char *isa_modes[] = {    "ARM" , "Thumb" , "Jazelle", "ThumbEE"  }; -static volatile int hlt_counter; - -void disable_hlt(void) -{ -	hlt_counter++; -} - -void enable_hlt(void) -{ -	hlt_counter--; -	BUG_ON(hlt_counter < 0); -} - -static int __init nohlt_setup(char *__unused) -{ -	hlt_counter = 1; -	return 1; -} - -static int __init hlt_setup(char *__unused) -{ -	hlt_counter = 0; -	return 1; -} - -__setup("nohlt", nohlt_setup); -__setup("hlt", hlt_setup); -  extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);  typedef void (*phys_reset_t)(unsigned long); @@ -168,54 +140,38 @@ static void default_idle(void)  	local_irq_enable();  } -/* - * The idle thread. - * We always respect 'hlt_counter' to prevent low power idle. - */ -void cpu_idle(void) +void arch_cpu_idle_prepare(void)  {  	local_fiq_enable(); +} -	/* endless idle loop with no priority at all */ -	while (1) { -		tick_nohz_idle_enter(); -		rcu_idle_enter(); -		ledtrig_cpu(CPU_LED_IDLE_START); -		while (!need_resched()) { -#ifdef CONFIG_HOTPLUG_CPU -			if (cpu_is_offline(smp_processor_id())) -				cpu_die(); +void arch_cpu_idle_enter(void) +{ +	ledtrig_cpu(CPU_LED_IDLE_START); +#ifdef CONFIG_PL310_ERRATA_769419 +	wmb();  #endif +} -			/* -			 * We need to disable interrupts here -			 * to ensure we don't miss a wakeup call. -			 */ -			local_irq_disable(); -#ifdef CONFIG_PL310_ERRATA_769419 -			wmb(); +void arch_cpu_idle_exit(void) +{ +	ledtrig_cpu(CPU_LED_IDLE_END); +} + +#ifdef CONFIG_HOTPLUG_CPU +void arch_cpu_idle_dead(void) +{ +	cpu_die(); +}  #endif -			if (hlt_counter) { -				local_irq_enable(); -				cpu_relax(); -			} else if (!need_resched()) { -				stop_critical_timings(); -				if (cpuidle_idle_call()) -					default_idle(); -				start_critical_timings(); -				/* -				 * default_idle functions must always -				 * return with IRQs enabled. -				 */ -				WARN_ON(irqs_disabled()); -			} else -				local_irq_enable(); -		} -		ledtrig_cpu(CPU_LED_IDLE_END); -		rcu_idle_exit(); -		tick_nohz_idle_exit(); -		schedule_preempt_disabled(); -	} + +/* + * Called from the core idle loop. + */ +void arch_cpu_idle(void) +{ +	if (cpuidle_idle_call()) +		default_idle();  }  static char reboot_mode = 'h'; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 1f2ccccaf00..4619177bcfe 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -336,7 +336,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)  	/*  	 * OK, it's off to the idle thread for us  	 */ -	cpu_idle(); +	cpu_startup_entry(CPUHP_ONLINE);  }  void __init smp_cpus_done(unsigned int max_cpus) diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c index 92bbd6bb600..87dff4f5059 100644 --- a/arch/arm/mach-gemini/idle.c +++ b/arch/arm/mach-gemini/idle.c @@ -13,9 +13,11 @@ static void gemini_idle(void)  	 * will never wakeup... Acctualy it is not very good to enable  	 * interrupts first since scheduler can miss a tick, but there is  	 * no other way around this. Platforms that needs it for power saving -	 * should call enable_hlt() in init code, since by default it is +	 * should enable it in init code, since by default it is  	 * disabled.  	 */ + +	/* FIXME: Enabling interrupts here is racy! */  	local_irq_enable();  	cpu_do_idle();  } diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index 020852d3bdd..6d8f6d1669f 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c @@ -15,6 +15,8 @@  #include <linux/stddef.h>  #include <linux/list.h>  #include <linux/sched.h> +#include <linux/cpu.h> +  #include <asm/irq.h>  #include <asm/mach/irq.h>  #include <asm/system_misc.h> @@ -77,7 +79,7 @@ void __init gemini_init_irq(void)  	 * Disable the idle handler by default since it is buggy  	 * For more info see arch/arm/mach-gemini/idle.c  	 */ -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	request_resource(&iomem_resource, &irq_resource); diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 1dbeb7c99d5..6600cff6bd9 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -29,6 +29,7 @@  #include <linux/io.h>  #include <linux/export.h>  #include <linux/gpio.h> +#include <linux/cpu.h>  #include <mach/udc.h>  #include <mach/hardware.h> @@ -239,7 +240,7 @@ void __init ixp4xx_init_irq(void)  	 * ixp4xx does not implement the XScale PWRMODE register  	 * so it must not call cpu_do_idle().  	 */ -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	/* Route all sources to IRQ instead of FIQ */  	*IXP4XX_ICLR = 0x0; diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 7a7690ab6cb..db37f49da5a 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -43,6 +43,7 @@  #include <linux/module.h>  #include <linux/io.h>  #include <linux/atomic.h> +#include <linux/cpu.h>  #include <asm/fncpy.h>  #include <asm/system_misc.h> @@ -584,8 +585,7 @@ static void omap_pm_init_proc(void)  static int omap_pm_prepare(void)  {  	/* We cannot sleep in idle until we have resumed */ -	disable_hlt(); - +	cpu_idle_poll_ctrl(true);  	return 0;  } @@ -621,7 +621,7 @@ static int omap_pm_enter(suspend_state_t state)  static void omap_pm_finish(void)  { -	enable_hlt(); +	cpu_idle_poll_ctrl(false);  } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index a202a478510..e512253601c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -138,6 +138,7 @@  #include <linux/spinlock.h>  #include <linux/slab.h>  #include <linux/bootmem.h> +#include <linux/cpu.h>  #include <asm/system_misc.h> @@ -2157,7 +2158,7 @@ static int _enable(struct omap_hwmod *oh)  	if (soc_ops.enable_module)  		soc_ops.enable_module(oh);  	if (oh->flags & HWMOD_BLOCK_WFI) -		disable_hlt(); +		cpu_idle_poll_ctrl(true);  	if (soc_ops.update_context_lost)  		soc_ops.update_context_lost(oh); @@ -2221,7 +2222,7 @@ static int _idle(struct omap_hwmod *oh)  	_del_initiator_dep(oh, mpu_oh);  	if (oh->flags & HWMOD_BLOCK_WFI) -		enable_hlt(); +		cpu_idle_poll_ctrl(false);  	if (soc_ops.disable_module)  		soc_ops.disable_module(oh); @@ -2331,7 +2332,7 @@ static int _shutdown(struct omap_hwmod *oh)  		_del_initiator_dep(oh, mpu_oh);  		/* XXX what about the other system initiators here? dma, dsp */  		if (oh->flags & HWMOD_BLOCK_WFI) -			enable_hlt(); +			cpu_idle_poll_ctrl(false);  		if (soc_ops.disable_module)  			soc_ops.disable_module(oh);  		_disable_clocks(oh); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 673a4c1d1d7..dec553349ae 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -218,7 +218,7 @@ static int omap_pm_enter(suspend_state_t suspend_state)  static int omap_pm_begin(suspend_state_t state)  { -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	if (cpu_is_omap34xx())  		omap_prcm_irq_prepare();  	return 0; @@ -226,8 +226,7 @@ static int omap_pm_begin(suspend_state_t state)  static void omap_pm_end(void)  { -	enable_hlt(); -	return; +	cpu_idle_poll_ctrl(false);  }  static void omap_pm_finish(void) diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c index 35a8014529c..94fbb815680 100644 --- a/arch/arm/mach-orion5x/board-dt.c +++ b/arch/arm/mach-orion5x/board-dt.c @@ -14,6 +14,7 @@  #include <linux/init.h>  #include <linux/of.h>  #include <linux/of_platform.h> +#include <linux/cpu.h>  #include <asm/system_misc.h>  #include <asm/mach/arch.h>  #include <mach/orion5x.h> @@ -52,7 +53,7 @@ static void __init orion5x_dt_init(void)  	 */  	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {  		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n"); -		disable_hlt(); +		cpu_idle_poll_ctrl(true);  	}  	if (of_machine_is_compatible("lacie,ethernet-disk-mini-v2")) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index d068f1431c4..ad71c8a03ff 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -293,7 +293,7 @@ void __init orion5x_init(void)  	 */  	if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {  		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n"); -		disable_hlt(); +		cpu_idle_poll_ctrl(true);  	}  	/* diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index b63dec84819..15355572498 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -10,6 +10,7 @@  #include <linux/sched.h>  #include <linux/serial_8250.h>  #include <linux/io.h> +#include <linux/cpu.h>  #include <asm/setup.h>  #include <asm/mach-types.h> @@ -130,7 +131,7 @@ static void __init shark_timer_init(void)  static void shark_init_early(void)  { -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  }  MACHINE_START(SHARK, "Shark") diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index 47d83f7a70b..5d92b5dd486 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -12,6 +12,8 @@  #include <linux/suspend.h>  #include <linux/module.h>  #include <linux/err.h> +#include <linux/cpu.h> +  #include <asm/io.h>  #include <asm/system_misc.h> @@ -23,13 +25,13 @@ static int shmobile_suspend_default_enter(suspend_state_t suspend_state)  static int shmobile_suspend_begin(suspend_state_t state)  { -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	return 0;  }  static void shmobile_suspend_end(void)  { -	enable_hlt(); +	cpu_idle_poll_ctrl(false);  }  struct platform_suspend_ops shmobile_suspend_ops = { diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 7abdb9645c5..e65a80a1ac7 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c @@ -19,6 +19,7 @@  #include <linux/init.h>  #include <linux/platform_device.h>  #include <linux/slab.h> +#include <linux/cpu.h>  #include <linux/mtd/physmap.h>  #include <linux/mtd/mtd.h> @@ -531,7 +532,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = {  void __init nuc900_board_init(struct platform_device **device, int size)  { -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	platform_add_devices(device, size);  	platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));  	spi_register_board_info(nuc900_spi_board_info,  |