Merge branch 'sh-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / base / power / runtime.c
index 42615b4..3172c60 100644 (file)
@@ -168,6 +168,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
 static int rpm_idle(struct device *dev, int rpmflags)
 {
        int (*callback)(struct device *);
+       int (*domain_callback)(struct device *);
        int retval;
 
        retval = rpm_check_suspend_allowed(dev);
@@ -213,19 +214,28 @@ static int rpm_idle(struct device *dev, int rpmflags)
 
        dev->power.idle_notification = true;
 
-       if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle)
-               callback = dev->bus->pm->runtime_idle;
-       else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle)
+       if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_idle;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_idle;
+       else if (dev->bus && dev->bus->pm)
+               callback = dev->bus->pm->runtime_idle;
        else
                callback = NULL;
 
-       if (callback) {
+       if (dev->pwr_domain)
+               domain_callback = dev->pwr_domain->ops.runtime_idle;
+       else
+               domain_callback = NULL;
+
+       if (callback || domain_callback) {
                spin_unlock_irq(&dev->power.lock);
 
-               callback(dev);
+               if (domain_callback)
+                       retval = domain_callback(dev);
+
+               if (!retval && callback)
+                       callback(dev);
 
                spin_lock_irq(&dev->power.lock);
        }
@@ -372,12 +382,12 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 
        __update_runtime_status(dev, RPM_SUSPENDING);
 
-       if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend)
-               callback = dev->bus->pm->runtime_suspend;
-       else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend)
+       if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_suspend;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_suspend;
+       else if (dev->bus && dev->bus->pm)
+               callback = dev->bus->pm->runtime_suspend;
        else
                callback = NULL;
 
@@ -390,6 +400,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                else
                        pm_runtime_cancel_pending(dev);
        } else {
+               if (dev->pwr_domain)
+                       rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev);
  no_callback:
                __update_runtime_status(dev, RPM_SUSPENDED);
                pm_runtime_deactivate_timer(dev);
@@ -431,7 +443,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
  *
  * Check if the device's run-time PM status allows it to be resumed.  Cancel
  * any scheduled or pending requests.  If another resume has been started
- * earlier, either return imediately or wait for it to finish, depending on the
+ * earlier, either return immediately or wait for it to finish, depending on the
  * RPM_NOWAIT and RPM_ASYNC flags.  Similarly, if there's a suspend running in
  * parallel with this function, either tell the other process to resume after
  * suspending (deferred_resume) or wait for it to finish.  If the RPM_ASYNC
@@ -569,12 +581,15 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
        __update_runtime_status(dev, RPM_RESUMING);
 
-       if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
-               callback = dev->bus->pm->runtime_resume;
-       else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume)
+       if (dev->pwr_domain)
+               rpm_callback(dev->pwr_domain->ops.runtime_resume, dev);
+
+       if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_resume;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_resume;
+       else if (dev->bus && dev->bus->pm)
+               callback = dev->bus->pm->runtime_resume;
        else
                callback = NULL;