diff options
author | Ezra Savard <ezra.savard@xilinx.com> | 2014-08-29 13:58:46 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-09-04 12:23:29 -0400 |
commit | 59e22114b253aaa7caf14221df4dcf924d067922 (patch) | |
tree | c63cb09d523d653526b0104a581e52db888e9f77 /drivers/gpio | |
parent | a19467788170c55104082ba82c8d50f54b9d6106 (diff) |
gpio: zynq: Fixed broken wakeup implementation
Use of unmask/mask in set_wake was an incorrect implementation. The new
implementation correctly sets wakeup for the gpio chip's IRQ so the gpio chip
will not sleep while wakeup-enabled gpio are in use.
Signed-off-by: Ezra Savard <ezra.savard@xilinx.com>
Reviewed-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-zynq.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index d80d722529ad..1e6f19a07454 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
@@ -88,16 +88,17 @@ | |||
88 | * @chip: instance of the gpio_chip | 88 | * @chip: instance of the gpio_chip |
89 | * @base_addr: base address of the GPIO device | 89 | * @base_addr: base address of the GPIO device |
90 | * @clk: clock resource for this controller | 90 | * @clk: clock resource for this controller |
91 | * @irq: interrupt for the GPIO device | ||
91 | */ | 92 | */ |
92 | struct zynq_gpio { | 93 | struct zynq_gpio { |
93 | struct gpio_chip chip; | 94 | struct gpio_chip chip; |
94 | void __iomem *base_addr; | 95 | void __iomem *base_addr; |
95 | struct clk *clk; | 96 | struct clk *clk; |
97 | int irq; | ||
96 | }; | 98 | }; |
97 | 99 | ||
98 | static struct irq_chip zynq_gpio_level_irqchip; | 100 | static struct irq_chip zynq_gpio_level_irqchip; |
99 | static struct irq_chip zynq_gpio_edge_irqchip; | 101 | static struct irq_chip zynq_gpio_edge_irqchip; |
100 | |||
101 | /** | 102 | /** |
102 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank | 103 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank |
103 | * for a given pin in the GPIO device | 104 | * for a given pin in the GPIO device |
@@ -434,10 +435,9 @@ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type) | |||
434 | 435 | ||
435 | static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) | 436 | static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) |
436 | { | 437 | { |
437 | if (on) | 438 | struct zynq_gpio *gpio = irq_data_get_irq_chip_data(data); |
438 | zynq_gpio_irq_unmask(data); | 439 | |
439 | else | 440 | irq_set_irq_wake(gpio->irq, on); |
440 | zynq_gpio_irq_mask(data); | ||
441 | 441 | ||
442 | return 0; | 442 | return 0; |
443 | } | 443 | } |
@@ -518,7 +518,11 @@ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) | |||
518 | 518 | ||
519 | static int __maybe_unused zynq_gpio_suspend(struct device *dev) | 519 | static int __maybe_unused zynq_gpio_suspend(struct device *dev) |
520 | { | 520 | { |
521 | if (!device_may_wakeup(dev)) | 521 | struct platform_device *pdev = to_platform_device(dev); |
522 | int irq = platform_get_irq(pdev, 0); | ||
523 | struct irq_data *data = irq_get_irq_data(irq); | ||
524 | |||
525 | if (!irqd_is_wakeup_set(data)) | ||
522 | return pm_runtime_force_suspend(dev); | 526 | return pm_runtime_force_suspend(dev); |
523 | 527 | ||
524 | return 0; | 528 | return 0; |
@@ -526,7 +530,11 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) | |||
526 | 530 | ||
527 | static int __maybe_unused zynq_gpio_resume(struct device *dev) | 531 | static int __maybe_unused zynq_gpio_resume(struct device *dev) |
528 | { | 532 | { |
529 | if (!device_may_wakeup(dev)) | 533 | struct platform_device *pdev = to_platform_device(dev); |
534 | int irq = platform_get_irq(pdev, 0); | ||
535 | struct irq_data *data = irq_get_irq_data(irq); | ||
536 | |||
537 | if (!irqd_is_wakeup_set(data)) | ||
530 | return pm_runtime_force_resume(dev); | 538 | return pm_runtime_force_resume(dev); |
531 | 539 | ||
532 | return 0; | 540 | return 0; |
@@ -587,7 +595,7 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { | |||
587 | */ | 595 | */ |
588 | static int zynq_gpio_probe(struct platform_device *pdev) | 596 | static int zynq_gpio_probe(struct platform_device *pdev) |
589 | { | 597 | { |
590 | int ret, bank_num, irq; | 598 | int ret, bank_num; |
591 | struct zynq_gpio *gpio; | 599 | struct zynq_gpio *gpio; |
592 | struct gpio_chip *chip; | 600 | struct gpio_chip *chip; |
593 | struct resource *res; | 601 | struct resource *res; |
@@ -603,10 +611,10 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
603 | if (IS_ERR(gpio->base_addr)) | 611 | if (IS_ERR(gpio->base_addr)) |
604 | return PTR_ERR(gpio->base_addr); | 612 | return PTR_ERR(gpio->base_addr); |
605 | 613 | ||
606 | irq = platform_get_irq(pdev, 0); | 614 | gpio->irq = platform_get_irq(pdev, 0); |
607 | if (irq < 0) { | 615 | if (gpio->irq < 0) { |
608 | dev_err(&pdev->dev, "invalid IRQ\n"); | 616 | dev_err(&pdev->dev, "invalid IRQ\n"); |
609 | return irq; | 617 | return gpio->irq; |
610 | } | 618 | } |
611 | 619 | ||
612 | /* configure the gpio chip */ | 620 | /* configure the gpio chip */ |
@@ -654,14 +662,12 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
654 | goto err_rm_gpiochip; | 662 | goto err_rm_gpiochip; |
655 | } | 663 | } |
656 | 664 | ||
657 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, irq, | 665 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, gpio->irq, |
658 | zynq_gpio_irqhandler); | 666 | zynq_gpio_irqhandler); |
659 | 667 | ||
660 | pm_runtime_set_active(&pdev->dev); | 668 | pm_runtime_set_active(&pdev->dev); |
661 | pm_runtime_enable(&pdev->dev); | 669 | pm_runtime_enable(&pdev->dev); |
662 | 670 | ||
663 | device_set_wakeup_capable(&pdev->dev, 1); | ||
664 | |||
665 | return 0; | 671 | return 0; |
666 | 672 | ||
667 | err_rm_gpiochip: | 673 | err_rm_gpiochip: |