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
|