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