PCI / PM: handle failure to enable wakeup on PCIe PME
authorLucas Stach <l.stach@pengutronix.de>
Wed, 22 Oct 2014 12:31:55 +0000 (14:31 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 23 Oct 2014 20:47:28 +0000 (22:47 +0200)
If the irqchip handling the PCIe PME interrupt is not able
to enable interrupt wakeup we should properly reflect this
in the PME suspend status.

This fixes a kernel warning on resume, where it would try
to disable the irq wakeup that failed to be activated while
suspending, for example:

WARNING: CPU: 0 PID: 609 at kernel/irq/manage.c:536 irq_set_irq_wake+0xc0/0xf8()
Unbalanced IRQ 384 wake disable

Fixes: 76cde7e49590 (PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle)
Reported-and-tested-by: Richard Zhu <richard.zhu@freescale.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/pci/pcie/pme.c

index a9f9c46e50221d75eefc73457425876199f79a0e..63fc63911295e7c0be875b39436c889c6850234e 100644 (file)
@@ -397,6 +397,7 @@ static int pcie_pme_suspend(struct pcie_device *srv)
        struct pcie_pme_service_data *data = get_service_data(srv);
        struct pci_dev *port = srv->port;
        bool wakeup;
+       int ret;
 
        if (device_may_wakeup(&port->dev)) {
                wakeup = true;
@@ -407,9 +408,10 @@ static int pcie_pme_suspend(struct pcie_device *srv)
        }
        spin_lock_irq(&data->lock);
        if (wakeup) {
-               enable_irq_wake(srv->irq);
+               ret = enable_irq_wake(srv->irq);
                data->suspend_level = PME_SUSPEND_WAKEUP;
-       } else {
+       }
+       if (!wakeup || ret) {
                struct pci_dev *port = srv->port;
 
                pcie_pme_interrupt_enable(port, false);