Skip to content

Commit

Permalink
PCI / PM: Detect early wakeup in pci_pm_prepare()
Browse files Browse the repository at this point in the history
A subsequent patch is going to move the invocation of
pm_runtime_barrier() from dpm_prepare() to __device_suspend().
Consequently, early wakeup events resulting from runtime resume
requests for wakeup devices queued up right before system suspend
will only be detected after all of the subsystem-level .prepare()
callbacks have run.  However, the PCI bus type calls
pm_runtime_get_sync() from its pci_pm_prepare() callback routine,
so it would destroy the early wakeup events information regarding PCI
devices.  To prevent this from happening add an early wakeup
detection mechanism, analogous to the one currently in dpm_prepare(),
to pci_pm_prepare().

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
  • Loading branch information
Rafael J. Wysocki committed Jul 6, 2011
1 parent 632e270 commit eea3fc0
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion drivers/pci/pci-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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
* wake-up.
*/
pm_runtime_get_sync(dev);
pm_runtime_resume(dev);

if (drv && drv->pm && drv->pm->prepare)
error = drv->pm->prepare(dev);
Expand Down

0 comments on commit eea3fc0

Please sign in to comment.