Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: pxa: fix gpio wakeup setting

In 3.3, gpio wakeup setting was broken. The call
enable_irq_wake() didn't set up the PXA gpio registers
(PWER, ...) anymore.

Fix it at least for pxa27x. The driver doesn't seem to be
used in pxa25x (weird ...), and the fix doesn't extend to
pxa3xx and pxa95x (which don't have a gpio_set_wake()
available).

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

authored by

Robert Jarzmik and committed by
Haojian Zhuang
b95ace54 66f75a5d

+28 -3
+5 -1
arch/arm/mach-pxa/pxa27x.c
··· 421 421 pxa_register_device(&pxa27x_device_i2c_power, info); 422 422 } 423 423 424 + static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { 425 + .gpio_set_wake = gpio_set_wake, 426 + }; 427 + 424 428 static struct platform_device *devices[] __initdata = { 425 - &pxa_device_gpio, 426 429 &pxa27x_device_udc, 427 430 &pxa_device_pmu, 428 431 &pxa_device_i2s, ··· 461 458 register_syscore_ops(&pxa2xx_mfp_syscore_ops); 462 459 register_syscore_ops(&pxa2xx_clock_syscore_ops); 463 460 461 + pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info); 464 462 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 465 463 } 466 464
+19 -2
drivers/gpio/gpio-pxa.c
··· 64 64 unsigned long irq_mask; 65 65 unsigned long irq_edge_rise; 66 66 unsigned long irq_edge_fall; 67 + int (*set_wake)(unsigned int gpio, unsigned int on); 67 68 68 69 #ifdef CONFIG_PM 69 70 unsigned long saved_gplr; ··· 270 269 (value ? GPSR_OFFSET : GPCR_OFFSET)); 271 270 } 272 271 273 - static int __devinit pxa_init_gpio_chip(int gpio_end) 272 + static int __devinit pxa_init_gpio_chip(int gpio_end, 273 + int (*set_wake)(unsigned int, unsigned int)) 274 274 { 275 275 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; 276 276 struct pxa_gpio_chip *chips; ··· 287 285 288 286 sprintf(chips[i].label, "gpio-%d", i); 289 287 chips[i].regbase = gpio_reg_base + BANK_OFF(i); 288 + chips[i].set_wake = set_wake; 290 289 291 290 c->base = gpio; 292 291 c->label = chips[i].label; ··· 415 412 writel_relaxed(gfer, c->regbase + GFER_OFFSET); 416 413 } 417 414 415 + static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) 416 + { 417 + int gpio = pxa_irq_to_gpio(d->irq); 418 + struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); 419 + 420 + if (c->set_wake) 421 + return c->set_wake(gpio, on); 422 + else 423 + return 0; 424 + } 425 + 418 426 static void pxa_unmask_muxed_gpio(struct irq_data *d) 419 427 { 420 428 int gpio = pxa_irq_to_gpio(d->irq); ··· 441 427 .irq_mask = pxa_mask_muxed_gpio, 442 428 .irq_unmask = pxa_unmask_muxed_gpio, 443 429 .irq_set_type = pxa_gpio_irq_type, 430 + .irq_set_wake = pxa_gpio_set_wake, 444 431 }; 445 432 446 433 static int pxa_gpio_nums(void) ··· 486 471 struct pxa_gpio_chip *c; 487 472 struct resource *res; 488 473 struct clk *clk; 474 + struct pxa_gpio_platform_data *info; 489 475 int gpio, irq, ret; 490 476 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; 491 477 ··· 532 516 } 533 517 534 518 /* Initialize GPIO chips */ 535 - pxa_init_gpio_chip(pxa_last_gpio); 519 + info = dev_get_platdata(&pdev->dev); 520 + pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); 536 521 537 522 /* clear all GPIO edge detects */ 538 523 for_each_gpio_chip(gpio, c) {
+4
include/linux/gpio-pxa.h
··· 13 13 14 14 extern int pxa_irq_to_gpio(int irq); 15 15 16 + struct pxa_gpio_platform_data { 17 + int (*gpio_set_wake)(unsigned int gpio, unsigned int on); 18 + }; 19 + 16 20 #endif /* __GPIO_PXA_H */