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