1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License version 2 as 4 * published by the Free Software Foundation. 5 */ 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/delay.h> 9 #include <linux/gpio.h> 10 #include <asm/io.h> 11 #include <asm/proc-fns.h> 12 13 #include <asm/arch/pxa-regs.h> 14 #include <asm/arch/pxa2xx-regs.h> 15 16 static void do_hw_reset(void); 17 18 static int reset_gpio = -1; 19 20 int init_gpio_reset(int gpio) 21 { 22 int rc; 23 24 rc = gpio_request(gpio, "reset generator"); 25 if (rc) { 26 printk(KERN_ERR "Can't request reset_gpio\n"); 27 goto out; 28 } 29 30 rc = gpio_direction_input(gpio); 31 if (rc) { 32 printk(KERN_ERR "Can't configure reset_gpio for input\n"); 33 gpio_free(gpio); 34 goto out; 35 } 36 37 out: 38 if (!rc) 39 reset_gpio = gpio; 40 41 return rc; 42 } 43 44 /* 45 * Trigger GPIO reset. 46 * This covers various types of logic connecting gpio pin 47 * to RESET pins (nRESET or GPIO_RESET): 48 */ 49 static void do_gpio_reset(void) 50 { 51 BUG_ON(reset_gpio == -1); 52 53 /* drive it low */ 54 gpio_direction_output(reset_gpio, 0); 55 mdelay(2); 56 /* rising edge or drive high */ 57 gpio_set_value(reset_gpio, 1); 58 mdelay(2); 59 /* falling edge */ 60 gpio_set_value(reset_gpio, 0); 61 62 /* give it some time */ 63 mdelay(10); 64 65 WARN_ON(1); 66 /* fallback */ 67 do_hw_reset(); 68 } 69 70 static void do_hw_reset(void) 71 { 72 /* Initialize the watchdog and let it fire */ 73 OWER = OWER_WME; 74 OSSR = OSSR_M3; 75 OSMR3 = OSCR + 368640; /* ... in 100 ms */ 76 } 77 78 void arch_reset(char mode) 79 { 80 if (cpu_is_pxa2xx()) 81 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 82 83 switch (mode) { 84 case 's': 85 /* Jump into ROM at address 0 */ 86 cpu_reset(0); 87 break; 88 case 'h': 89 do_hw_reset(); 90 break; 91 case 'g': 92 do_gpio_reset(); 93 break; 94 } 95 } 96 97