From e039614a0ce6df645f8fa4cbe32e4b21fe46a288 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dbaryshkov@gmail.com> Date: Sun, 20 Jan 2008 02:44:03 +0300 Subject: [PATCH 56/64] Support resetting by asserting GPIO pin This adds support for resetting via assertion of GPIO pin. This e.g. is used on Sharp Zaurus SL-6000. Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- arch/arm/mach-pxa/gpio.c | 43 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/pm.c | 4 +- include/asm-arm/arch-pxa/system.h | 10 ++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c index 8638dd7..589da3b 100644 --- a/arch/arm/mach-pxa/gpio.c +++ b/arch/arm/mach-pxa/gpio.c @@ -19,6 +19,7 @@ #include <asm/hardware.h> #include <asm/io.h> #include <asm/arch/pxa-regs.h> +#include <asm/arch/system.h> #include "generic.h" @@ -194,4 +195,46 @@ void __init pxa_init_gpio(int gpio_nr) pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i; gpiochip_add(&pxa_gpio_chip[i/32].chip); } + + if (reset_gpio < gpio_nr) + init_reset_gpio(); +} + +int reset_gpio = -1; +static int __init reset_gpio_setup(char *str) +{ + if (get_option(&str, &reset_gpio) != 1) { + printk(KERN_ERR "reset_gpio: bad value secified"); + return 0; + } + + return 1; +} + +__setup("reset_gpio=", reset_gpio_setup); + +int init_reset_gpio(void) +{ + int rc = 0; + if (reset_gpio == -1) + goto out; + + rc = gpio_request(reset_gpio, "reset generator"); + if (rc) { + printk(KERN_ERR "Can't request reset_gpio\n"); + goto out; + } + + rc = gpio_direction_input(reset_gpio); + if (rc) { + printk(KERN_ERR "Can't configure reset_gpio for input\n"); + gpio_free(reset_gpio); + goto out; + } + +out: + if (rc) + reset_gpio = -1; + + return rc; } diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index a941c71..64f37e5 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -40,8 +40,8 @@ int pxa_pm_enter(suspend_state_t state) pxa_cpu_pm_fns->save(sleep_save); - /* Clear sleep reset status */ - RCSR = RCSR_SMR; + /* Clear reset status */ + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; /* before sleeping, calculate and save a checksum */ for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h index 1d56a3e..c075018 100644 --- a/include/asm-arm/arch-pxa/system.h +++ b/include/asm-arm/arch-pxa/system.h @@ -11,6 +11,7 @@ */ #include <asm/proc-fns.h> +#include <asm/gpio.h> #include "hardware.h" #include "pxa-regs.h" @@ -19,12 +20,21 @@ static inline void arch_idle(void) cpu_do_idle(); } +extern int reset_gpio; + +int init_reset_gpio(void); static inline void arch_reset(char mode) { + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + if (mode == 's') { /* Jump into ROM at address 0 */ cpu_reset(0); + } else if (mode == 'g' && reset_gpio != -1) { + /* Use GPIO reset */ + gpio_direction_output(reset_gpio, 0); + gpio_set_value(reset_gpio, 1); } else { /* Initialize the watchdog and let it fire */ OWER = OWER_WME; -- 1.5.3.8