restart cleanups
Subsystems (13)
cover restart cleanups
This series cleans up some of the restart code for ARM. It doesn't go as far as Will's patch set (or even anywhere close to it) mainly because of the poor state of the various implementations in various platforms.
Effectively, the various platforms themselves stand in the way of optimal cleanup of this code.
We already have a function pointer to allow the restart to be hooked at runtime - it's called arm_pm_restart().
What a lot of platforms use this for is to intercept the restart call, do something, and then continue on by calling arm_machine_restart().
One platform (mioa701) in particular thinks its a good idea to call functions like gpio_free() and free_irq() from here. This is soo far from reality its untrue; the restart paths can be called from _any_ context including IRQ context. This alone effectively stands in the way of moving the IRQ disables before the call to arm_pm_restart().
Other platforms use arm_pm_restart() to intercept the restart, and force the mode to 'g', 'h' or 's'. As the mode already defaults to 'h' I don't understand why people felt forcing it in that case was necessary. As for the 's' case, this can be done by merely specifying ".soft_reboot = 1" in the machine record. We can solve the 'g' case by changing .soft_reboot to be a char "restart_mode" argument which sets the default restart mode.
Although I have a patch (not published as part of this series) which makes that change, I've found it less than useful for getting rid of some of the intercept crap because of other games platforms play in there (like writing magic values to registers.)
Essentially, we want to move to a state where arm_pm_restart() is _the_ hook for platforms to insert their restart code into, with the default function being a no-op. All platforms which want to have working restart support then have to insert their restart code into this hook.
So, this patch set takes us a little way there by cleaning up some of the restart code:
1. remove the useless argument to setup_mm_for_reboot()
2. remove the silly indirection in AT91 code and do this like other platforms do.
3. remove any local_irq_disable() calls inside arch_reset() because this is already the case.
4. factor out the code which fiddles with the MMU tables.
5. provide (and use) a function for soft rebooting which includes the setup of the MMU tables and call cpu_reset() - and remove the MMU setup from the code paths before arch_reset() is called.
PATCH 1/5 ARM: restart: remove argument to setup_mm_for_reboot()
setup_mm_for_reboot() doesn't make use of its argument, so remove it.
--- arch/arm/kernel/machine_kexec.c | 4 ++-- arch/arm/kernel/process.c | 4 ++-- arch/arm/mm/idmap.c | 2 +- arch/arm/mm/nommu.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)
arch/arm/kernel/machine_kexec.c +2 -2
@@ -16,7 +16,7 @@extern const unsigned char relocate_new_kernel[];extern const unsigned int relocate_new_kernel_size; -extern void setup_mm_for_reboot (char mode); +extern void setup_mm_for_reboot (void );extern unsigned long kexec_start_address;extern unsigned long kexec_indirection_page;
@@ -114,7 +114,7 @@ void machine_kexec(struct kimage *image)kexec_reinit ();local_irq_disable ();local_fiq_disable (); -setup_mm_for_reboot (0 );/* mode is not used, so just pass 0*/ +setup_mm_for_reboot ();/* mode is not used, so just pass 0*/ flush_cache_all ();outer_flush_all ();outer_disable ();
arch/arm/kernel/process.c +2 -2
@@ -57,7 +57,7 @@ static const char *isa_modes[] = { "ARM" , "Thumb" , "Jazelle", "ThumbEE" }; -extern void setup_mm_for_reboot (char mode); +extern void setup_mm_for_reboot (void );static volatile int hlt_counter;
@@ -103,7 +103,7 @@ void arm_machine_restart(char mode, const char *cmd)* we may need it to insert some 1:1 mappings so that * soft boot works. */ -setup_mm_for_reboot (mode); +setup_mm_for_reboot ();/* Clean and invalidate caches */ flush_cache_all ();
arch/arm/mm/idmap.c +1 -1
@@ -78,7 +78,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)* the user-mode pages. This will then ensure that we have predictable * results when turning the mmu off */ -void setup_mm_for_reboot (char mode) +void setup_mm_for_reboot (void ) {/* * We need to access to user-mode page tables here. For kernel threads
arch/arm/mm/nommu.c +1 -1
@@ -43,7 +43,7 @@ void __init paging_init(struct machine_desc *mdesc)/* * We don't need to do anything here for nommu machines. */ -void setup_mm_for_reboot (char mode) +void setup_mm_for_reboot (void ) { }
Signature · 1 line
1.7.4.4
PATCH 1/5 ARM: restart: remove argument to setup_mm_for_reboot()
Quoted 24 lines · Russell King - ARM Linux
setup_mm_for_reboot()doesn't make use of its argument, so remove it.Signed-off-by Russell King <[email protected]>--- arch/arm/kernel/machine_kexec.c | 4 ++-- arch/arm/kernel/process.c | 4 ++-- arch/arm/mm/idmap.c | 2 +- arch/arm/mm/nommu.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)arch/arm/kernel/machine_kexec.c +1
-1@@ -16,7 +16,7 @@extern const unsigned char relocate_new_kernel[];extern const unsigned int relocate_new_kernel_size; -extern void setup_mm_for_reboot (char mode); +extern void setup_mm_for_reboot (void );extern unsigned long kexec_start_address;extern unsigned long kexec_indirection_page;
arch/arm/kernel/machine_kexec.c void machine_kexec(struct kimage *image) · line 117
Quoted 5 lines
arch/arm/kernel/machine_kexec.c +1
-1@@ -114,7 +114,7 @@ void machine_kexec(struct kimage *image)kexec_reinit ();local_irq_disable ();local_fiq_disable (); -setup_mm_for_reboot (0 );/* mode is not used, so just pass 0*/ +setup_mm_for_reboot ();/* mode is not used, so just pass 0*/
The comment should get removed now also.
~Ryan
PATCH 1/5 ARM: restart: remove argument to setup_mm_for_reboot()
Quoted 1 line · Ryan Mallon
The comment should get removed now also.
Thanks, it'll be gone for the next posting of these patches.
PATCH 2/5 ARM: restart: get rid of needless at91_arch_reset additional indirection
In reply to Russell King - ARM LinuxWe don't need an additional level of indirection here, we can just turn arch_reset into a function pointer directly and assign the appropriate function (with appropriate arguments to it) just like other platforms do.
--- arch/arm/mach-at91/at91cap9.c | 4 ++-- arch/arm/mach-at91/at91rm9200.c | 4 ++-- arch/arm/mach-at91/at91sam9260.c | 2 +- arch/arm/mach-at91/at91sam9261.c | 2 +- arch/arm/mach-at91/at91sam9263.c | 2 +- arch/arm/mach-at91/at91sam9g45.c | 4 ++-- arch/arm/mach-at91/at91sam9rl.c | 2 +- arch/arm/mach-at91/generic.h | 2 +- arch/arm/mach-at91/include/mach/system.h | 9 +-------- 9 files changed, 12 insertions(+), 19 deletions(-)
arch/arm/mach-at91/at91cap9.c +2 -2
@@ -311,7 +311,7 @@ static struct at91_gpio_bank at91cap9_gpio[] = { } }; -static void at91cap9_reset (void ) +static void at91cap9_reset (char mode,const char *cmd) {at91_sys_write (AT91_RSTC_CR ,AT91_RSTC_KEY |AT91_RSTC_PROCRST |AT91_RSTC_PERRST ); }
@@ -333,7 +333,7 @@ static void __init at91cap9_map_io(void)static void __init at91cap9_initialize (void ) { - at91_arch_reset = at91cap9_reset; + 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 +2 -2
@@ -286,7 +286,7 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; -static void at91rm9200_reset (void ) +static void at91rm9200_reset (char mode,const char *cmd) {/* * Perform a hardware reset with the use of the Watchdog timer.
@@ -307,7 +307,7 @@ static void __init at91rm9200_map_io(void)static void __init at91rm9200_initialize (void ) { - at91_arch_reset = at91rm9200_reset; + arch_reset = at91rm9200_reset; at91_extern_irq = (1 <<AT91RM9200_ID_IRQ0 ) | (1 <<AT91RM9200_ID_IRQ1 ) | (1 <<AT91RM9200_ID_IRQ2 ) | (1 <<AT91RM9200_ID_IRQ3 ) | (1 <<AT91RM9200_ID_IRQ4 ) | (1 <<AT91RM9200_ID_IRQ5 )
arch/arm/mach-at91/at91sam9260.c +1 -1
@@ -317,7 +317,7 @@ static void __init at91sam9260_map_io(void)static void __init at91sam9260_initialize (void ) { - at91_arch_reset = at91sam9_alt_reset; + arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 <<AT91SAM9260_ID_IRQ0 ) | (1 <<AT91SAM9260_ID_IRQ1 ) | (1 <<AT91SAM9260_ID_IRQ2 );
arch/arm/mach-at91/at91sam9261.c +1 -1
@@ -286,7 +286,7 @@ static void __init at91sam9261_map_io(void)static void __init at91sam9261_initialize (void ) { - at91_arch_reset = at91sam9_alt_reset; + arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 <<AT91SAM9261_ID_IRQ0 ) | (1 <<AT91SAM9261_ID_IRQ1 ) | (1 <<AT91SAM9261_ID_IRQ2 );
arch/arm/mach-at91/at91sam9263.c +1 -1
@@ -303,7 +303,7 @@ static void __init at91sam9263_map_io(void)static void __init at91sam9263_initialize (void ) { - at91_arch_reset = at91sam9_alt_reset; + 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 +2 -2
@@ -301,7 +301,7 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { } }; -static void at91sam9g45_reset (void ) +static void at91sam9g45_reset (char mode,const char *cmd) {at91_sys_write (AT91_RSTC_CR ,AT91_RSTC_KEY |AT91_RSTC_PROCRST |AT91_RSTC_PERRST ); }
@@ -323,7 +323,7 @@ static void __init at91sam9g45_map_io(void)static void __init at91sam9g45_initialize (void ) { - at91_arch_reset = at91sam9g45_reset; + arch_reset = at91sam9g45_reset; pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 <<AT91SAM9G45_ID_IRQ0 );
arch/arm/mach-at91/at91sam9rl.c +1 -1
@@ -292,7 +292,7 @@ static void __init at91sam9rl_map_io(void)static void __init at91sam9rl_initialize (void ) { - at91_arch_reset = at91sam9_alt_reset; + arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 <<AT91SAM9RL_ID_IRQ0 );
arch/arm/mach-at91/generic.h +1 -1
@@ -57,7 +57,7 @@ extern void at91_irq_suspend(void);extern void at91_irq_resume (void );/* reset */ -extern void at91sam9_alt_reset (void ); +extern void at91sam9_alt_reset (char ,const char *);/* GPIO */ #define AT91RM9200_PQFP 3/* AT91RM9200 PQFP package has 3 banks */
arch/arm/mach-at91/include/mach/system.h +1 -8
@@ -47,13 +47,6 @@ static inline void arch_idle(void) #endif } -void (*at91_arch_reset)(void ); - -static inline void arch_reset (char mode,const char *cmd) -{ -/* call the CPU-specific reset function */ -if (at91_arch_reset) - (at91_arch_reset)(); -} +void (*arch_reset)(char mode,const char *cmd);#endif
Signature · 1 line
1.7.4.4
PATCH 3/5 ARM: restart: remove local_irq_disable() from within arch_reset()
In reply to Russell King - ARM LinuxIRQs are already disabled by the time arch_reset() is called, so these calls to local_irq_disable() instead arch_reset() are redundant. Remove them.
The following spatch was used:
@ rule1 @ identifier fn; @@arch_reset = fn;
@@ identifier rule1.fn, m, c; @@
void fn(char m, const char *c)
{
<... when != local_irq_enable
-local_irq_disable();
...>
}
@@ identifier m, c; @@arch_reset(char m, const char *c)
{
<... when != local_irq_enable
-local_irq_disable();
...>
}
--- arch/arm/mach-ep93xx/include/mach/system.h | 2 -- arch/arm/mach-iop32x/include/mach/system.h | 2 -- arch/arm/mach-ixp2000/include/mach/system.h | 2 -- arch/arm/mach-lpc32xx/include/mach/system.h | 3 --- arch/arm/mach-shark/core.c | 1 - arch/arm/mach-u300/include/mach/system.h | 1 - 6 files changed, 0 insertions(+), 11 deletions(-)
arch/arm/mach-ep93xx/include/mach/system.h +0 -2
@@ -11,8 +11,6 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -local_irq_disable (); -/* * Set then clear the SWRST bit to initiate a software reset */
arch/arm/mach-iop32x/include/mach/system.h +0 -2
@@ -18,8 +18,6 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -local_irq_disable (); -if (machine_is_n2100 ()) {gpio_line_set (N2100_HARDWARE_RESET ,GPIO_LOW );gpio_line_config (N2100_HARDWARE_RESET ,GPIO_OUT );
arch/arm/mach-ixp2000/include/mach/system.h +0 -2
@@ -19,8 +19,6 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -local_irq_disable (); -/* * Reset flash banking register so that we are pointing at * RedBoot bank.
arch/arm/mach-lpc32xx/include/mach/system.h +0 -3
@@ -33,9 +33,6 @@ static inline void arch_reset(char mode, const char *cmd)case 'h' :printk (KERN_CRIT "RESET: Rebooting system\n" ); -/* Disable interrupts */ -local_irq_disable (); -lpc32xx_watchdog_reset ();break ;
arch/arm/mach-shark/core.c +0 -1
@@ -29,7 +29,6 @@void arch_reset (char mode,const char *cmd) {short temp; -local_irq_disable ();/* Reset the Machine via pc[3] of the sequoia chipset */ outw (0x09 ,0x24 ); temp=inw (0x26 );
arch/arm/mach-u300/include/mach/system.h +0 -1
@@ -28,7 +28,6 @@ static void arch_reset(char mode, const char *cmd)case 'h' :printk (KERN_CRIT "RESET: shutting down/rebooting system\n" );/* Disable interrupts */ -local_irq_disable ();#ifdef CONFIG_COH901327_WATCHDOG coh901327_watchdog_reset ();#endif
Signature · 1 line
1.7.4.4
PATCH 3/5 ARM: restart: remove local_irq_disable() from within arch_reset()
Quoted 28 lines · Russell King
IRQs are already disabled by the time
arch_reset()is called, so these calls tolocal_irq_disable()insteadarch_reset()are redundant. Remove them.The following spatch was used:
@ rule1 @ identifier fn; @@arch_reset= fn;@@ identifier rule1.fn, m, c; @@
voidfn(char m, const char *c)
{
<... when !=local_irq_enable
-local_irq_disable();
...>
}@@ identifier m, c; @@
arch_reset(char m, const char *c)
{
<... when !=local_irq_enable
-local_irq_disable();
...>
}Signed-off-by Russell King <[email protected]>--- arch/arm/mach-ep93xx/include/mach/system.h | 2 --
[...]
arch/arm/mach-ep93xx/include/mach/system.h static inline void arch_idle(void) · line 16
Quoted 13 lines
arch/arm/mach-ep93xx/include/mach/system.h +0
-2@@ -11,8 +11,6 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -local_irq_disable (); -/* * Set then clear the SWRST bit to initiate a software reset */
For ep93xx.
PATCH 3/5 ARM: restart: remove local_irq_disable() from within arch_reset()
Quoted 16 lines · H Hartley Sweeten
arch/arm/mach-ep93xx/include/mach/system.h static inline void arch_idle(void) · line 16
Quoted 13 lines
arch/arm/mach-ep93xx/include/mach/system.h +0
-2@@ -11,8 +11,6 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -local_irq_disable (); -/* * Set then clear the SWRST bit to initiate a software reset */ For ep93xx.
Quoted 1 line
Thanks. I noticed that u300 had a comment which should've been deleted, so I've also done that and removed the spatch from the commit log (as it no longer reflects the patch.)
PATCH 4/5 ARM: restart: turn reboot setup code into a library function
In reply to Russell King - ARM LinuxMove the failure to reboot into machine_restart() to always catch this condition, and turn the bulk of arm_machine_restart() which is required for soft-reboot modes into a library call.
This allows everyone to hook into the restart via the same method via arm_pm_restart() irrespective of what they want, and if they want the old 'arch_reset' way, call setup_restart() themselves.
--- arch/arm/kernel/process.c | 35 +++++++++++++++++++---------------- 1 files changed, 19 insertions(+), 16 deletions(-)
arch/arm/kernel/process.c +19 -16
@@ -92,12 +92,8 @@ static int __init hlt_setup(char *__unused)__setup ("nohlt" , nohlt_setup);__setup ("hlt" , hlt_setup); -void arm_machine_restart (char mode,const char *cmd) +static void setup_restart (void ) { -/* Disable interrupts first */ -local_irq_disable (); -local_fiq_disable (); -/* * Tell the mm system that we are going to reboot - * we may need it to insert some 1:1 mappings so that
@@ -113,19 +109,18 @@ void arm_machine_restart(char mode, const char *cmd)/* Push out any further dirty data, and ensure cache is empty */ flush_cache_all (); +} -/* -* Now call the architecture specific reboot code. -*/ -arch_reset (mode, cmd); +void arm_machine_restart (char mode,const char *cmd) +{ +/* Disable interrupts first */ +local_irq_disable (); +local_fiq_disable (); -/* -* Whoops - the architecture was unable to reboot. -* Tell the user! -*/ -mdelay (1000 ); -printk ("Reboot failed -- System halted\n" ); -while (1 ); +setup_restart (); + +/* Now call the architecture specific reboot code. */ +arch_reset (mode, cmd); }/*
@@ -250,7 +245,15 @@ void machine_power_off(void)void machine_restart (char *cmd) {machine_shutdown (); +arm_pm_restart (reboot_mode, cmd); + +/* Give a grace period for failure to restart of 1s */ +mdelay (1000 ); + +/* Whoops - the platform was unable to reboot. Tell the user! */ +printk ("Reboot failed -- System halted\n" ); +while (1 ); }void __show_regs (struct pt_regs *regs)
Signature · 1 line
1.7.4.4
PATCH 5/5 ARM: restart: only perform setup for restart when soft-restarting
In reply to Russell King - ARM LinuxWe only need to set the system up for a soft-restart if we're going to be doing a soft-restart. Provide a new function (soft_restart()) which does the setup and final call for this, and make platforms use it. Eliminate the call to setup_restart() from the default handler.
This means that platforms arch_reset() function is no longer called with the page tables prepared for a soft-restart, and caches will still be enabled.
--- arch/arm/include/asm/system.h | 1 + arch/arm/kernel/process.c | 10 +++++++--- arch/arm/mach-clps711x/include/mach/system.h | 2 +- arch/arm/mach-ebsa110/include/mach/system.h | 2 +- arch/arm/mach-footbridge/include/mach/system.h | 2 +- arch/arm/mach-iop32x/include/mach/system.h | 2 +- arch/arm/mach-iop33x/include/mach/system.h | 2 +- arch/arm/mach-ixp4xx/include/mach/system.h | 2 +- arch/arm/mach-ks8695/include/mach/system.h | 2 +- arch/arm/mach-mmp/include/mach/system.h | 4 ++-- arch/arm/mach-mxs/system.c | 2 +- arch/arm/mach-nuc93x/include/mach/system.h | 2 +- arch/arm/mach-pnx4008/include/mach/system.h | 2 +- arch/arm/mach-pxa/reset.c | 2 +- arch/arm/mach-rpc/include/mach/system.h | 2 +- arch/arm/mach-s3c2410/include/mach/system-reset.h | 4 ++-- arch/arm/mach-s3c64xx/include/mach/system.h | 2 +- arch/arm/mach-sa1100/include/mach/system.h | 2 +- arch/arm/mach-shmobile/include/mach/system.h | 2 +- arch/arm/mach-w90x900/include/mach/system.h | 2 +- arch/arm/plat-mxc/system.c | 2 +- arch/arm/plat-spear/include/plat/system.h | 2 +- 22 files changed, 30 insertions(+), 25 deletions(-)
arch/arm/include/asm/system.h +1 -0
@@ -101,6 +101,7 @@ extern int __pure cpu_architecture(void);extern void cpu_init (void );void arm_machine_restart (char mode,const char *cmd); +void soft_restart (unsigned long );extern void (*arm_pm_restart)(char str,const char *cmd);#define UDBG_UNDEFINED (1 << 0)
arch/arm/kernel/process.c +7 -3
@@ -111,15 +111,19 @@ static void setup_restart(void)flush_cache_all (); } +void soft_restart (unsigned long addr) +{ +setup_restart (); +cpu_reset (addr); +} +void arm_machine_restart (char mode,const char *cmd) {/* Disable interrupts first */ local_irq_disable ();local_fiq_disable (); -setup_restart (); - -/* Now call the architecture specific reboot code. */ +/* Call the architecture specific reboot code. */ arch_reset (mode, cmd); }
arch/arm/mach-clps711x/include/mach/system.h +1 -1
@@ -34,7 +34,7 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -cpu_reset (0 ); +soft_restart (0 ); }#endif
arch/arm/mach-ebsa110/include/mach/system.h +1 -1
@@ -34,6 +34,6 @@ static inline void arch_idle(void) asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); } -#define arch_reset (mode, cmd) cpu_reset(0x80000000) +#define arch_reset (mode, cmd) soft_restart(0x80000000)#endif
arch/arm/mach-footbridge/include/mach/system.h +1 -1
@@ -24,7 +24,7 @@ static inline void arch_reset(char mode, const char *cmd)/* * Jump into the ROM */ -cpu_reset (0x41000000 ); +soft_restart (0x41000000 ); }else {if (machine_is_netwinder ()) {/* open up the SuperIO chip
arch/arm/mach-iop32x/include/mach/system.h +1 -1
@@ -28,5 +28,5 @@ static inline void arch_reset(char mode, const char *cmd) *IOP3XX_PCSR =0x30 ;/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }
arch/arm/mach-iop33x/include/mach/system.h +1 -1
@@ -19,5 +19,5 @@ static inline void arch_reset(char mode, const char *cmd) *IOP3XX_PCSR =0x30 ;/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }
arch/arm/mach-ixp4xx/include/mach/system.h +1 -1
@@ -26,7 +26,7 @@ static inline void arch_reset(char mode, const char *cmd) {if (1 && mode =='s' ) {/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }else {/* Use on-chip reset capability */
arch/arm/mach-ks8695/include/mach/system.h +1 -1
@@ -32,7 +32,7 @@ static void arch_reset(char mode, const char *cmd)unsigned int reg;if (mode =='s' ) -cpu_reset (0 ); +soft_restart (0 );/* disable timer0 */ reg =__raw_readl (KS8695_TMR_VA +KS8695_TMCON );
arch/arm/mach-mmp/include/mach/system.h +2 -2
@@ -19,8 +19,8 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) {if (cpu_is_pxa168 ()) -cpu_reset (0xffff0000 ); +soft_restart (0xffff0000 );else -cpu_reset (0 ); +soft_restart (0 ); }#endif /* __ASM_MACH_SYSTEM_H */
arch/arm/mach-mxs/system.c +1 -1
@@ -53,7 +53,7 @@ void arch_reset(char mode, const char *cmd)mdelay (50 );/* We'll take a jump through zero as a poor second */ -cpu_reset (0 ); +soft_restart (0 ); }static int __init mxs_arch_reset_init (void )
arch/arm/mach-nuc93x/include/mach/system.h +1 -1
@@ -23,6 +23,6 @@ static void arch_idle(void)static void arch_reset (char mode,const char *cmd) { -cpu_reset (0 ); +soft_restart (0 ); }
arch/arm/mach-pnx4008/include/mach/system.h +1 -1
@@ -32,7 +32,7 @@ static void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -cpu_reset (0 ); +soft_restart (0 ); }#endif
arch/arm/mach-pxa/reset.c +1 -1
@@ -88,7 +88,7 @@ void arch_reset(char mode, const char *cmd)switch (mode) {case 's' :/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 );break ;case 'g' :do_gpio_reset ();
arch/arm/mach-rpc/include/mach/system.h +1 -1
@@ -23,5 +23,5 @@ static inline void arch_reset(char mode, const char *cmd)/* * Jump into the ROM */ -cpu_reset (0 ); +soft_restart (0 ); }
arch/arm/mach-s3c2410/include/mach/system-reset.h +2 -2
@@ -19,7 +19,7 @@ static void arch_reset(char mode, const char *cmd) {if (mode =='s' ) { -cpu_reset (0 ); +soft_restart (0 ); }if (s3c24xx_reset_hook)
@@ -28,5 +28,5 @@ arch_reset(char mode, const char *cmd)arch_wdt_reset ();/* we'll take a jump through zero as a poor second */ -cpu_reset (0 ); +soft_restart (0 ); }
arch/arm/mach-s3c64xx/include/mach/system.h +1 -1
@@ -24,7 +24,7 @@ static void arch_reset(char mode, const char *cmd)arch_wdt_reset ();/* if all else fails, or mode was for soft, jump to 0 */ - cpu_reset(0); + soft_restart(0); }#endif /* __ASM_ARCH_IRQ_H */
arch/arm/mach-sa1100/include/mach/system.h +1 -1
@@ -14,7 +14,7 @@ static inline void arch_reset(char mode, const char *cmd) {if (mode =='s' ) {/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }else {/* Use on-chip reset capability */ RSRR =RSRR_SWR ;
arch/arm/mach-shmobile/include/mach/system.h +1 -1
@@ -8,7 +8,7 @@ static inline void arch_idle(void)static inline void arch_reset (char mode,const char *cmd) { -cpu_reset (0 ); +soft_restart (0 ); }#endif
arch/arm/mach-w90x900/include/mach/system.h +1 -1
@@ -33,7 +33,7 @@ static void arch_reset(char mode, const char *cmd) {if (mode =='s' ) {/* Jump into ROM at address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }else {__raw_writel (WTE |WTRE |WTCLK ,WTCR ); }
arch/arm/plat-mxc/system.c +1 -1
@@ -67,7 +67,7 @@ void arch_reset(char mode, const char *cmd)mdelay (50 );/* we'll take a jump through zero as a poor second */ -cpu_reset (0 ); +soft_restart (0 ); }void mxc_arch_reset_init (void __iomem *base)
arch/arm/plat-spear/include/plat/system.h +1 -1
@@ -31,7 +31,7 @@ static inline void arch_reset(char mode, const char *cmd) {if (mode =='s' ) {/* software reset, Jump into ROM@address 0 */ -cpu_reset (0 ); +soft_restart (0 ); }else {/* hardware reset, Use on-chip reset capability */ sysctl_soft_reset ((void __iomem *)VA_SPEAR_SYS_CTRL_BASE );
Signature · 1 line
1.7.4.4
PATCH 5/5 ARM: restart: only perform setup for restart when soft-restarting
Hi Russell,
Quoted 26 lines · Russell King - ARM Linux
We only need to set the system up for a soft-restart if we're going to be doing a soft-restart. Provide a new function (
soft_restart()) which does the setup and final call for this, and make platforms use it. Eliminate the call tosetup_restart()from the default handler.This means that platforms
arch_reset()function is no longer called with the page tables prepared for a soft-restart, and caches will still be enabled.Signed-off-by Russell King <[email protected]>--- arch/arm/include/asm/system.h | 1 + arch/arm/kernel/process.c | 10 +++++++--- arch/arm/mach-clps711x/include/mach/system.h | 2 +- arch/arm/mach-ebsa110/include/mach/system.h | 2 +- arch/arm/mach-footbridge/include/mach/system.h | 2 +- arch/arm/mach-iop32x/include/mach/system.h | 2 +- arch/arm/mach-iop33x/include/mach/system.h | 2 +- arch/arm/mach-ixp4xx/include/mach/system.h | 2 +- arch/arm/mach-ks8695/include/mach/system.h | 2 +- arch/arm/mach-mmp/include/mach/system.h | 4 ++-- arch/arm/mach-mxs/system.c | 2 +- arch/arm/mach-nuc93x/include/mach/system.h | 2 +- arch/arm/mach-pnx4008/include/mach/system.h | 2 +- arch/arm/mach-pxa/reset.c | 2 +- arch/arm/mach-rpc/include/mach/system.h | 2 +-
Quoted 8 lines
arch/arm/mach-s3c2410/include/mach/system-reset.h | 4 ++-- arch/arm/mach-s3c64xx/include/mach/system.h | 2 +- arch/arm/mach-sa1100/include/mach/system.h | 2 +- arch/arm/mach-shmobile/include/mach/system.h | 2 +- arch/arm/mach-w90x900/include/mach/system.h | 2 +- arch/arm/plat-mxc/system.c | 2 +- arch/arm/plat-spear/include/plat/system.h | 2 +- 22 files changed, 30 insertions(+), 25 deletions(-)
Which branch is this patch taken against? I'm getting conflicts if I try to apply it against mainline, next, 3.1 or your devel branch.
Thanks,
Will
PATCH 5/5 ARM: restart: only perform setup for restart when soft-restarting
Quoted 38 lines · Will Deacon
Hi Russell,
Quoted 26 lines · Russell King - ARM Linux
We only need to set the system up for a soft-restart if we're going to be doing a soft-restart. Provide a new function (
soft_restart()) which does the setup and final call for this, and make platforms use it. Eliminate the call tosetup_restart()from the default handler.This means that platforms
arch_reset()function is no longer called with the page tables prepared for a soft-restart, and caches will still be enabled.Signed-off-by Russell King <[email protected]>--- arch/arm/include/asm/system.h | 1 + arch/arm/kernel/process.c | 10 +++++++--- arch/arm/mach-clps711x/include/mach/system.h | 2 +- arch/arm/mach-ebsa110/include/mach/system.h | 2 +- arch/arm/mach-footbridge/include/mach/system.h | 2 +- arch/arm/mach-iop32x/include/mach/system.h | 2 +- arch/arm/mach-iop33x/include/mach/system.h | 2 +- arch/arm/mach-ixp4xx/include/mach/system.h | 2 +- arch/arm/mach-ks8695/include/mach/system.h | 2 +- arch/arm/mach-mmp/include/mach/system.h | 4 ++-- arch/arm/mach-mxs/system.c | 2 +- arch/arm/mach-nuc93x/include/mach/system.h | 2 +- arch/arm/mach-pnx4008/include/mach/system.h | 2 +- arch/arm/mach-pxa/reset.c | 2 +- arch/arm/mach-rpc/include/mach/system.h | 2 +-Quoted 8 lines
arch/arm/mach-s3c2410/include/mach/system-reset.h | 4 ++-- arch/arm/mach-s3c64xx/include/mach/system.h | 2 +- arch/arm/mach-sa1100/include/mach/system.h | 2 +- arch/arm/mach-shmobile/include/mach/system.h | 2 +- arch/arm/mach-w90x900/include/mach/system.h | 2 +- arch/arm/plat-mxc/system.c | 2 +- arch/arm/plat-spear/include/plat/system.h | 2 +- 22 files changed, 30 insertions(+), 25 deletions(-)
Quoted 2 lines
Which branch is this patch taken against? I'm getting conflicts if I try to apply it against mainline, next, 3.1 or your devel branch.
It's at some random point during the merge window at the moment.
It's probably going to be a good idea to wait until after the merge window closes before tackling this stuff seriously, because things are still changing quite quickly - eg, we have new platforms merged last night which wouldn't have been updated with these patches.
I'd suggest not rushing this; we'll have a full 2-3 months before they can be merged into mainline.
PATCH 5/5 ARM: restart: only perform setup for restart when soft-restarting
Quoted 7 lines · Russell King - ARM Linux
It's probably going to be a good idea to wait until after the merge window closes before tackling this stuff seriously, because things are still changing quite quickly - eg, we have new platforms merged last night which wouldn't have been updated with these patches.
I'd suggest not rushing this; we'll have a full 2-3 months before they can be merged into mainline.
Sure, suits me - I have plenty of things to be getting on with.
Will
cover restart cleanups
In reply to Russell King - ARM LinuxCan someone please check whether this code:
/* Hook for arm_pm_restart to ensure we execute the reset code
* with the caches enabled. It seems at least the S3C2440 has a problem
* resetting if there is bus activity interrupted by the reset. */
static void s3c24xx_pm_restart(char mode, const char *cmd)
{
if (mode != 's') {
unsigned long flags;
local_irq_save(flags);
__cpuc_flush_kern_all();
__cpuc_flush_user_all();
arch_reset(mode, cmd);
local_irq_restore(flags);
}
/* fallback, or unhandled */
arm_machine_restart(mode, cmd);
}will be broken by any of these patches - and more importantly whether this code can simply be deleted with these five patches applied.
Thanks.
cover restart cleanups
Quoted 23 lines · Russell King - ARM Linux
Can someone please check whether this code:
/* Hook for
arm_pm_restartto ensure we execute the reset code
* with the caches enabled. It seems at least the S3C2440 has a problem
* resetting if there is bus activity interrupted by the reset. */
static voids3c24xx_pm_restart(char mode, const char *cmd){ if (mode != 's') { unsigned long flags; local_irq_save(flags); __cpuc_flush_kern_all(); __cpuc_flush_user_all(); arch_reset(mode, cmd); local_irq_restore(flags); } /* fallback, or unhandled */ arm_machine_restart(mode, cmd); }
Quoted 2 lines
will be broken by any of these patches - and more importantly whether this code can simply be deleted with these five patches applied.
Okay, I'm going to delete the above and hope for the best; I'm taking the lack of reply as meaning that no one in the Samsung community is that interested in this code.
cover restart cleanups
Quoted 25 lines · Russell King - ARM Linux
Quoted 23 lines · Russell King - ARM Linux
Can someone please check whether this code:
/* Hook for
arm_pm_restartto ensure we execute the reset code
* with the caches enabled. It seems at least the S3C2440 has a problem
* resetting if there is bus activity interrupted by the reset. */
static voids3c24xx_pm_restart(char mode, const char *cmd){ if (mode != 's') { unsigned long flags; local_irq_save(flags); __cpuc_flush_kern_all(); __cpuc_flush_user_all(); arch_reset(mode, cmd); local_irq_restore(flags); } /* fallback, or unhandled */ arm_machine_restart(mode, cmd); }
Quoted 6 lines
Quoted 2 lines
will be broken by any of these patches - and more importantly whether this code can simply be deleted with these five patches applied.
Okay, I'm going to delete the above and hope for the best; I'm taking the lack of reply as meaning that no one in the Samsung community is that interested in this code.
Russell,
Sorry for late response.
According to its commit message, it is needed...
[ARM] 4987/1: S3C24XX: Ensure watchdog reset initiated from cached code.
There seems to be some problem with at-least the S3C2440 and bus traffic during an reset. It is unlikely, but still possible that the system will hang in such a way that the watchdog cannot get the system out of the state it is in.
Change to making the code that calls the watchdog reset run from cached memory so that instruction fetches have quiesced before the watchdog fires.
But frankly, I'm not sure now and there is no S3C2440 on my desk :( Let me check again, if no response on this, please keep going on.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
cover restart cleanups
Quoted 45 lines · Kukjin Kim
Quoted 25 lines · Russell King - ARM Linux
Quoted 23 lines · Russell King - ARM Linux
Can someone please check whether this code:
/* Hook for
arm_pm_restartto ensure we execute the reset code
* with the caches enabled. It seems at least the S3C2440 has a problem
* resetting if there is bus activity interrupted by the reset. */
static voids3c24xx_pm_restart(char mode, const char *cmd){ if (mode != 's') { unsigned long flags; local_irq_save(flags); __cpuc_flush_kern_all(); __cpuc_flush_user_all(); arch_reset(mode, cmd); local_irq_restore(flags); } /* fallback, or unhandled */ arm_machine_restart(mode, cmd); }Quoted 6 lines
Quoted 2 lines
will be broken by any of these patches - and more importantly whether this code can simply be deleted with these five patches applied.
Okay, I'm going to delete the above and hope for the best; I'm taking the lack of reply as meaning that no one in the Samsung community is that interested in this code.
Russell,
Sorry for late response.According to its commit message, it is needed...
[ARM] 4987/1: S3C24XX: Ensure watchdog reset initiated from cached code.
There seems to be some problem with at-least the S3C2440 and bus traffic during an reset. It is unlikely, but still possible that the system will hang in such a way that the watchdog cannot get the system out of the state it is in.
Quoted 6 lines
Change to making the code that calls the watchdog reset run from cached memory so that instruction fetches have quiesced before the watchdog fires.
But frankly, I'm not sure now and there is no S3C2440 on my desk :( Let me check again, if no response on this, please keep going on.
And now consider it along side the set of patches that I posted as part of this thread, which have the effect that arch_reset() will now be called with caches enabled.
Given that, is it still required?
cover restart cleanups
In reply to Russell King - ARM Linux(Poodle doesn't have any MAINTAINERS entry, I think Richard Purdie last touched Poodle in a 'maintainery' way back in 2006.)
poodle does this:
static void poodle_restart(char mode, const char *cmd)
{
arm_machine_restart('h', cmd);
}Given that the default value of 'mode' (in the absense of any reboot= command line argument to the kernel) is 'h', this seems to be a no-op. Below is the history; I suspect that the reason this first appeared was because of the need to fiddle with RCSR - that's now gone so I suspect the entire restart handler can be deleted.
What I don't understand in that case is why 'mode' wasn't simply passed through in the first patch.
Please confirm.
commit 74617fb6b825ea370ae72565f7543306bc08ef6e
Author: Richard Purdie <[email protected]> Date: Mon Jun 19 19:57:12 2006 +0100
[ARM] 3593/1: Add reboot and shutdown handlers for Zaurus handhelds
Patch from Richard Purdie
Add functionality to allow machine specific reboot handlers on ARM. Add machine specific reboot and poweroff handlers for all PXA Zaurus models.
arch/arm/mach-pxa/poodle.c +0 -0
@@ -247,10 +249,25 @@ static struct platform_device *devices[] __initdata = {
&poodle_scoop_device,
};
+static void poodle_poweroff(void)
+{
+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+ arm_machine_restart('h');
+}
+
+static void poodle_restart(char mode)
+{
+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+ arm_machine_restart('h');
+}
+
static void __init poodle_init(void)
{
int ret = 0;+ pm_power_off = poodle_poweroff;
+ arm_pm_restart = poodle_restart;
...
commit dc38e2ad53ca27968919dea6d7fa60575782d5a6
Author: Russell King <[email protected]> Date: Thu May 8 16:50:39 2008 +0100
[ARM] pxa: Fix RCSR handling
Related to d3930614e68bdf83a120d904c039a64e9f75dba1.
RCSR is only present on PXA2xx CPUs, not on PXA3xx CPUs. Therefore, we should not be unconditionally writing to RCSR from generic code.
Since we now clear the RCSR status from the SoC specific PXA PM code and before reset in the arch_reset() function, the duplication in the corgi, poodle, spitz and tosa code can be removed.
arch/arm/mach-pxa/poodle.c +0 -2
@@ -326,13 +326,11 @@ static struct platform_device *devices[] __initdata = {static void poodle_poweroff (void ) { -RCSR =RCSR_HWR |RCSR_WDR |RCSR_SMR |RCSR_GPR ;arm_machine_restart ('h' ); }static void poodle_restart (char mode) { -RCSR =RCSR_HWR |RCSR_WDR |RCSR_SMR |RCSR_GPR ;arm_machine_restart ('h' ); }
cover restart cleanups
Quoted 18 lines · Russell King - ARM Linux
(Poodle doesn't have any
MAINTAINERSentry, I think Richard Purdie last touched Poodle in a 'maintainery' way back in 2006.)poodle does this:
static void
poodle_restart(char mode, const char *cmd){ arm_machine_restart('h', cmd); }Given that the default value of 'mode' (in the absense of any reboot= command line argument to the kernel) is 'h', this seems to be a no-op. Below is the history; I suspect that the reason this first appeared was because of the need to fiddle with RCSR - that's now gone so I suspect the entire restart handler can be deleted.
What I don't understand in that case is why 'mode' wasn't simply passed through in the first patch.
cover restart cleanups
Quoted 6 lines · Richard Purdie
Quoted 1 line
From what I remember that hardware either always reboots or always
halts. I think the option was therefore left hardcoded to make it clear it wasn't expected to work. Later Zaurii models could do either but required some manual poking of registers to make it happen iirc.
Regardless, you can probably clean this up as you suggest now.
Thanks, I've now committed a change which removes the indirection entirely from poodle.
cover restart cleanups
Quoted 12 lines · Russell King - ARM Linux
Quoted 6 lines · Richard Purdie
Quoted 1 line
From what I remember that hardware either always reboots or always
halts. I think the option was therefore left hardcoded to make it clear it wasn't expected to work. Later Zaurii models could do either but required some manual poking of registers to make it happen iirc.
Regardless, you can probably clean this up as you suggest now.
Thanks, I've now committed a change which removes the indirection entirely from poodle.
Hi, sorry for the late reply
I'm playing with poodle and I can confirm that poweroff does indeed not work with 2.6.3x kernels.
See this thread:
http://lists.linuxtogo.org/pipermail/zaurus-devel/2011-May/000501.html
I'll be happy to test again and report
Regards
Andrea
Quoted 4 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
cover restart cleanups
Quoted 14 lines · Andrea Adami
Quoted 12 lines · Russell King - ARM Linux
Quoted 6 lines · Richard Purdie
Quoted 1 line
From what I remember that hardware either always reboots or always
halts. I think the option was therefore left hardcoded to make it clear it wasn't expected to work. Later Zaurii models could do either but required some manual poking of registers to make it happen iirc.
Regardless, you can probably clean this up as you suggest now.
Thanks, I've now committed a change which removes the indirection entirely from poodle.
Quoted 6 lines
Hi, sorry for the late reply
I'm playing with poodle and I can confirm that poweroff does indeed not work with 2.6.3x kernels.
See this thread:
http://lists.linuxtogo.org/pipermail/zaurus-devel/2011-May/000501.html
Okay, at least we know that restart works with that.
I'm not offering to try and change the poweroff behaviour for the better, as I know absolutely nothing about the Zaurus platforms.
cover restart cleanups
Quoted 15 lines · Russell King - ARM Linux
Quoted 14 lines · Andrea Adami
Quoted 12 lines · Russell King - ARM Linux
Quoted 6 lines · Richard Purdie
Quoted 1 line
From what I remember that hardware either always reboots or always
halts. I think the option was therefore left hardcoded to make it clear it wasn't expected to work. Later Zaurii models could do either but required some manual poking of registers to make it happen iirc.
Regardless, you can probably clean this up as you suggest now.
Thanks, I've now committed a change which removes the indirection entirely from poodle.
Quoted 8 lines
Quoted 6 lines
Hi, sorry for the late reply
I'm playing with poodle and I can confirm that poweroff does indeed not work with 2.6.3x kernels.
See this thread:
http://lists.linuxtogo.org/pipermail/zaurus-devel/2011-May/000501.htmlOkay, at least we know that restart works with that.
Yes, indeed
Quoted 4 lines
I'm not offering to try and change the poweroff behaviour for the better, as I know absolutely nothing about the Zaurus platforms.
I see, np. I'm just puzzled because after a cold reset (pulling battery out) poodle is acting as if powered off and does not restart itself.
Apparently we cannot reach this state again after boot.
FYI the modern zaurus (corgi and spitz) do suspend/resume/poweroff/restart flawlessy so it's only this machine failing poweroff (and maybe collie, no idea).
Regards
Andrea
cover restart cleanups
In reply to Russell King - ARM LinuxHi Russell,
Quoted 3 lines · Russell King - ARM Linux
This series cleans up some of the restart code for ARM. It doesn't go as far as Will's patch set (or even anywhere close to it) mainly because of the poor state of the various implementations in various platforms.
Thanks for helping out with this!
Quoted 2 lines
Effectively, the various platforms themselves stand in the way of optimal cleanup of this code.
Agreed. I'm hoping that people will complain if we break them by accident.
Quoted 7 lines
Other platforms use
arm_pm_restart()to intercept the restart, and force the mode to 'g', 'h' or 's'. As the mode already defaults to 'h' I don't understand why people felt forcing it in that case was necessary. As for the 's' case, this can be done by merely specifying ".soft_reboot = 1" in the machine record. We can solve the 'g' case by changing .soft_reboot to be a char "restart_mode" argument which sets the default restart mode.
Actually, I think we can go as far as deleteing the 'g' mode and using the GPIO reset as a fallback if we fail in the usual 'h' case. This mode is only used by mach-pxa, so it would be good to get rid of it.
We can always do this in a later patch series if it gets in the way (I have a series to clean up the reboot modes already).
Quoted 4 lines
So, this patch set takes us a little way there by cleaning up some of the restart code:
1. remove the useless argument to
setup_mm_for_reboot()
I'm definitely in favour of this change, but be aware that I plan to modify setup_mm_for_reboot in the future to:
(a) Use a static identity mapping so we don't have to pgd_alloc explicitly [I can't see this affecting anything]
(b) Extend the identity mapping into kernel space, leaving some room for the kernel image. If this is all called from soft_reboot, which just does the cpu_reset(addr) afterwards, then we're fine. I have code to take care of changing stack and switching to the new mapping.
Quoted 3 lines
5. provide (and use) a function for soft rebooting which includes the setup of the MMU tables and call
cpu_reset()- and remove the MMU setup from the code paths beforearch_reset()is called.
This function will probably grow to contain the arm_machine_reset function body that I have for kexec.
If you're happy with the direction I'd like to take this in, then you can have my Acked-by tags for patches 1 and 5.
Cheers,
Will
cover restart cleanups
Quoted 11 lines · Will Deacon
Hi Russell,
Quoted 7 lines · Russell King - ARM Linux
Other platforms use
arm_pm_restart()to intercept the restart, and force the mode to 'g', 'h' or 's'. As the mode already defaults to 'h' I don't understand why people felt forcing it in that case was necessary. As for the 's' case, this can be done by merely specifying ".soft_reboot = 1" in the machine record. We can solve the 'g' case by changing .soft_reboot to be a char "restart_mode" argument which sets the default restart mode.
Quoted 6 lines
Actually, I think we can go as far as deleteing the 'g' mode and using the GPIO reset as a fallback if we fail in the usual 'h' case. This mode is only used by mach-pxa, so it would be good to get rid of it.
We can always do this in a later patch series if it gets in the way (I have a series to clean up the reboot modes already).
I think it's useful to distinguish between them especially as there's platforms in PXA land doing weirdo things with this. Some platforms use the GPIO reset thing as a way to shut the system down as well as reboot it, so it's not purely just about reboot (which is in itself annoying).
The other thing is that the generic code shouldn't care what value 'mode' actually is - we just pass it through to the platform handler (via arm_pm_restart()) and if the platform handler wants to ignore it and just do the software reboot thing, it uses soft_restart(addr) which does all the necessary setup for that.
The nice thing about that is we no longer have to worry about calling arm_pm_restart() with 'h' and a platform doing a soft-reboot instead.
Quoted 8 lines
Quoted 4 lines
So, this patch set takes us a little way there by cleaning up some of the restart code:
1. remove the useless argument to
setup_mm_for_reboot()I'm definitely in favour of this change, but be aware that I plan to modify
setup_mm_for_rebootin the future to:
Quoted 7 lines
(a) Use a static identity mapping so we don't have to
pgd_allocexplicitly [I can't see this affecting anything](b) Extend the identity mapping into kernel space, leaving some room for the kernel image. If this is all called from
soft_reboot, which just does thecpu_reset(addr)afterwards, then we're fine. I have code to take care of changing stack and switching to the new mapping.
Well, bear in mind that (1) + (5) produce something really self-contained. We no longer fiddle with MMU tables for anything but the 'soft reboot' path. That means things like hardware based reset (eg, using watchdogs, asserting GPIOs, etc) are all dealt with without fiddling with the MMU and caches.
The side effect of this is that the whole soft-reboot thing is now a self-contained chunk of code which can deal with setting things up in order to do what it needs to do without fear of trampling over hardware mappings.
Quoted 6 lines
Quoted 3 lines
5. provide (and use) a function for soft rebooting which includes the setup of the MMU tables and call
cpu_reset()- and remove the MMU setup from the code paths beforearch_reset()is called.This function will probably grow to contain the
arm_machine_resetfunction body that I have for kexec.
arm_machine_restart() has become almost empty - I want to move the IRQ disables out into machine_restart() and kill off arm_machine_restart() entirely (at the moment its the 'default' action, which is to call the old arch_reset() thing.)
Eventually, when we have everyone hooking into arm_pm_restart() instead, arm_machine_restart() will be unused and meaningless to keep around.
cover restart cleanups
Quoted 5 lines · Russell King - ARM Linux
The other thing is that the generic code shouldn't care what value 'mode' actually is - we just pass it through to the platform handler (via
arm_pm_restart()) and if the platform handler wants to ignore it and just do the software reboot thing, it usessoft_restart(addr)which does all the necessary setup for that.
Ah yes, you're right. I think it might be worth defining 'h' as REBOOT_MODE_HARD and 's' as REBOOT_MODE_SOFT, but there's no reason to disallow other combinations giving that the core code no longer has to do anything with these.
Quoted 2 lines
The nice thing about that is we no longer have to worry about calling
arm_pm_restart()with 'h' and a platform doing a soft-reboot instead.
Yes, that's truly horrific. It's a miracle soft reboot worked at all from v6 onwards.
Quoted 11 lines
Quoted 10 lines
I'm definitely in favour of this change, but be aware that I plan to modify
setup_mm_for_rebootin the future to:(a) Use a static identity mapping so we don't have to
pgd_allocexplicitly [I can't see this affecting anything](b) Extend the identity mapping into kernel space, leaving some room for the kernel image. If this is all called from
soft_reboot, which just does thecpu_reset(addr)afterwards, then we're fine. I have code to take care of changing stack and switching to the new mapping.
Quoted 5 lines
Well, bear in mind that (1) + (5) produce something really self-contained. We no longer fiddle with MMU tables for anything but the 'soft reboot' path. That means things like hardware based reset (eg, using watchdogs, asserting GPIOs, etc) are all dealt with without fiddling with the MMU and caches.
Yup, so we should be able to add the scary MMU and cache stuff into soft_reboot. We can even call this function from the kexec code.
Quoted 7 lines
arm_machine_restart()has become almost empty - I want to move the IRQ disables out intomachine_restart()and kill offarm_machine_restart()entirely (at the moment its the 'default' action, which is to call the oldarch_reset()thing.)Eventually, when we have everyone hooking into
arm_pm_restart()instead,arm_machine_restart()will be unused and meaningless to keep around.
That's where our friend Coccinelle comes in at the end of my patch series.
Will
cover restart cleanups
Quoted 4 lines · Will Deacon
Ah yes, you're right. I think it might be worth defining 'h' as
REBOOT_MODE_HARDand 's' asREBOOT_MODE_SOFT, but there's no reason to disallow other combinations giving that the core code no longer has to do anything with these.
I don't see any need to define these to anything, especially as we just take the first character of the reboot= argument. If we did change it, it would imply that we'd need to change how we parsed that argument as well.
Quoted 5 lines
Quoted 2 lines
The nice thing about that is we no longer have to worry about calling
arm_pm_restart()with 'h' and a platform doing a soft-reboot instead.Yes, that's truly horrific. It's a miracle soft reboot worked at all from v6 onwards.
The short answer is it doesn't - and it's something that with this new structure we can fix - we're no longer concerned by whatever the platform code is doing between the soft restart setup code and actually executing the soft restart itself.
Thankfully, at the point where we have v6 support, most platforms have advanced to the point where there's (mostly) always a hardware method to do a restart, which is much more preferable than trying to do a soft-reboot (it ensures that all peripheral devices are placed into a known state, whereas a soft restart doesn't have that guarantee.)
Quoted 9 lines
Quoted 7 lines
arm_machine_restart()has become almost empty - I want to move the IRQ disables out intomachine_restart()and kill offarm_machine_restart()entirely (at the moment its the 'default' action, which is to call the oldarch_reset()thing.)Eventually, when we have everyone hooking into
arm_pm_restart()instead,arm_machine_restart()will be unused and meaningless to keep around.That's where our friend Coccinelle comes in at the end of my patch series.
We do have this problem - mioa701 - which insists on doing things like kfree, free_irq, gpio_free in this path, which is a bad idea as it can be called from many different contexts including IRQ context. That will appear to work for '/sbin/reboot' but not for things like softdog or a sysrq-b. Arguably, mioa701 is broken in this regard.
However, we don't know whether removing the code will then prevent it rebooting even for a userspace-invoked reboot. We need feedback from the platform maintainer for that (added Philipp and Robert in the hope one of them can answer this - and maybe send a patch to fix it.)
Robert Jarzmik
maintainercover restart cleanups
Quoted 4 lines · Russell King - ARM Linux
However, we don't know whether removing the code will then prevent it rebooting even for a userspace-invoked reboot. We need feedback from the platform maintainer for that (added Philipp and Robert in the hope one of them can answer this - and maybe send a patch to fix it.)
OK, I tested the serie on mioa701 board, and everything works as before. I tested it with mioa701.c amended so that no more halt/reboot hooks are used anymore. The resources freeing is gone as well.
I will submit the following patch [1] to get rid of the hooks to Eric, unless you want it in your tree.
Cheers.
Signature · 3 lines
Robert [1]
cover restart cleanups
Quoted 6 lines · Robert Jarzmik
Quoted 4 lines · Russell King - ARM Linux
However, we don't know whether removing the code will then prevent it rebooting even for a userspace-invoked reboot. We need feedback from the platform maintainer for that (added Philipp and Robert in the hope one of them can answer this - and maybe send a patch to fix it.)
Quoted 6 lines
OK, I tested the serie on mioa701 board, and everything works as before. I tested it with
mioa701.camended so that no more halt/reboot hooks are used anymore. The resources freeing is gone as well.I will submit the following patch [1] to get rid of the hooks to Eric, unless you want it in your tree.
I think I should pick it up because I have a patch changing the .soft_reboot stuff.
cover restart cleanups
In reply to Russell King - ARM LinuxQuoted 3 lines · Russell King - ARM Linux
This series cleans up some of the restart code for ARM. It doesn't go as far as Will's patch set (or even anywhere close to it) mainly because of the poor state of the various implementations in various platforms.
[...]
For the 5 patches:
Nicolas