Commit 71c63122 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

PM / Runtime: Reduce code duplication in core helper functions

Reduce code duplication in rpm_idle(), rpm_suspend() and rpm_resume()
by using local pointers to store callback addresses and moving some
duplicated code into a separate function.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: default avatarAlan Stern <stern@rowland.harvard.edu>
parent dbeeec5f
...@@ -153,7 +153,6 @@ static int rpm_check_suspend_allowed(struct device *dev) ...@@ -153,7 +153,6 @@ static int rpm_check_suspend_allowed(struct device *dev)
return retval; return retval;
} }
/** /**
* rpm_idle - Notify device bus type if the device can be suspended. * rpm_idle - Notify device bus type if the device can be suspended.
* @dev: Device to notify the bus type about. * @dev: Device to notify the bus type about.
...@@ -167,8 +166,8 @@ static int rpm_check_suspend_allowed(struct device *dev) ...@@ -167,8 +166,8 @@ static int rpm_check_suspend_allowed(struct device *dev)
* This function must be called under dev->power.lock with interrupts disabled. * This function must be called under dev->power.lock with interrupts disabled.
*/ */
static int rpm_idle(struct device *dev, int rpmflags) static int rpm_idle(struct device *dev, int rpmflags)
__releases(&dev->power.lock) __acquires(&dev->power.lock)
{ {
int (*callback)(struct device *);
int retval; int retval;
retval = rpm_check_suspend_allowed(dev); retval = rpm_check_suspend_allowed(dev);
...@@ -214,23 +213,19 @@ static int rpm_idle(struct device *dev, int rpmflags) ...@@ -214,23 +213,19 @@ static int rpm_idle(struct device *dev, int rpmflags)
dev->power.idle_notification = true; dev->power.idle_notification = true;
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) { if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle)
spin_unlock_irq(&dev->power.lock); callback = dev->bus->pm->runtime_idle;
else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle)
dev->bus->pm->runtime_idle(dev); callback = dev->type->pm->runtime_idle;
else if (dev->class && dev->class->pm)
spin_lock_irq(&dev->power.lock); callback = dev->class->pm->runtime_idle;
} else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { else
spin_unlock_irq(&dev->power.lock); callback = NULL;
dev->type->pm->runtime_idle(dev);
spin_lock_irq(&dev->power.lock); if (callback) {
} else if (dev->class && dev->class->pm
&& dev->class->pm->runtime_idle) {
spin_unlock_irq(&dev->power.lock); spin_unlock_irq(&dev->power.lock);
dev->class->pm->runtime_idle(dev); callback(dev);
spin_lock_irq(&dev->power.lock); spin_lock_irq(&dev->power.lock);
} }
...@@ -242,6 +237,29 @@ static int rpm_idle(struct device *dev, int rpmflags) ...@@ -242,6 +237,29 @@ static int rpm_idle(struct device *dev, int rpmflags)
return retval; return retval;
} }
/**
* rpm_callback - Run a given runtime PM callback for a given device.
* @cb: Runtime PM callback to run.
* @dev: Device to run the callback for.
*/
static int rpm_callback(int (*cb)(struct device *), struct device *dev)
__releases(&dev->power.lock) __acquires(&dev->power.lock)
{
int retval;
if (!cb)
return -ENOSYS;
spin_unlock_irq(&dev->power.lock);
retval = cb(dev);
spin_lock_irq(&dev->power.lock);
dev->power.runtime_error = retval;
return retval;
}
/** /**
* rpm_suspend - Carry out run-time suspend of given device. * rpm_suspend - Carry out run-time suspend of given device.
* @dev: Device to suspend. * @dev: Device to suspend.
...@@ -261,6 +279,7 @@ static int rpm_idle(struct device *dev, int rpmflags) ...@@ -261,6 +279,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
static int rpm_suspend(struct device *dev, int rpmflags) static int rpm_suspend(struct device *dev, int rpmflags)
__releases(&dev->power.lock) __acquires(&dev->power.lock) __releases(&dev->power.lock) __acquires(&dev->power.lock)
{ {
int (*callback)(struct device *);
struct device *parent = NULL; struct device *parent = NULL;
bool notify = false; bool notify = false;
int retval; int retval;
...@@ -351,33 +370,16 @@ static int rpm_suspend(struct device *dev, int rpmflags) ...@@ -351,33 +370,16 @@ static int rpm_suspend(struct device *dev, int rpmflags)
__update_runtime_status(dev, RPM_SUSPENDING); __update_runtime_status(dev, RPM_SUSPENDING);
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend)
spin_unlock_irq(&dev->power.lock); callback = dev->bus->pm->runtime_suspend;
else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend)
retval = dev->bus->pm->runtime_suspend(dev); callback = dev->type->pm->runtime_suspend;
else if (dev->class && dev->class->pm)
spin_lock_irq(&dev->power.lock); callback = dev->class->pm->runtime_suspend;
dev->power.runtime_error = retval; else
} else if (dev->type && dev->type->pm callback = NULL;
&& dev->type->pm->runtime_suspend) {
spin_unlock_irq(&dev->power.lock);
retval = dev->type->pm->runtime_suspend(dev);
spin_lock_irq(&dev->power.lock);
dev->power.runtime_error = retval;
} else if (dev->class && dev->class->pm
&& dev->class->pm->runtime_suspend) {
spin_unlock_irq(&dev->power.lock);
retval = dev->class->pm->runtime_suspend(dev);
spin_lock_irq(&dev->power.lock);
dev->power.runtime_error = retval;
} else {
retval = -ENOSYS;
}
retval = rpm_callback(callback, dev);
if (retval) { if (retval) {
__update_runtime_status(dev, RPM_ACTIVE); __update_runtime_status(dev, RPM_ACTIVE);
dev->power.deferred_resume = 0; dev->power.deferred_resume = 0;
...@@ -443,6 +445,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) ...@@ -443,6 +445,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
static int rpm_resume(struct device *dev, int rpmflags) static int rpm_resume(struct device *dev, int rpmflags)
__releases(&dev->power.lock) __acquires(&dev->power.lock) __releases(&dev->power.lock) __acquires(&dev->power.lock)
{ {
int (*callback)(struct device *);
struct device *parent = NULL; struct device *parent = NULL;
int retval = 0; int retval = 0;
...@@ -563,33 +566,16 @@ static int rpm_resume(struct device *dev, int rpmflags) ...@@ -563,33 +566,16 @@ static int rpm_resume(struct device *dev, int rpmflags)
__update_runtime_status(dev, RPM_RESUMING); __update_runtime_status(dev, RPM_RESUMING);
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) { if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
spin_unlock_irq(&dev->power.lock); callback = dev->bus->pm->runtime_resume;
else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume)
retval = dev->bus->pm->runtime_resume(dev); callback = dev->type->pm->runtime_resume;
else if (dev->class && dev->class->pm)
spin_lock_irq(&dev->power.lock); callback = dev->class->pm->runtime_resume;
dev->power.runtime_error = retval; else
} else if (dev->type && dev->type->pm callback = NULL;
&& dev->type->pm->runtime_resume) {
spin_unlock_irq(&dev->power.lock);
retval = dev->type->pm->runtime_resume(dev);
spin_lock_irq(&dev->power.lock);
dev->power.runtime_error = retval;
} else if (dev->class && dev->class->pm
&& dev->class->pm->runtime_resume) {
spin_unlock_irq(&dev->power.lock);
retval = dev->class->pm->runtime_resume(dev);
spin_lock_irq(&dev->power.lock);
dev->power.runtime_error = retval;
} else {
retval = -ENOSYS;
}
retval = rpm_callback(callback, dev);
if (retval) { if (retval) {
__update_runtime_status(dev, RPM_SUSPENDED); __update_runtime_status(dev, RPM_SUSPENDED);
pm_runtime_cancel_pending(dev); pm_runtime_cancel_pending(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment