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 <mach/pxa-regs.h> 14 #include <mach/reset.h> 15 16 unsigned int reset_status; 17 EXPORT_SYMBOL(reset_status); 18 19 static void do_hw_reset(void); 20 21 static int reset_gpio = -1; 22 23 int init_gpio_reset(int gpio) 24 { 25 int rc; 26 27 rc = gpio_request(gpio, "reset generator"); 28 if (rc) { 29 printk(KERN_ERR "Can't request reset_gpio\n"); 30 goto out; 31 } 32 33 rc = gpio_direction_input(gpio); 34 if (rc) { 35 printk(KERN_ERR "Can't configure reset_gpio for input\n"); 36 gpio_free(gpio); 37 goto out; 38 } 39 40 out: 41 if (!rc) 42 reset_gpio = gpio; 43 44 return rc; 45 } 46 47 /* 48 * Trigger GPIO reset. 49 * This covers various types of logic connecting gpio pin 50 * to RESET pins (nRESET or GPIO_RESET): 51 */ 52 static void do_gpio_reset(void) 53 { 54 BUG_ON(reset_gpio == -1); 55 56 /* drive it low */ 57 gpio_direction_output(reset_gpio, 0); 58 mdelay(2); 59 /* rising edge or drive high */ 60 gpio_set_value(reset_gpio, 1); 61 mdelay(2); 62 /* falling edge */ 63 gpio_set_value(reset_gpio, 0); 64 65 /* give it some time */ 66 mdelay(10); 67 68 WARN_ON(1); 69 /* fallback */ 70 do_hw_reset(); 71 } 72 73 static void do_hw_reset(void) 74 { 75 /* Initialize the watchdog and let it fire */ 76 OWER = OWER_WME; 77 OSSR = OSSR_M3; 78 OSMR3 = OSCR + 368640; /* ... in 100 ms */ 79 } 80 81 void arch_reset(char mode) 82 { 83 clear_reset_status(RESET_STATUS_ALL); 84 85 switch (mode) { 86 case 's': 87 /* Jump into ROM at address 0 */ 88 cpu_reset(0); 89 break; 90 case 'h': 91 do_hw_reset(); 92 break; 93 case 'g': 94 do_gpio_reset(); 95 break; 96 } 97 } 98 99