aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-04-27 12:31:02 -0400
committerOlof Johansson <olof@lixom.net>2012-04-27 12:31:02 -0400
commitdadb3660a3ad162ac6e76be7262c72f48177f1aa (patch)
tree9298fc01b98d5f56afb1494ddedddcc753f2e2b4
parentb7b617c527224acd862274fc58ff16dd34ab6466 (diff)
parentef7c7c693b4b05a293678fd40ed1511bc94d6f61 (diff)
Merge branch 'fixes' of git://github.com/hzhuang1/linux into fixes
* 'fixes' of git://github.com/hzhuang1/linux: ARM: PXA2xx: MFP: fix potential direction bug ARM: PXA2xx: MFP: fix bug with MFP_LPM_KEEP_OUTPUT arm/sa1100: fix sa1100-rtc memory resource ARM: pxa: fix gpio wakeup setting
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h7
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c21
-rw-r--r--arch/arm/mach-pxa/pxa27x.c6
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--drivers/gpio/gpio-pxa.c21
-rw-r--r--include/linux/gpio-pxa.h4
6 files changed, 55 insertions, 6 deletions
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
index c54cef25895c..cbf51ae81855 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -17,6 +17,7 @@
17 * 17 *
18 * bit 23 - Input/Output (PXA2xx specific) 18 * bit 23 - Input/Output (PXA2xx specific)
19 * bit 24 - Wakeup Enable(PXA2xx specific) 19 * bit 24 - Wakeup Enable(PXA2xx specific)
20 * bit 25 - Keep Output (PXA2xx specific)
20 */ 21 */
21 22
22#define MFP_DIR_IN (0x0 << 23) 23#define MFP_DIR_IN (0x0 << 23)
@@ -25,6 +26,12 @@
25#define MFP_DIR(x) (((x) >> 23) & 0x1) 26#define MFP_DIR(x) (((x) >> 23) & 0x1)
26 27
27#define MFP_LPM_CAN_WAKEUP (0x1 << 24) 28#define MFP_LPM_CAN_WAKEUP (0x1 << 24)
29
30/*
31 * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to
32 * retain their last output level (low or high).
33 * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input.
34 */
28#define MFP_LPM_KEEP_OUTPUT (0x1 << 25) 35#define MFP_LPM_KEEP_OUTPUT (0x1 << 25)
29 36
30#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) 37#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index b0a842887780..ef0426a159d4 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -33,6 +33,8 @@
33#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) 33#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
34#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5)) 34#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5))
35#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) 35#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
36#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18)
37#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)
36 38
37#define PWER_WE35 (1 << 24) 39#define PWER_WE35 (1 << 24)
38 40
@@ -348,6 +350,7 @@ static inline void pxa27x_mfp_init(void) {}
348#ifdef CONFIG_PM 350#ifdef CONFIG_PM
349static unsigned long saved_gafr[2][4]; 351static unsigned long saved_gafr[2][4];
350static unsigned long saved_gpdr[4]; 352static unsigned long saved_gpdr[4];
353static unsigned long saved_gplr[4];
351static unsigned long saved_pgsr[4]; 354static unsigned long saved_pgsr[4];
352 355
353static int pxa2xx_mfp_suspend(void) 356static int pxa2xx_mfp_suspend(void)
@@ -366,14 +369,26 @@ static int pxa2xx_mfp_suspend(void)
366 } 369 }
367 370
368 for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { 371 for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
369
370 saved_gafr[0][i] = GAFR_L(i); 372 saved_gafr[0][i] = GAFR_L(i);
371 saved_gafr[1][i] = GAFR_U(i); 373 saved_gafr[1][i] = GAFR_U(i);
372 saved_gpdr[i] = GPDR(i * 32); 374 saved_gpdr[i] = GPDR(i * 32);
375 saved_gplr[i] = GPLR(i * 32);
373 saved_pgsr[i] = PGSR(i); 376 saved_pgsr[i] = PGSR(i);
374 377
375 GPDR(i * 32) = gpdr_lpm[i]; 378 GPSR(i * 32) = PGSR(i);
379 GPCR(i * 32) = ~PGSR(i);
380 }
381
382 /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */
383 for (i = 0; i < pxa_last_gpio; i++) {
384 if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) ||
385 ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
386 (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i))))
387 GPDR(i) |= GPIO_bit(i);
388 else
389 GPDR(i) &= ~GPIO_bit(i);
376 } 390 }
391
377 return 0; 392 return 0;
378} 393}
379 394
@@ -384,6 +399,8 @@ static void pxa2xx_mfp_resume(void)
384 for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { 399 for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
385 GAFR_L(i) = saved_gafr[0][i]; 400 GAFR_L(i) = saved_gafr[0][i];
386 GAFR_U(i) = saved_gafr[1][i]; 401 GAFR_U(i) = saved_gafr[1][i];
402 GPSR(i * 32) = saved_gplr[i];
403 GPCR(i * 32) = ~saved_gplr[i];
387 GPDR(i * 32) = saved_gpdr[i]; 404 GPDR(i * 32) = saved_gpdr[i];
388 PGSR(i) = saved_pgsr[i]; 405 PGSR(i) = saved_pgsr[i];
389 } 406 }
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 6bce78edce7a..4726c246dcdc 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -421,8 +421,11 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
421 pxa_register_device(&pxa27x_device_i2c_power, info); 421 pxa_register_device(&pxa27x_device_i2c_power, info);
422} 422}
423 423
424static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
425 .gpio_set_wake = gpio_set_wake,
426};
427
424static struct platform_device *devices[] __initdata = { 428static struct platform_device *devices[] __initdata = {
425 &pxa_device_gpio,
426 &pxa27x_device_udc, 429 &pxa27x_device_udc,
427 &pxa_device_pmu, 430 &pxa_device_pmu,
428 &pxa_device_i2s, 431 &pxa_device_i2s,
@@ -458,6 +461,7 @@ static int __init pxa27x_init(void)
458 register_syscore_ops(&pxa2xx_mfp_syscore_ops); 461 register_syscore_ops(&pxa2xx_mfp_syscore_ops);
459 register_syscore_ops(&pxa2xx_clock_syscore_ops); 462 register_syscore_ops(&pxa2xx_clock_syscore_ops);
460 463
464 pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info);
461 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 465 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
462 } 466 }
463 467
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 7c524b4e415d..16be4c56abe3 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -306,7 +306,7 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
306} 306}
307 307
308static struct resource sa1100_rtc_resources[] = { 308static struct resource sa1100_rtc_resources[] = {
309 DEFINE_RES_MEM(0x90010000, 0x9001003f), 309 DEFINE_RES_MEM(0x90010000, 0x40),
310 DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"), 310 DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
311 DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"), 311 DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
312}; 312};
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 5689ce62fd81..fc3ace3fd4cb 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -64,6 +64,7 @@ struct pxa_gpio_chip {
64 unsigned long irq_mask; 64 unsigned long irq_mask;
65 unsigned long irq_edge_rise; 65 unsigned long irq_edge_rise;
66 unsigned long irq_edge_fall; 66 unsigned long irq_edge_fall;
67 int (*set_wake)(unsigned int gpio, unsigned int on);
67 68
68#ifdef CONFIG_PM 69#ifdef CONFIG_PM
69 unsigned long saved_gplr; 70 unsigned long saved_gplr;
@@ -269,7 +270,8 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
269 (value ? GPSR_OFFSET : GPCR_OFFSET)); 270 (value ? GPSR_OFFSET : GPCR_OFFSET));
270} 271}
271 272
272static int __devinit pxa_init_gpio_chip(int gpio_end) 273static int __devinit pxa_init_gpio_chip(int gpio_end,
274 int (*set_wake)(unsigned int, unsigned int))
273{ 275{
274 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; 276 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
275 struct pxa_gpio_chip *chips; 277 struct pxa_gpio_chip *chips;
@@ -285,6 +287,7 @@ static int __devinit pxa_init_gpio_chip(int gpio_end)
285 287
286 sprintf(chips[i].label, "gpio-%d", i); 288 sprintf(chips[i].label, "gpio-%d", i);
287 chips[i].regbase = gpio_reg_base + BANK_OFF(i); 289 chips[i].regbase = gpio_reg_base + BANK_OFF(i);
290 chips[i].set_wake = set_wake;
288 291
289 c->base = gpio; 292 c->base = gpio;
290 c->label = chips[i].label; 293 c->label = chips[i].label;
@@ -412,6 +415,17 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
412 writel_relaxed(gfer, c->regbase + GFER_OFFSET); 415 writel_relaxed(gfer, c->regbase + GFER_OFFSET);
413} 416}
414 417
418static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
419{
420 int gpio = pxa_irq_to_gpio(d->irq);
421 struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
422
423 if (c->set_wake)
424 return c->set_wake(gpio, on);
425 else
426 return 0;
427}
428
415static void pxa_unmask_muxed_gpio(struct irq_data *d) 429static void pxa_unmask_muxed_gpio(struct irq_data *d)
416{ 430{
417 int gpio = pxa_irq_to_gpio(d->irq); 431 int gpio = pxa_irq_to_gpio(d->irq);
@@ -427,6 +441,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {
427 .irq_mask = pxa_mask_muxed_gpio, 441 .irq_mask = pxa_mask_muxed_gpio,
428 .irq_unmask = pxa_unmask_muxed_gpio, 442 .irq_unmask = pxa_unmask_muxed_gpio,
429 .irq_set_type = pxa_gpio_irq_type, 443 .irq_set_type = pxa_gpio_irq_type,
444 .irq_set_wake = pxa_gpio_set_wake,
430}; 445};
431 446
432static int pxa_gpio_nums(void) 447static int pxa_gpio_nums(void)
@@ -471,6 +486,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
471 struct pxa_gpio_chip *c; 486 struct pxa_gpio_chip *c;
472 struct resource *res; 487 struct resource *res;
473 struct clk *clk; 488 struct clk *clk;
489 struct pxa_gpio_platform_data *info;
474 int gpio, irq, ret; 490 int gpio, irq, ret;
475 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; 491 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
476 492
@@ -516,7 +532,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
516 } 532 }
517 533
518 /* Initialize GPIO chips */ 534 /* Initialize GPIO chips */
519 pxa_init_gpio_chip(pxa_last_gpio); 535 info = dev_get_platdata(&pdev->dev);
536 pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
520 537
521 /* clear all GPIO edge detects */ 538 /* clear all GPIO edge detects */
522 for_each_gpio_chip(gpio, c) { 539 for_each_gpio_chip(gpio, c) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 05071ee34c3f..d755b28ba635 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -13,4 +13,8 @@ extern int pxa_last_gpio;
13 13
14extern int pxa_irq_to_gpio(int irq); 14extern int pxa_irq_to_gpio(int irq);
15 15
16struct pxa_gpio_platform_data {
17 int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
18};
19
16#endif /* __GPIO_PXA_H */ 20#endif /* __GPIO_PXA_H */