aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch
blob: 99220f920089b8fb1851fad57a78962ba955454f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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