|
@@ -18,6 +18,7 @@
|
|
#include <linux/sched.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/pm_runtime.h>
|
|
|
|
+#include <linux/suspend.h>
|
|
#include "pci.h"
|
|
#include "pci.h"
|
|
|
|
|
|
struct pci_dynid {
|
|
struct pci_dynid {
|
|
@@ -615,6 +616,21 @@ static int pci_pm_prepare(struct device *dev)
|
|
struct device_driver *drv = dev->driver;
|
|
struct device_driver *drv = dev->driver;
|
|
int error = 0;
|
|
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
|
|
* PCI devices suspended at run time need to be resumed at this
|
|
* point, because in general it is necessary to reconfigure them for
|
|
* point, because in general it is necessary to reconfigure them for
|
|
@@ -624,7 +640,7 @@ static int pci_pm_prepare(struct device *dev)
|
|
* system from the sleep state, we'll have to prevent it from signaling
|
|
* system from the sleep state, we'll have to prevent it from signaling
|
|
* wake-up.
|
|
* wake-up.
|
|
*/
|
|
*/
|
|
- pm_runtime_get_sync(dev);
|
|
|
|
|
|
+ pm_runtime_resume(dev);
|
|
|
|
|
|
if (drv && drv->pm && drv->pm->prepare)
|
|
if (drv && drv->pm && drv->pm->prepare)
|
|
error = drv->pm->prepare(dev);
|
|
error = drv->pm->prepare(dev);
|