Skip to content

Commit

Permalink
PM / Runtime: Remove idle notification after failing suspend
Browse files Browse the repository at this point in the history
If runtime suspend of a device fails returning -EAGAIN or -EBUSY,
which means that it's safe to try to suspend it again, the PM core
runs the runtime idle helper function for it.  Unfortunately this may
lead to problems, for example for PCI devices whose drivers don't
implement the ->runtime_idle() callback, because in that case the
PCI bus type's ->runtime_idle() always calls pm_runtime_suspend()
for the given device.  Then, if there's an automatic idle
notification after the driver's ->runtime_suspend() returning -EAGAIN
or -EBUSY, it will make the suspend happen again possibly causing a
busy loop to appear.  To avoid that, remove the idle notification
after failing runtime suspend of a device altogether and let the
callers of pm_runtime_suspend() repeat the operation if need be.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
  • Loading branch information
Rafael J. Wysocki committed Oct 16, 2010
1 parent 3624eb0 commit f71648d
Showing 1 changed file with 2 additions and 9 deletions.
11 changes: 2 additions & 9 deletions drivers/base/power/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
{
int (*callback)(struct device *);
struct device *parent = NULL;
bool notify = false;
int retval;

dev_dbg(dev, "%s flags 0x%x\n", __func__, rpmflags);
Expand Down Expand Up @@ -383,13 +382,10 @@ static int rpm_suspend(struct device *dev, int rpmflags)
if (retval) {
__update_runtime_status(dev, RPM_ACTIVE);
dev->power.deferred_resume = 0;
if (retval == -EAGAIN || retval == -EBUSY) {
if (dev->power.timer_expires == 0)
notify = true;
if (retval == -EAGAIN || retval == -EBUSY)
dev->power.runtime_error = 0;
} else {
else
pm_runtime_cancel_pending(dev);
}
} else {
no_callback:
__update_runtime_status(dev, RPM_SUSPENDED);
Expand All @@ -408,9 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
goto out;
}

if (notify)
rpm_idle(dev, 0);

if (parent && !parent->power.ignore_children) {
spin_unlock_irq(&dev->power.lock);

Expand Down

0 comments on commit f71648d

Please sign in to comment.