aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric miao <eric.y.miao@gmail.com>2007-08-29 05:22:17 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-10-12 16:15:33 -0400
commitc95530c7798b760901c5d6212e528b03e323b8ac (patch)
tree9bb58fcfaa0b7d44da117d94fc2b7606bbb9d98e
parent30f0b40844e5add7ad879e2f5939ff498f72f3e6 (diff)
[ARM] 4560/1: pxa: move processor specific set_wake logic out of irq.c
a function pxa_init_irq_set_wake() was introduced, so that processor specific code could install their own version code setting PFER and PRER registers within pxa_gpio_irq_type are removed, and the edge configuration is postponed to the (*set_wake) and copies the GRER and GFER register, which will always be set up correctly by pxa_gpio_irq_type() Signed-off-by: eric miao <eric.y.miao@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-pxa/generic.h1
-rw-r--r--arch/arm/mach-pxa/irq.c76
-rw-r--r--arch/arm/mach-pxa/pxa25x.c42
-rw-r--r--arch/arm/mach-pxa/pxa27x.c70
4 files changed, 116 insertions, 73 deletions
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 25bd9bf727b6..2c4fe617cfc0 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -15,6 +15,7 @@ extern struct sys_timer pxa_timer;
15extern void __init pxa_init_irq_low(void); 15extern void __init pxa_init_irq_low(void);
16extern void __init pxa_init_irq_high(void); 16extern void __init pxa_init_irq_high(void);
17extern void __init pxa_init_irq_gpio(int gpio_nr); 17extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
18extern void __init pxa25x_init_irq(void); 19extern void __init pxa25x_init_irq(void);
19extern void __init pxa27x_init_irq(void); 20extern void __init pxa27x_init_irq(void);
20extern void __init pxa_map_io(void); 21extern void __init pxa_map_io(void);
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 3d95442d4168..294cc6758d55 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -38,33 +38,11 @@ static void pxa_unmask_low_irq(unsigned int irq)
38 ICMR |= (1 << irq); 38 ICMR |= (1 << irq);
39} 39}
40 40
41static int pxa_set_wake(unsigned int irq, unsigned int on)
42{
43 u32 mask;
44
45 switch (irq) {
46 case IRQ_RTCAlrm:
47 mask = PWER_RTC;
48 break;
49#ifdef CONFIG_PXA27x
50 /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
51#endif
52 default:
53 return -EINVAL;
54 }
55 if (on)
56 PWER |= mask;
57 else
58 PWER &= ~mask;
59 return 0;
60}
61
62static struct irq_chip pxa_internal_chip_low = { 41static struct irq_chip pxa_internal_chip_low = {
63 .name = "SC", 42 .name = "SC",
64 .ack = pxa_mask_low_irq, 43 .ack = pxa_mask_low_irq,
65 .mask = pxa_mask_low_irq, 44 .mask = pxa_mask_low_irq,
66 .unmask = pxa_unmask_low_irq, 45 .unmask = pxa_unmask_low_irq,
67 .set_wake = pxa_set_wake,
68}; 46};
69 47
70void __init pxa_init_irq_low(void) 48void __init pxa_init_irq_low(void)
@@ -125,26 +103,6 @@ void __init pxa_init_irq_high(void)
125} 103}
126#endif 104#endif
127 105
128/* Note that if an input/irq line ever gets changed to an output during
129 * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
130 */
131#ifdef CONFIG_PXA27x
132
133/* PXA27x: Various gpios can issue wakeup events. This logic only
134 * handles the simple cases, not the WEMUX2 and WEMUX3 options
135 */
136#define PXA27x_GPIO_NOWAKE_MASK \
137 ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
138#define WAKEMASK(gpio) \
139 (((gpio) <= 15) \
140 ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
141 : ((gpio == 35) ? (1 << 24) : 0))
142#else
143
144/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */
145#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
146#endif
147
148/* 106/*
149 * PXA GPIO edge detection for IRQs: 107 * PXA GPIO edge detection for IRQs:
150 * IRQs are generated on Falling-Edge, Rising-Edge, or both. 108 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
@@ -158,11 +116,9 @@ static long GPIO_IRQ_mask[4];
158static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) 116static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
159{ 117{
160 int gpio, idx; 118 int gpio, idx;
161 u32 mask;
162 119
163 gpio = IRQ_TO_GPIO(irq); 120 gpio = IRQ_TO_GPIO(irq);
164 idx = gpio >> 5; 121 idx = gpio >> 5;
165 mask = WAKEMASK(gpio);
166 122
167 if (type == IRQT_PROBE) { 123 if (type == IRQT_PROBE) {
168 /* Don't mess with enabled GPIOs using preconfigured edges or 124 /* Don't mess with enabled GPIOs using preconfigured edges or
@@ -182,19 +138,15 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
182 if (type & __IRQT_RISEDGE) { 138 if (type & __IRQT_RISEDGE) {
183 /* printk("rising "); */ 139 /* printk("rising "); */
184 __set_bit (gpio, GPIO_IRQ_rising_edge); 140 __set_bit (gpio, GPIO_IRQ_rising_edge);
185 PRER |= mask;
186 } else { 141 } else {
187 __clear_bit (gpio, GPIO_IRQ_rising_edge); 142 __clear_bit (gpio, GPIO_IRQ_rising_edge);
188 PRER &= ~mask;
189 } 143 }
190 144
191 if (type & __IRQT_FALEDGE) { 145 if (type & __IRQT_FALEDGE) {
192 /* printk("falling "); */ 146 /* printk("falling "); */
193 __set_bit (gpio, GPIO_IRQ_falling_edge); 147 __set_bit (gpio, GPIO_IRQ_falling_edge);
194 PFER |= mask;
195 } else { 148 } else {
196 __clear_bit (gpio, GPIO_IRQ_falling_edge); 149 __clear_bit (gpio, GPIO_IRQ_falling_edge);
197 PFER &= ~mask;
198 } 150 }
199 151
200 /* printk("edges\n"); */ 152 /* printk("edges\n"); */
@@ -213,29 +165,12 @@ static void pxa_ack_low_gpio(unsigned int irq)
213 GEDR0 = (1 << (irq - IRQ_GPIO0)); 165 GEDR0 = (1 << (irq - IRQ_GPIO0));
214} 166}
215 167
216static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
217{
218 int gpio = IRQ_TO_GPIO(irq);
219 u32 mask = WAKEMASK(gpio);
220
221 if (!mask)
222 return -EINVAL;
223
224 if (on)
225 PWER |= mask;
226 else
227 PWER &= ~mask;
228 return 0;
229}
230
231
232static struct irq_chip pxa_low_gpio_chip = { 168static struct irq_chip pxa_low_gpio_chip = {
233 .name = "GPIO-l", 169 .name = "GPIO-l",
234 .ack = pxa_ack_low_gpio, 170 .ack = pxa_ack_low_gpio,
235 .mask = pxa_mask_low_irq, 171 .mask = pxa_mask_low_irq,
236 .unmask = pxa_unmask_low_irq, 172 .unmask = pxa_unmask_low_irq,
237 .set_type = pxa_gpio_irq_type, 173 .set_type = pxa_gpio_irq_type,
238 .set_wake = pxa_set_gpio_wake,
239}; 174};
240 175
241/* 176/*
@@ -342,7 +277,6 @@ static struct irq_chip pxa_muxed_gpio_chip = {
342 .mask = pxa_mask_muxed_gpio, 277 .mask = pxa_mask_muxed_gpio,
343 .unmask = pxa_unmask_muxed_gpio, 278 .unmask = pxa_unmask_muxed_gpio,
344 .set_type = pxa_gpio_irq_type, 279 .set_type = pxa_gpio_irq_type,
345 .set_wake = pxa_set_gpio_wake,
346}; 280};
347 281
348void __init pxa_init_irq_gpio(int gpio_nr) 282void __init pxa_init_irq_gpio(int gpio_nr)
@@ -377,3 +311,13 @@ void __init pxa_init_irq_gpio(int gpio_nr)
377 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); 311 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
378 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); 312 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
379} 313}
314
315void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
316{
317 pxa_internal_chip_low.set_wake = set_wake;
318#ifdef CONFIG_PXA27x
319 pxa_internal_chip_high.set_wake = set_wake;
320#endif
321 pxa_low_gpio_chip.set_wake = set_wake;
322 pxa_muxed_gpio_chip.set_wake = set_wake;
323}
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index ef40c049d9e2..0d6a72504caa 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -227,10 +227,52 @@ static void __init pxa25x_init_pm(void)
227} 227}
228#endif 228#endif
229 229
230/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
231 */
232
233static int pxa25x_set_wake(unsigned int irq, unsigned int on)
234{
235 int gpio = IRQ_TO_GPIO(irq);
236 uint32_t gpio_bit, mask = 0;
237
238 if (gpio >= 0 && gpio <= 15) {
239 gpio_bit = GPIO_bit(gpio);
240 mask = gpio_bit;
241 if (on) {
242 if (GRER(gpio) | gpio_bit)
243 PRER |= gpio_bit;
244 else
245 PRER &= ~gpio_bit;
246
247 if (GFER(gpio) | gpio_bit)
248 PFER |= gpio_bit;
249 else
250 PFER &= ~gpio_bit;
251 }
252 goto set_pwer;
253 }
254
255 if (irq == IRQ_RTCAlrm) {
256 mask = PWER_RTC;
257 goto set_pwer;
258 }
259
260 return -EINVAL;
261
262set_pwer:
263 if (on)
264 PWER |= mask;
265 else
266 PWER &=~mask;
267
268 return 0;
269}
270
230void __init pxa25x_init_irq(void) 271void __init pxa25x_init_irq(void)
231{ 272{
232 pxa_init_irq_low(); 273 pxa_init_irq_low();
233 pxa_init_irq_gpio(85); 274 pxa_init_irq_gpio(85);
275 pxa_init_irq_set_wake(pxa25x_set_wake);
234} 276}
235 277
236static struct platform_device *pxa25x_devices[] __initdata = { 278static struct platform_device *pxa25x_devices[] __initdata = {
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d193755afb2b..2d7fc39732e4 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -306,6 +306,69 @@ static void __init pxa27x_init_pm(void)
306} 306}
307#endif 307#endif
308 308
309/* PXA27x: Various gpios can issue wakeup events. This logic only
310 * handles the simple cases, not the WEMUX2 and WEMUX3 options
311 */
312#define PXA27x_GPIO_NOWAKE_MASK \
313 ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
314#define WAKEMASK(gpio) \
315 (((gpio) <= 15) \
316 ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
317 : ((gpio == 35) ? (1 << 24) : 0))
318
319static int pxa27x_set_wake(unsigned int irq, unsigned int on)
320{
321 int gpio = IRQ_TO_GPIO(irq);
322 uint32_t mask;
323
324 if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) {
325 if (WAKEMASK(gpio) == 0)
326 return -EINVAL;
327
328 mask = WAKEMASK(gpio);
329
330 if (on) {
331 if (GRER(gpio) | GPIO_bit(gpio))
332 PRER |= mask;
333 else
334 PRER &= ~mask;
335
336 if (GFER(gpio) | GPIO_bit(gpio))
337 PFER |= mask;
338 else
339 PFER &= ~mask;
340 }
341 goto set_pwer;
342 }
343
344 switch (irq) {
345 case IRQ_RTCAlrm:
346 mask = PWER_RTC;
347 break;
348 case IRQ_USB:
349 mask = 1u << 26;
350 break;
351 default:
352 return -EINVAL;
353 }
354
355set_pwer:
356 if (on)
357 PWER |= mask;
358 else
359 PWER &=~mask;
360
361 return 0;
362}
363
364void __init pxa27x_init_irq(void)
365{
366 pxa_init_irq_low();
367 pxa_init_irq_high();
368 pxa_init_irq_gpio(128);
369 pxa_init_irq_set_wake(pxa27x_set_wake);
370}
371
309/* 372/*
310 * device registration specific to PXA27x. 373 * device registration specific to PXA27x.
311 */ 374 */
@@ -375,13 +438,6 @@ static struct platform_device *devices[] __initdata = {
375 &pxa27x_device_ohci, 438 &pxa27x_device_ohci,
376}; 439};
377 440
378void __init pxa27x_init_irq(void)
379{
380 pxa_init_irq_low();
381 pxa_init_irq_high();
382 pxa_init_irq_gpio(128);
383}
384
385static int __init pxa27x_init(void) 441static int __init pxa27x_init(void)
386{ 442{
387 int ret = 0; 443 int ret = 0;