step towards removal of mach/system.h
Subsystems (10)
cover step towards removal of mach/system.h
In the spirit of eventually being able to boot a single zImage on multiple SOCs, we need to get rid of mach/system.h. This file mainly contains two inline functions that should be out-of-line and assigned to the existing global hooks at run time. Those functions are arch_idle() and arch_reset(). The following series only address the former.
This is a RFC and RFT patch series. This was not compiled even less tested yet, but I'm posting it now in the hope that people could help fixing/testing this on the platform they have access to, or even improve upon this initial draft patches.
The same thing needs to be done with arch_reset(), however there is no existing global reset hook yet, only arm_pm_restart which may be used but implies a bit more than arch_reset() does.
[PATCH 01/12] ARM: clean up idle handlers
[PATCH 02/12] ARM: mach-at91: move special idle code to a [PATCH 03/12] ARM: mach-clps711x: move special idle code to a [PATCH 04/12] ARM: mach-ebsa110: move special idle code to a [PATCH 05/12] ARM: mach-gemini: move special idle code to a [PATCH 06/12] ARM: mach-h720x: move special idle code to a [PATCH 07/12] ARM: mach-ixp23xx: properly disable CPU idle call [PATCH 08/12] ARM: mach-ixp4xx: properly disable CPU idle call [PATCH 09/12] ARM: s3c24xx: move special idle code to a proper [PATCH 10/12] ARM: mach-shark: properly disable CPU idle call [PATCH 11/12] ARM: mach-w90x900: properly disable CPU idle call [PATCH 12/12] ARM: imx: move special idle code to proper out-of-line
PATCH 1/12 ARM: clean up idle handlers
Let's factor out the need_resched() check instead of having it duplicated in every pm_idle implementations to avoid inconsistencies (omap2_pm_idle was missing it already).
The forceful re-enablement of IRQs after pm_idle has returned can go. The warning certainly doesn't trigger for existing users. Similar for the redundant local_irq_disable() call in the OMAP implementations.
And finally move the comment explaining the reason for the turning off of IRQs to a more proper location.
--- arch/arm/kernel/process.c | 19 ++++++++++--------- arch/arm/mach-exynos4/cpu.c | 4 +--- arch/arm/mach-omap1/pm.c | 6 ------ arch/arm/mach-omap2/pm24xx.c | 1 - arch/arm/mach-omap2/pm34xx.c | 3 +-- arch/arm/mach-s5p64x0/cpu.c | 15 +++++++-------- arch/arm/mach-s5pc100/cpu.c | 4 +--- arch/arm/mach-s5pv210/cpu.c | 4 +--- 8 files changed, 21 insertions(+), 35 deletions(-)
arch/arm/kernel/process.c +10 -9
@@ -158,13 +158,11 @@ void cpu_idle_wait(void)EXPORT_SYMBOL_GPL (cpu_idle_wait);/* -* This is our default idle handler. We need to disable -* interrupts here to ensure we don't miss a wakeup call. +* This is our default idle handler. */ static void default_idle (void ) { -if (!need_resched ()) -arch_idle (); +arch_idle ();local_irq_enable (); }
@@ -191,23 +189,26 @@ void cpu_idle(void)cpu_die ();#endif +/* +* We need to disable interrupts here +* to ensure we don't miss a wakeup call. +*/ local_irq_disable ();if (hlt_counter) {local_irq_enable ();cpu_relax (); - }else { + }else if (!need_resched ()) {stop_critical_timings ();if (cpuidle_idle_call ())pm_idle ();start_critical_timings ();/* -* This will eventually be removed - pm_idle -* functions should always return with IRQs -* enabled. +* pm_idle functions should always +* return with IRQs enabled. */ WARN_ON (irqs_disabled ()); + }else local_irq_enable (); - } }leds_event (led_idle_end);tick_nohz_restart_sched_tick ();
arch/arm/mach-exynos4/cpu.c +1 -3
@@ -123,9 +123,7 @@ static struct map_desc exynos4_iodesc[] __initdata = {static void exynos4_idle (void ) { -if (!need_resched ()) -cpu_do_idle (); - +cpu_do_idle ();local_irq_enable (); }
arch/arm/mach-omap1/pm.c +0 -6
@@ -108,13 +108,7 @@ void omap1_pm_idle(void)__u32 use_idlect1 = arm_idlect1_mask;int do_sleep =0 ; -local_irq_disable ();local_fiq_disable (); -if (need_resched ()) { -local_fiq_enable (); -local_irq_enable (); -return ; - }#ifdef CONFIG_OMAP_MPU_TIMER #warning Enable 32kHz OS timer in order to allow sleep states in idle
arch/arm/mach-omap2/pm24xx.c +0 -1
@@ -277,7 +277,6 @@ static int omap2_can_sleep(void)static void omap2_pm_idle (void ) { -local_irq_disable ();local_fiq_disable ();if (!omap2_can_sleep ()) {
arch/arm/mach-omap2/pm34xx.c +1 -2
@@ -492,13 +492,12 @@ int omap3_can_sleep(void)static void omap3_pm_idle (void ) { -local_irq_disable ();local_fiq_disable ();if (!omap3_can_sleep ()) goto out; -if (omap_irq_pending () ||need_resched ()) +if (omap_irq_pending ()) goto out;trace_power_start (POWER_CSTATE ,1 ,smp_processor_id ());
arch/arm/mach-s5p64x0/cpu.c +7 -8
@@ -88,14 +88,13 @@ static void s5p64x0_idle(void) {unsigned long val; -if (!need_resched ()) { - val =__raw_readl (S5P64X0_PWR_CFG ); - val &= ~(0x3 <<5 ); - val |= (0x1 <<5 ); -__raw_writel (val,S5P64X0_PWR_CFG ); - -cpu_do_idle (); - } + val =__raw_readl (S5P64X0_PWR_CFG ); + val &= ~(0x3 <<5 ); + val |= (0x1 <<5 ); +__raw_writel (val,S5P64X0_PWR_CFG ); + +cpu_do_idle (); +local_irq_enable (); }
arch/arm/mach-s5pc100/cpu.c +1 -3
@@ -94,9 +94,7 @@ static struct map_desc s5pc100_iodesc[] __initdata = {static void s5pc100_idle (void ) { -if (!need_resched ()) -cpu_do_idle (); - +cpu_do_idle ();local_irq_enable (); }
arch/arm/mach-s5pv210/cpu.c +1 -3
@@ -101,9 +101,7 @@ static struct map_desc s5pv210_iodesc[] __initdata = {static void s5pv210_idle (void ) { -if (!need_resched ()) -cpu_do_idle (); - +cpu_do_idle ();local_irq_enable (); }
Signature · 1 line
1.7.7.1.431.g10b2a
Tony Lindgren
maintainerPATCH 1/12 ARM: clean up idle handlers
Quoted 7 lines · Nicolas Pitre
Let's factor out the
need_resched()check instead of having it duplicated in everypm_idleimplementations to avoid inconsistencies (omap2_pm_idlewas missing it already).The forceful re-enablement of IRQs after
pm_idlehas returned can go. The warning certainly doesn't trigger for existing users. Similar for the redundantlocal_irq_disable()call in the OMAP implementations.
Looks good to me.
Quoted 2 lines
And finally move the comment explaining the reason for the turning off of IRQs to a more proper location.
One minor comment on that comment below.
Quoted 2 lines
arch/arm/kernel/process.c +0
-0
...
arch/arm/kernel/process.c void cpu_idle(void) · line 210
Quoted 10 lines
arch/arm/kernel/process.c +3
-4-* This will eventually be removed - pm_idle -* functions should always return with IRQs -* enabled. +* pm_idle functions should always +* return with IRQs enabled. */ WARN_ON (irqs_disabled ()); + }else local_irq_enable (); - }
Any reason to use "should always return" instead of "must always return with IRQs enabled"?
Regards,
Tony
PATCH 1/12 ARM: clean up idle handlers
Quoted 20 lines · Tony Lindgren
Quoted 7 lines · Nicolas Pitre
Let's factor out the
need_resched()check instead of having it duplicated in everypm_idleimplementations to avoid inconsistencies (omap2_pm_idlewas missing it already).The forceful re-enablement of IRQs after
pm_idlehas returned can go. The warning certainly doesn't trigger for existing users. Similar for the redundantlocal_irq_disable()call in the OMAP implementations.Looks good to me.
Quoted 2 lines
And finally move the comment explaining the reason for the turning off of IRQs to a more proper location.
One minor comment on that comment below.
Quoted 2 lines
arch/arm/kernel/process.c +0
-0...
Quoted 13 lines
arch/arm/kernel/process.c void cpu_idle(void) · line 210
Quoted 10 lines
arch/arm/kernel/process.c +3
-4-* This will eventually be removed - pm_idle -* functions should always return with IRQs -* enabled. +* pm_idle functions should always +* return with IRQs enabled. */ WARN_ON (irqs_disabled ()); + }else local_irq_enable (); - }Any reason to use "should always return" instead of "must always return with IRQs enabled"?
I think it's now a 'must' rather than a 'should'. I'm not aware of any cases recently where IRQs were disabled at this point.
PATCH 1/12 ARM: clean up idle handlers
In reply to Nicolas PitreQuoted 3 lines · Nicolas Pitre
Let's factor out the
need_resched()check instead of having it duplicated in everypm_idleimplementations to avoid inconsistencies (omap2_pm_idlewas missing it already).
If we do this, we should talk to the other architecture maintainers as well to keep all architectures pm_idle hooks the same.
PATCH 2/12 ARM: mach-at91: move special idle code to a out-of-line pm_idle hook
In reply to Nicolas Pitre--- arch/arm/mach-at91/at91cap9.c | 8 ++++++++ arch/arm/mach-at91/at91rm9200.c | 11 +++++++++++ arch/arm/mach-at91/at91sam9260.c | 8 ++++++++ arch/arm/mach-at91/at91sam9261.c | 8 ++++++++ arch/arm/mach-at91/at91sam9263.c | 8 ++++++++ arch/arm/mach-at91/at91sam9g45.c | 8 ++++++++ arch/arm/mach-at91/at91sam9rl.c | 8 ++++++++ arch/arm/mach-at91/at91x40.c | 11 +++++++++++ arch/arm/mach-at91/include/mach/system.h | 16 ---------------- 9 files changed, 70 insertions(+), 16 deletions(-)
arch/arm/mach-at91/at91cap9.c +8 -0
@@ -311,6 +311,13 @@ static struct at91_gpio_bank at91cap9_gpio[] = { } }; +static void at91cap9_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void at91cap9_reset (void ) {at91_sys_write (AT91_RSTC_CR ,AT91_RSTC_KEY |AT91_RSTC_PROCRST |AT91_RSTC_PERRST );
@@ -333,6 +340,7 @@ static void __init at91cap9_map_io(void)static void __init at91cap9_initialize (void ) { + pm_idle = at91cap9_idle; at91_arch_reset = at91cap9_reset; pm_power_off = at91cap9_poweroff; at91_extern_irq = (1 <<AT91CAP9_ID_IRQ0 ) | (1 <<AT91CAP9_ID_IRQ1 );
arch/arm/mach-at91/at91rm9200.c +11 -0
@@ -286,6 +286,16 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; +static void at91rm9200_idle (void ) +{ +/* +* Disable the processor clock. The processor will be automatically +* re-enabled by an interrupt or by a reset. +*/ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +local_irq_enable (); +} +static void at91rm9200_reset (void ) {/*
@@ -307,6 +317,7 @@ static void __init at91rm9200_map_io(void)static void __init at91rm9200_initialize (void ) { + pm_idle = at91rm9200_idle; at91_arch_reset = at91rm9200_reset; at91_extern_irq = (1 <<AT91RM9200_ID_IRQ0 ) | (1 <<AT91RM9200_ID_IRQ1 ) | (1 <<AT91RM9200_ID_IRQ2 ) | (1 <<AT91RM9200_ID_IRQ3 )
arch/arm/mach-at91/at91sam9260.c +8 -0
@@ -315,8 +315,16 @@ static void __init at91sam9260_map_io(void) } } +static void at91sam9260_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void __init at91sam9260_initialize (void ) { + pm_idle = at91sam9260_idle; at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 <<AT91SAM9260_ID_IRQ0 ) | (1 <<AT91SAM9260_ID_IRQ1 )
arch/arm/mach-at91/at91sam9261.c +8 -0
@@ -284,8 +284,16 @@ static void __init at91sam9261_map_io(void)at91_init_sram (0 ,AT91SAM9261_SRAM_BASE ,AT91SAM9261_SRAM_SIZE ); } +static void at91sam9261_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void __init at91sam9261_initialize (void ) { + pm_idle = at91sam9261_idle; at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 <<AT91SAM9261_ID_IRQ0 ) | (1 <<AT91SAM9261_ID_IRQ1 )
arch/arm/mach-at91/at91sam9263.c +8 -0
@@ -301,8 +301,16 @@ static void __init at91sam9263_map_io(void)at91_init_sram (1 ,AT91SAM9263_SRAM1_BASE ,AT91SAM9263_SRAM1_SIZE ); } +static void at91sam9263_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void __init at91sam9263_initialize (void ) { + pm_idle = at91sam9263_idle; at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9263_poweroff; at91_extern_irq = (1 <<AT91SAM9263_ID_IRQ0 ) | (1 <<AT91SAM9263_ID_IRQ1 );
arch/arm/mach-at91/at91sam9g45.c +8 -0
@@ -302,6 +302,13 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { } }; +static void at91sam9g45_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void at91sam9g45_reset (void ) {at91_sys_write (AT91_RSTC_CR ,AT91_RSTC_KEY |AT91_RSTC_PROCRST |AT91_RSTC_PERRST );
@@ -325,6 +332,7 @@ static void __init at91sam9g45_map_io(void)static void __init at91sam9g45_initialize (void ) { + pm_idle = at91sam9g45_idle; at91_arch_reset = at91sam9g45_reset; pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 <<AT91SAM9G45_ID_IRQ0 );
arch/arm/mach-at91/at91sam9rl.c +8 -0
@@ -290,8 +290,16 @@ static void __init at91sam9rl_map_io(void)at91_init_sram (0 ,AT91SAM9RL_SRAM_BASE , sram_size); } +static void at91sam9rl_idle (void ) +{ +at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); +cpu_do_idle (); +local_irq_enable (); +} +static void __init at91sam9rl_initialize (void ) { + pm_idle = at91sam9rl_idle; at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 <<AT91SAM9RL_ID_IRQ0 );
arch/arm/mach-at91/at91x40.c +11 -0
@@ -37,8 +37,19 @@ unsigned long clk_get_rate(struct clk *clk)return AT91X40_MASTER_CLOCK ; } +static void at91x40_idle (void ) +{ +/* +* Disable the processor clock. The processor will be automatically +* re-enabled by an interrupt or by a reset. +*/ +at91_sys_write (AT91_PS_CR ,AT91_PS_CR_CPU ); +cpu_do_idle (); +} +void __init at91x40_initialize (unsigned long main_clock) { + pm_idle = at91x40_idle; at91_extern_irq = (1 <<AT91X40_ID_IRQ0 ) | (1 <<AT91X40_ID_IRQ1 ) | (1 <<AT91X40_ID_IRQ2 ); }
arch/arm/mach-at91/include/mach/system.h +0 -16
@@ -28,23 +28,7 @@static inline void arch_idle (void ) { -/* -* Disable the processor clock. The processor will be automatically -* re-enabled by an interrupt or by a reset. -*/ -#ifdef AT91_PS -at91_sys_write (AT91_PS_CR ,AT91_PS_CR_CPU ); -#else -at91_sys_write (AT91_PMC_SCDR ,AT91_PMC_PCK ); -#endif -#ifndef CONFIG_CPU_ARM920T -/* -* Set the processor (CP15) into 'Wait for Interrupt' mode. -* Post-RM9200 processors need this in conjunction with the above -* to save power when idle. -*/ cpu_do_idle (); -#endif }void (*at91_arch_reset)(void );
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 3/12 ARM: mach-clps711x: move special idle code to a out-of-line pm_idle hook
In reply to Nicolas Pitre--- arch/arm/mach-clps711x/Makefile | 2 +- arch/arm/mach-clps711x/idle.c | 25 +++++++++++++++++++++++++ arch/arm/mach-clps711x/include/mach/system.h | 5 +---- 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-clps711x/idle.c
arch/arm/mach-clps711x/Makefile +1 -1
@@ -4,7 +4,7 @@ # Object file lists. -obj-y := irq.o mm.o time.o +obj-y := irq.o mm.o time.o idle.o obj-m := obj-n := obj- :=
arch/arm/mach-clps711x/idle.c new file +25 -0
@@ -0,0 +1,25 @@ +/* +* arch/arm/mach-clps711x/idle.c +*/ + +#include <linux/init.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <asm/hardware/clps7111.h> + +static void clps711x_idle (void ) +{ +clps_writel (1 ,HALT ); + __asm__ __volatile__( +"mov r0, r0\n\ +mov r0, r0" ); +} + +static int __init clps711x_idle_init (void ) +{ + pm_idle = clps711x_idle; +return 0 ; +} + +arch_initcall (clps711x_idle_init); +
arch/arm/mach-clps711x/include/mach/system.h +1 -4
@@ -26,10 +26,7 @@static inline void arch_idle (void ) { -clps_writel (1 ,HALT ); - __asm__ __volatile__( -"mov r0, r0\n\ -mov r0, r0" ); +cpu_do_idle (); }static inline void arch_reset (char mode,const char *cmd)
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 4/12 ARM: mach-ebsa110: move special idle code to a out-of-line pm_idle hook
In reply to Nicolas Pitre--- arch/arm/mach-ebsa110/core.c | 28 +++++++++++++++++++++++++++ arch/arm/mach-ebsa110/include/mach/system.h | 21 +------------------- 2 files changed, 29 insertions(+), 20 deletions(-)
arch/arm/mach-ebsa110/core.c +28 -0
@@ -271,8 +271,36 @@ static struct platform_device *ebsa110_devices[] = { &am79c961_device, }; +/* +* EBSA110 idling methodology: +* +* We can not execute the "wait for interrupt" instruction since that +* will stop our MCLK signal (which provides the clock for the glue +* logic, and therefore the timer interrupt). +* +* Instead, we spin, polling the IRQ_STAT register for the occurrence +* of any interrupt with core clock down to the memory clock. +*/ +static void ebsa110_idle (void ) +{ +const char *irq_stat = (char *)0xff000000 ; + +/* disable clock switching */ + asmvolatile ("mcr p15, 0, ip, c15, c2, 2" : : :"cc" ); + +/* wait for an interrupt to occur */ +while (!*irq_stat); + +/* enable clock switching */ + asmvolatile ("mcr p15, 0, ip, c15, c1, 2" : : :"cc" ); + +/* return with IRQ enabled */ +local_irq_enable (); +} +static int __init ebsa110_init (void ) { + pm_idle = ebsa110_idle;return platform_add_devices (ebsa110_devices,ARRAY_SIZE (ebsa110_devices)); }
arch/arm/mach-ebsa110/include/mach/system.h +1 -20
@@ -10,28 +10,9 @@#ifndef __ASM_ARCH_SYSTEM_H#define __ASM_ARCH_SYSTEM_H -/* -* EBSA110 idling methodology: -* -* We can not execute the "wait for interrupt" instruction since that -* will stop our MCLK signal (which provides the clock for the glue -* logic, and therefore the timer interrupt). -* -* Instead, we spin, polling the IRQ_STAT register for the occurrence -* of any interrupt with core clock down to the memory clock. -*/ static inline void arch_idle (void ) { -const char *irq_stat = (char *)0xff000000 ; - -/* disable clock switching */ - asmvolatile ("mcr p15, 0, ip, c15, c2, 2" : : :"cc" ); - -/* wait for an interrupt to occur */ -while (!*irq_stat); - -/* enable clock switching */ - asmvolatile ("mcr p15, 0, ip, c15, c1, 2" : : :"cc" ); +cpu_do_idle (); }#define arch_reset (mode, cmd) cpu_reset(0x80000000)
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 5/12 ARM: mach-gemini: move special idle code to a out-of-line pm_idle hook
In reply to Nicolas Pitre--- arch/arm/mach-gemini/Makefile | 2 +- arch/arm/mach-gemini/idle.c | 28 ++++++++++++++++++++++++++++ arch/arm/mach-gemini/include/mach/system.h | 10 ---------- 3 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 arch/arm/mach-gemini/idle.c
arch/arm/mach-gemini/Makefile +1 -1
@@ -4,7 +4,7 @@ # Object file lists. -obj-y := irq.o mm.o time.o devices.o gpio.o +obj-y := irq.o mm.o time.o devices.o gpio.o idle.o # Board-specific support obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o
arch/arm/mach-gemini/idle.c new file +28 -0
@@ -0,0 +1,28 @@ +/* +* arch/arm/mach-gemini/idle.c +*/ + +#include <linux/init.h> + +static void gemini_idle (void ) +{ +/* +* Because of broken hardware we have to enable interrupts or the CPU +* 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 +* disabled. +*/ +local_irq_enable (); +cpu_do_idle (); +} + +static int __init gemini_idle_init (void ) +{ + pm_idle = gemini_idle; +return 0 ; +} + +arch_initcall (gemini_idle_init); +
arch/arm/mach-gemini/include/mach/system.h +0 -10
@@ -16,16 +16,6 @@static inline void arch_idle (void ) { -/* -* Because of broken hardware we have to enable interrupts or the CPU -* will never wakeup... Acctualy it is not very good to enable -* interrupts here 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 -* disabled. -*/ -local_irq_enable (); -cpu_do_idle (); }static inline void arch_reset (char mode,const char *cmd)
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 6/12 ARM: mach-h720x: move special idle code to a out-of-line pm_idle hook
In reply to Nicolas Pitre--- arch/arm/mach-h720x/common.c | 20 ++++++++++++++++++++ arch/arm/mach-h720x/include/mach/system.h | 6 ------ 2 files changed, 20 insertions(+), 6 deletions(-)
arch/arm/mach-h720x/common.c +20 -0
@@ -242,3 +242,23 @@ void __init h720x_map_io(void) {iotable_init (h720x_io_desc,ARRAY_SIZE (h720x_io_desc)); } + +static void h720x__idle (void ) +{ +CPU_REG (PMU_BASE ,PMU_MODE ) =PMU_MODE_IDLE ; +nop (); +nop (); +CPU_REG (PMU_BASE ,PMU_MODE ) =PMU_MODE_RUN ; +nop (); +nop (); +local_irq_enable (); +} + +static int __init h720x__idle_init (void ) +{ + pm_idle = h720x__idle; +return 0 ; +} + +arch_initcall (h720x_idle_init); +
arch/arm/mach-h720x/include/mach/system.h +0 -6
@@ -16,12 +16,6 @@static void arch_idle (void ) { -CPU_REG (PMU_BASE ,PMU_MODE ) =PMU_MODE_IDLE ; -nop (); -nop (); -CPU_REG (PMU_BASE ,PMU_MODE ) =PMU_MODE_RUN ; -nop (); -nop (); }
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 7/12 ARM: mach-ixp23xx: properly disable CPU idle call
In reply to Nicolas Pitre--- arch/arm/mach-ixp23xx/core.c | 3 +++ arch/arm/mach-ixp23xx/include/mach/system.h | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-)
arch/arm/mach-ixp23xx/core.c +3 -0
@@ -443,4 +443,7 @@ void __init ixp23xx_sys_init(void) { *IXP23XX_EXP_UNIT_FUSE |=0xf ;platform_add_devices (ixp23xx_devices,ARRAY_SIZE (ixp23xx_devices)); + +/* by default, the idle code is disabled */ +disable_hlt (); }
arch/arm/mach-ixp23xx/include/mach/system.h +0 -4
@@ -13,10 +13,6 @@static inline void arch_idle (void ) { -#if 0 -if (!hlt_counter) -cpu_do_idle (); -#endif }static inline void arch_reset (char mode,const char *cmd)
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 8/12 ARM: mach-ixp4xx: properly disable CPU idle call
In reply to Nicolas Pitre--- arch/arm/mach-ixp4xx/common.c | 7 +++++++ arch/arm/mach-ixp4xx/include/mach/system.h | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-)
arch/arm/mach-ixp4xx/common.c +7 -0
@@ -256,6 +256,13 @@ void __init ixp4xx_init_irq(void) handle_level_irq);set_irq_flags (i,IRQF_VALID ); } + +/* +* ixp4xx does not implement the XScale PWRMODE register +* ixp4xx does not implement the XScale PWRMODE registerso it must not +* call cpu_do_idle(). +*/ +disable_hlt (); }
arch/arm/mach-ixp4xx/include/mach/system.h +0 -6
@@ -13,12 +13,6 @@static inline void arch_idle (void ) { -/* ixp4xx does not implement the XScale PWRMODE register, -* so it must not call cpu_do_idle() here. -*/ -#if 0 -cpu_do_idle (); -#endif }
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 8/12 ARM: mach-ixp4xx: properly disable CPU idle call
arch/arm/mach-ixp4xx/common.c void __init ixp4xx_init_irq(void) · line 262
Quoted 3 lines · Nicolas Pitre
arch/arm/mach-ixp4xx/common.c +3
-0+/* +* ixp4xx does not implement the XScale PWRMODE register +* ixp4xx does not implement the XScale PWRMODE registerso it must not
Missing space between 'register' and 'so', otherwise this is fine.
PATCH 9/12 ARM: s3c24xx: move special idle code to a proper out-of-line pm_idle hooks
In reply to Nicolas Pitre--- arch/arm/mach-s3c2410/include/mach/system.h | 30 --------------------------- arch/arm/mach-s3c2412/s3c2412.c | 4 +- arch/arm/mach-s3c2416/s3c2416.c | 2 - arch/arm/plat-s3c24xx/cpu.c | 30 +++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 34 deletions(-)
arch/arm/mach-s3c2410/include/mach/system.h +0 -30
@@ -19,40 +19,10 @@#include <mach/regs-clock.h> -void (*s3c24xx_idle)(void );void (*s3c24xx_reset_hook)(void ); -void s3c24xx_default_idle (void ) -{ -unsigned long tmp; -int i; - -/* idle the system by using the idle mode which will wait for an -* interrupt to happen before restarting the system. -*/ - -/* Warning: going into idle state upsets jtag scanning */ - -__raw_writel (__raw_readl (S3C2410_CLKCON ) |S3C2410_CLKCON_IDLE , -S3C2410_CLKCON ); - -/* the samsung port seems to do a loop and then unset idle.. */ -for (i =0 ; i <50 ; i++) { - tmp +=__raw_readl (S3C2410_CLKCON );/* ensure loop not optimised out */ - } - -/* this bit is not cleared on re-start... */ - -__raw_writel (__raw_readl (S3C2410_CLKCON ) & ~S3C2410_CLKCON_IDLE , -S3C2410_CLKCON ); -} -static void arch_idle (void ) { -if (s3c24xx_idle !=NULL ) - (s3c24xx_idle)(); -else -s3c24xx_default_idle (); }#include <mach/system-reset.h>
arch/arm/mach-s3c2412/s3c2412.c +2 -2
@@ -33,7 +33,6 @@#include <asm/irq.h> #include <mach/reset.h> -#include <mach/idle.h> #include <plat/cpu-freq.h>
@@ -129,6 +128,7 @@ static void s3c2412_idle(void)__raw_writel (tmp,S3C2412_PWRCFG );cpu_do_idle (); +local_irq_enable (); }static void s3c2412_hard_reset (void )
@@ -162,7 +162,7 @@ void __init s3c2412_map_io(void)/* set our idle function */ - s3c24xx_idle = s3c2412_idle; + pm_idle = s3c2412_idle;/* set custom reset hook */
arch/arm/mach-s3c2416/s3c2416.c +0 -2
@@ -45,7 +45,6 @@#include <asm/irq.h> #include <mach/reset.h> -#include <mach/idle.h> #include <mach/regs-s3c2443-clock.h> #include <plat/gpio-core.h>
@@ -85,7 +84,6 @@ int __init s3c2416_init(void)printk (KERN_INFO "S3C2416: Initializing architecture\n" ); s3c24xx_reset_hook = s3c2416_hard_reset; -/* s3c24xx_idle = s3c2416_idle; */ /* change WDT IRQ number */ s3c_device_wdt.resource[1 ].start =IRQ_S3C2443_WDT ;
arch/arm/plat-s3c24xx/cpu.c +30 -0
@@ -192,6 +192,35 @@ static unsigned long s3c24xx_read_idcode_v4(void)return __raw_readl (S3C2410_GSTATUS1 ); } +static void s3c24xx_default_idle (void ) +{ +unsigned long tmp; +int i; + +/* idle the system by using the idle mode which will wait for an +* interrupt to happen before restarting the system. +*/ + +/* Warning: going into idle state upsets jtag scanning */ + +__raw_writel (__raw_readl (S3C2410_CLKCON ) |S3C2410_CLKCON_IDLE , +S3C2410_CLKCON ); + +/* the samsung port seems to do a loop and then unset idle.. */ +for (i =0 ; i <50 ; i++) { + tmp +=__raw_readl (S3C2410_CLKCON );/* ensure loop not optimised out */ + } + +/* this bit is not cleared on re-start... */ + +__raw_writel (__raw_readl (S3C2410_CLKCON ) & ~S3C2410_CLKCON_IDLE , +S3C2410_CLKCON ); + +/* return with IRQs enabled */ +local_irq_enable (); +} + +/* Hook for arm_pm_restart to ensure we execute the reset code * with the caches enabled. It seems@least the S3C2440 has a problem * resetting if there is bus activity interrupted by the reset.
@@ -227,6 +256,7 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) idcode =s3c24xx_read_idcode_v4 (); } + pm_idle = s3c24xx_default_idle; arm_pm_restart = s3c24xx_pm_restart;s3c_init_cpu (idcode, cpu_ids,ARRAY_SIZE (cpu_ids));
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 10/12 ARM: mach-shark: properly disable CPU idle call
In reply to Nicolas Pitre--- arch/arm/mach-shark/core.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
arch/arm/mach-shark/core.c +6 -0
@@ -150,11 +150,17 @@ static struct sys_timer shark_timer = { .init = shark_timer_init, }; +static void shark_init_irq (void ) +{ +disable_hlt (); +} +MACHINE_START (SHARK ,"Shark" )/* Maintainer: Alexander Schulz */ .atag_offset = 0x3000, .map_io = shark_map_io, .init_irq = shark_init_irq, + .init_machine = shark_init_machine, .timer = &shark_timer, .dma_zone_size =SZ_4M ,MACHINE_END
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 11/12 ARM: mach-w90x900: properly disable CPU idle call
In reply to Nicolas Pitre--- arch/arm/mach-w90x900/dev.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/mach-w90x900/dev.c +1 -0
@@ -534,5 +534,6 @@ void __init nuc900_board_init(struct platform_device **device, int size)platform_add_devices (nuc900_public_dev,ARRAY_SIZE (nuc900_public_dev));spi_register_board_info (nuc900_spi_board_info,ARRAY_SIZE (nuc900_spi_board_info)); +disable_hlt (); }
Signature · 1 line
1.7.7.1.431.g10b2a
PATCH 12/12 ARM: imx: move special idle code to proper out-of-line pm_idle hooks
In reply to Nicolas Pitre--- arch/arm/mach-imx/Makefile | 4 +- arch/arm/mach-imx/idle-mx3.c | 31 +++++++++++++++++++++++++++++ arch/arm/mach-imx/mm-imx31.c | 1 + arch/arm/mach-imx/mm-imx35.c | 1 + arch/arm/mach-mx5/clock-mx51-mx53.c | 7 ++++++ arch/arm/plat-mxc/include/mach/system.h | 33 +------------------------------ 6 files changed, 43 insertions(+), 34 deletions(-) create mode 100644 arch/arm/mach-imx/idle-mx3.c
arch/arm/mach-imx/Makefile +2 -2
@@ -8,8 +8,8 @@ obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o ehci-imx25.o obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx31.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o -obj-$(CONFIG_SOC_IMX35) += mm-imx35.o cpu-imx35.o clock-imx35.o ehci-imx35.o +obj-$(CONFIG_SOC_IMX31) += mm-imx31.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o idle-mx3.o +obj-$(CONFIG_SOC_IMX35) += mm-imx35.o cpu-imx35.o clock-imx35.o ehci-imx35.o idle-mx3.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o # Support for CMOS sensor interface
arch/arm/mach-imx/idle-mx3.c new file +31 -0
@@ -0,0 +1,31 @@ +#include <mach/hardware.h> +#include <mach/common.h> + +void mx3_idle (void ) +{ +/* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */ +unsigned long reg =0 ; + __asm__ __volatile__( +/* disable I and D cache */ +"mrc p15, 0, %0, c1, c0, 0\n" +"bic %0, %0, #0x00001000\n" +"bic %0, %0, #0x00000004\n" +"mcr p15, 0, %0, c1, c0, 0\n" +/* invalidate I cache */ +"mov %0, #0\n" +"mcr p15, 0, %0, c7, c5, 0\n" +/* clear and invalidate D cache */ +"mov %0, #0\n" +"mcr p15, 0, %0, c7, c14, 0\n" +/* WFI */ +"mov %0, #0\n" +"mcr p15, 0, %0, c7, c0, 4\n" +"nop\n" "nop\n" "nop\n" "nop\n" +"nop\n" "nop\n" "nop\n" +/* enable I and D cache */ +"mrc p15, 0, %0, c1, c0, 0\n" +"orr %0, %0, #0x00001000\n" +"orr %0, %0, #0x00000004\n" +"mcr p15, 0, %0, c1, c0, 0\n" + :"=r" (reg)); +}
arch/arm/mach-imx/mm-imx31.c +1 -0
@@ -51,6 +51,7 @@ void __init imx31_init_early(void) {mxc_set_cpu_type (MXC_CPU_MX31 );mxc_arch_reset_init (MX31_IO_ADDRESS (MX31_WDOG_BASE_ADDR )); + pm_idle = mx3_idle; }void __init mx31_init_irq (void )
arch/arm/mach-imx/mm-imx35.c +1 -0
@@ -48,6 +48,7 @@ void __init imx35_init_early(void)mxc_set_cpu_type (MXC_CPU_MX35 );mxc_iomux_v3_init (MX35_IO_ADDRESS (MX35_IOMUXC_BASE_ADDR ));mxc_arch_reset_init (MX35_IO_ADDRESS (MX35_WDOG_BASE_ADDR )); + pm_idle = mx3_idle; }void __init mx35_init_irq (void )
arch/arm/mach-mx5/clock-mx51-mx53.c +7 -0
@@ -1529,6 +1529,11 @@ static void clk_tree_init(void)__raw_writel (reg,MXC_CCM_CBCDR ); } +static void mx51_idle (void ) +{ +mx5_cpu_lp_set (WAIT_UNCLOCKED_POWER_OFF ); +} +int __init mx51_clocks_init (unsigned long ckil,unsigned long osc,unsigned long ckih1,unsigned long ckih2) {
@@ -1569,6 +1574,8 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,/* System timer */ mxc_timer_init (&gpt_clk,MX51_IO_ADDRESS (MX51_GPT1_BASE_ADDR ),MX51_MXC_INT_GPT ); + + pm_idle = mx51_idle;return 0 ; }
arch/arm/plat-mxc/include/mach/system.h +1 -32
@@ -20,40 +20,9 @@#include <mach/hardware.h> #include <mach/common.h> -extern void mx5_cpu_lp_set (enum mxc_cpu_pwr_mode mode); -static inline void arch_idle (void ) { -/* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */ -if (cpu_is_mx31 () ||cpu_is_mx35 ()) { -unsigned long reg =0 ; - __asm__ __volatile__( -/* disable I and D cache */ -"mrc p15, 0, %0, c1, c0, 0\n" -"bic %0, %0, #0x00001000\n" -"bic %0, %0, #0x00000004\n" -"mcr p15, 0, %0, c1, c0, 0\n" -/* invalidate I cache */ -"mov %0, #0\n" -"mcr p15, 0, %0, c7, c5, 0\n" -/* clear and invalidate D cache */ -"mov %0, #0\n" -"mcr p15, 0, %0, c7, c14, 0\n" -/* WFI */ -"mov %0, #0\n" -"mcr p15, 0, %0, c7, c0, 4\n" -"nop\n" "nop\n" "nop\n" "nop\n" -"nop\n" "nop\n" "nop\n" -/* enable I and D cache */ -"mrc p15, 0, %0, c1, c0, 0\n" -"orr %0, %0, #0x00001000\n" -"orr %0, %0, #0x00000004\n" -"mcr p15, 0, %0, c1, c0, 0\n" - :"=r" (reg)); - }else if (cpu_is_mx51 ()) -mx5_cpu_lp_set (WAIT_UNCLOCKED_POWER_OFF ); -else -cpu_do_idle (); +cpu_do_idle (); }void arch_reset (char mode,const char *cmd);
Signature · 1 line
1.7.7.1.431.g10b2a
Sascha Hauer
maintainerPATCH 12/12 ARM: imx: move special idle code to proper out-of-line pm_idle hooks
Nico,
Quoted 10 lines · Nicolas Pitre
Signed-off-by Nicolas Pitre <[email protected]>--- arch/arm/mach-imx/Makefile | 4 +- arch/arm/mach-imx/idle-mx3.c | 31 +++++++++++++++++++++++++++++ arch/arm/mach-imx/mm-imx31.c | 1 + arch/arm/mach-imx/mm-imx35.c | 1 + arch/arm/mach-mx5/clock-mx51-mx53.c | 7 ++++++ arch/arm/plat-mxc/include/mach/system.h | 33 +------------------------------ 6 files changed, 43 insertions(+), 34 deletions(-) create mode 100644 arch/arm/mach-imx/idle-mx3.c
Please fold the following in this patch. It fixes the compile errors in mx3_defconfig and mx51_defconfig. Also, we implemented arch_idle and now with your patch pm_idle, thus we have to call local_irq_enable().
With this:
on i.MX35, i.MX51 and i.MX27
commit 380c365d85af17d7c4bac5f0db961986fbb7f40d
Author: Sascha Hauer <[email protected]> Date: Mon Oct 24 14:26:20 2011 +0200
Fix compile and runtime errors introduced with last commit
arch/arm/mach-imx/idle-mx3.c +2 -0
@@ -28,4 +28,6 @@ void mx3_idle(void) "orr %0, %0, #0x00000004\n" "mcr p15, 0, %0, c1, c0, 0\n" : "=r" (reg)); + +local_irq_enable (); }
arch/arm/mach-mx5/clock-mx51-mx53.c +4 -0
@@ -15,12 +15,14 @@#include <linux/clk.h> #include <linux/io.h> #include <linux/clkdev.h> +#include <linux/pm.h> #include <asm/div64.h> #include <mach/hardware.h> #include <mach/common.h> #include <mach/clock.h> +#include <mach/system.h> #include "crm_regs.h"
@@ -1532,6 +1534,8 @@ static void clk_tree_init(void)static void mx51_idle (void ) {mx5_cpu_lp_set (WAIT_UNCLOCKED_POWER_OFF ); + +local_irq_enable (); } int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
arch/arm/plat-mxc/include/mach/mx3x.h +3 -0
@@ -203,6 +203,9 @@ static inline int mx35_revision(void) {return mx35_cpu_rev; } + +void mx3_idle (void ); +#endif #endif /* ifndef __MACH_MX3x_H__ */
arch/arm/plat-mxc/include/mach/system.h +2 -0
@@ -20,6 +20,8 @@#include <mach/hardware.h> #include <mach/common.h> +extern void mx5_cpu_lp_set (enum mxc_cpu_pwr_mode mode); +static inline void arch_idle (void ) {cpu_do_idle ();
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
cover step towards removal of mach/system.h
In reply to Nicolas PitreHi Nico,
Quoted 5 lines · Nicolas Pitre
In the spirit of eventually being able to boot a single zImage on multiple SOCs, we need to get rid of
mach/system.h. This file mainly contains two inline functions that should be out-of-line and assigned to the existing global hooks at run time. Those functions arearch_idle()andarch_reset(). The following series only address the former.
I'm looking at the latter, but I'm losing the will to live in the process.
Quoted 4 lines
[PATCH 01/12] ARM: clean up idle handlers
[PATCH 02/12] ARM: mach-at91: move special idle code to a [PATCH 03/12] ARM: mach-clps711x: move special idle code to a [PATCH 04/12] ARM: mach-ebsa110: move special idle code to a
Quoted 8 lines
[PATCH 05/12] ARM: mach-gemini: move special idle code to a [PATCH 06/12] ARM: mach-h720x: move special idle code to a [PATCH 07/12] ARM: mach-ixp23xx: properly disable CPU idle call [PATCH 08/12] ARM: mach-ixp4xx: properly disable CPU idle call [PATCH 09/12] ARM: s3c24xx: move special idle code to a proper [PATCH 10/12] ARM: mach-shark: properly disable CPU idle call [PATCH 11/12] ARM: mach-w90x900: properly disable CPU idle call [PATCH 12/12] ARM: imx: move special idle code to proper out-of-line
I think you might need to hack on mach-msm too as they have an implementation of arch_idle which is written in assembly (for reasons which aren't obvious to me).
Will