]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/pci/pci-driver.c
pci-label.c: size_t misspelled as mode_t
[karo-tx-linux.git] / drivers / pci / pci-driver.c
index 135df164a4c1e897e4d36a7d5a49336518669480..12d1e81a8abecd2fc1a6bc7ab3946d53df05542a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <linux/cpu.h>
 #include <linux/pm_runtime.h>
+#include <linux/suspend.h>
 #include "pci.h"
 
 struct pci_dynid {
@@ -615,6 +616,21 @@ static int pci_pm_prepare(struct device *dev)
        struct device_driver *drv = dev->driver;
        int error = 0;
 
+       /*
+        * If a PCI device configured to wake up the system from sleep states
+        * has been suspended at run time and there's a resume request pending
+        * for it, this is equivalent to the device signaling wakeup, so the
+        * system suspend operation should be aborted.
+        */
+       pm_runtime_get_noresume(dev);
+       if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
+               pm_wakeup_event(dev, 0);
+
+       if (pm_wakeup_pending()) {
+               pm_runtime_put_sync(dev);
+               return -EBUSY;
+       }
+
        /*
         * PCI devices suspended at run time need to be resumed at this
         * point, because in general it is necessary to reconfigure them for
@@ -638,6 +654,8 @@ static void pci_pm_complete(struct device *dev)
 
        if (drv && drv->pm && drv->pm->complete)
                drv->pm->complete(dev);
+
+       pm_runtime_put_sync(dev);
 }
 
 #else /* !CONFIG_PM_SLEEP */