Commit 74617fb6 authored by Richard Purdie's avatar Richard Purdie Committed by Russell King

[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.
Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b7408aff
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/elfcore.h> #include <linux/elfcore.h>
#include <linux/pm.h>
#include <asm/leds.h> #include <asm/leds.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -71,8 +72,36 @@ static int __init hlt_setup(char *__unused) ...@@ -71,8 +72,36 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup); __setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup); __setup("hlt", hlt_setup);
void arm_machine_restart(char mode)
{
/*
* Clean and disable cache, and turn off interrupts
*/
cpu_proc_fin();
/*
* Tell the mm system that we are going to reboot -
* we may need it to insert some 1:1 mappings so that
* soft boot works.
*/
setup_mm_for_reboot(mode);
/*
* Now call the architecture specific reboot code.
*/
arch_reset(mode);
/*
* Whoops - the architecture was unable to reboot.
* Tell the user!
*/
mdelay(1000);
printk("Reboot failed -- System halted\n");
while (1);
}
/* /*
* The following aren't currently used. * Function pointers to optional machine specific functions
*/ */
void (*pm_idle)(void); void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_idle);
...@@ -80,6 +109,10 @@ EXPORT_SYMBOL(pm_idle); ...@@ -80,6 +109,10 @@ EXPORT_SYMBOL(pm_idle);
void (*pm_power_off)(void); void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(pm_power_off);
void (*arm_pm_restart)(char str) = arm_machine_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
/* /*
* This is our default idle handler. We need to disable * This is our default idle handler. We need to disable
* interrupts here to ensure we don't miss a wakeup call. * interrupts here to ensure we don't miss a wakeup call.
...@@ -151,33 +184,9 @@ void machine_power_off(void) ...@@ -151,33 +184,9 @@ void machine_power_off(void)
pm_power_off(); pm_power_off();
} }
void machine_restart(char * __unused) void machine_restart(char * __unused)
{ {
/* arm_pm_restart(reboot_mode);
* Clean and disable cache, and turn off interrupts
*/
cpu_proc_fin();
/*
* Tell the mm system that we are going to reboot -
* we may need it to insert some 1:1 mappings so that
* soft boot works.
*/
setup_mm_for_reboot(reboot_mode);
/*
* Now call the architecture specific reboot code.
*/
arch_reset(reboot_mode);
/*
* Whoops - the architecture was unable to reboot.
* Tell the user!
*/
mdelay(1000);
printk("Reboot failed -- System halted\n");
while (1);
} }
void __show_regs(struct pt_regs *regs) void __show_regs(struct pt_regs *regs)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/pm.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/memory.h> #include <asm/memory.h>
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
...@@ -310,8 +312,31 @@ static struct platform_device *devices[] __initdata = { ...@@ -310,8 +312,31 @@ static struct platform_device *devices[] __initdata = {
&corgiled_device, &corgiled_device,
}; };
static void corgi_poweroff(void)
{
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
if (!machine_is_corgi())
/* Green LED off tells the bootloader to halt */
reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
arm_machine_restart('h');
}
static void corgi_restart(char mode)
{
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
if (!machine_is_corgi())
/* Green LED on tells the bootloader to reboot */
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
arm_machine_restart('h');
}
static void __init corgi_init(void) static void __init corgi_init(void)
{ {
pm_power_off = corgi_poweroff;
arm_pm_restart = corgi_restart;
/* setup sleep mode values */ /* setup sleep mode values */
PWER = 0x00000002; PWER = 0x00000002;
PFER = 0x00000000; PFER = 0x00000000;
......
...@@ -18,11 +18,13 @@ ...@@ -18,11 +18,13 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/pm.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/system.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
...@@ -247,10 +249,25 @@ static struct platform_device *devices[] __initdata = { ...@@ -247,10 +249,25 @@ static struct platform_device *devices[] __initdata = {
&poodle_scoop_device, &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) static void __init poodle_init(void)
{ {
int ret = 0; int ret = 0;
pm_power_off = poodle_poweroff;
arm_pm_restart = poodle_restart;
/* setup sleep mode values */ /* setup sleep mode values */
PWER = 0x00000002; PWER = 0x00000002;
PFER = 0x00000000; PFER = 0x00000000;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/pm.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/memory.h> #include <asm/memory.h>
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
...@@ -432,8 +434,31 @@ static struct platform_device *devices[] __initdata = { ...@@ -432,8 +434,31 @@ static struct platform_device *devices[] __initdata = {
&spitzled_device, &spitzled_device,
}; };
static void spitz_poweroff(void)
{
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
mdelay(1000);
arm_machine_restart('h');
}
static void spitz_restart(char mode)
{
/* Bootloader magic for a reboot */
if((MSC0 & 0xffff0000) == 0x7ff00000)
MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
spitz_poweroff();
}
static void __init common_init(void) static void __init common_init(void)
{ {
pm_power_off = spitz_poweroff;
arm_pm_restart = spitz_restart;
PMCR = 0x00; PMCR = 0x00;
/* setup sleep mode values */ /* setup sleep mode values */
......
...@@ -19,12 +19,14 @@ ...@@ -19,12 +19,14 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/pm.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system.h>
#include <asm/arch/irda.h> #include <asm/arch/irda.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
#include <asm/arch/udc.h> #include <asm/arch/udc.h>
...@@ -266,8 +268,31 @@ static struct platform_device *devices[] __initdata = { ...@@ -266,8 +268,31 @@ static struct platform_device *devices[] __initdata = {
&tosaled_device, &tosaled_device,
}; };
static void tosa_poweroff(void)
{
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
mdelay(1000);
arm_machine_restart('h');
}
static void tosa_restart(char mode)
{
/* Bootloader magic for a reboot */
if((MSC0 & 0xffff0000) == 0x7ff00000)
MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
tosa_poweroff();
}
static void __init tosa_init(void) static void __init tosa_init(void)
{ {
pm_power_off = tosa_poweroff;
arm_pm_restart = tosa_restart;
pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <asm/proc-fns.h>
#include "hardware.h" #include "hardware.h"
#include "pxa-regs.h" #include "pxa-regs.h"
......
...@@ -108,6 +108,9 @@ extern void __show_regs(struct pt_regs *); ...@@ -108,6 +108,9 @@ extern void __show_regs(struct pt_regs *);
extern int cpu_architecture(void); extern int cpu_architecture(void);
extern void cpu_init(void); extern void cpu_init(void);
void arm_machine_restart(char mode);
extern void (*arm_pm_restart)(char str);
/* /*
* Intel's XScale3 core supports some v6 features (supersections, L2) * Intel's XScale3 core supports some v6 features (supersections, L2)
* but advertises itself as v5 as it does not support the v6 ISA. For * but advertises itself as v5 as it does not support the v6 ISA. For
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment