diff options
Diffstat (limited to 'drivers/base/power/runtime.c')
-rw-r--r-- | drivers/base/power/runtime.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 42615b419dfb..54597c859ecb 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -168,6 +168,7 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
168 | static int rpm_idle(struct device *dev, int rpmflags) | 168 | static int rpm_idle(struct device *dev, int rpmflags) |
169 | { | 169 | { |
170 | int (*callback)(struct device *); | 170 | int (*callback)(struct device *); |
171 | int (*domain_callback)(struct device *); | ||
171 | int retval; | 172 | int retval; |
172 | 173 | ||
173 | retval = rpm_check_suspend_allowed(dev); | 174 | retval = rpm_check_suspend_allowed(dev); |
@@ -213,19 +214,28 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
213 | 214 | ||
214 | dev->power.idle_notification = true; | 215 | dev->power.idle_notification = true; |
215 | 216 | ||
216 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) | 217 | if (dev->type && dev->type->pm) |
217 | callback = dev->bus->pm->runtime_idle; | ||
218 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) | ||
219 | callback = dev->type->pm->runtime_idle; | 218 | callback = dev->type->pm->runtime_idle; |
220 | else if (dev->class && dev->class->pm) | 219 | else if (dev->class && dev->class->pm) |
221 | callback = dev->class->pm->runtime_idle; | 220 | callback = dev->class->pm->runtime_idle; |
221 | else if (dev->bus && dev->bus->pm) | ||
222 | callback = dev->bus->pm->runtime_idle; | ||
222 | else | 223 | else |
223 | callback = NULL; | 224 | callback = NULL; |
224 | 225 | ||
225 | if (callback) { | 226 | if (dev->pwr_domain) |
227 | domain_callback = dev->pwr_domain->ops.runtime_idle; | ||
228 | else | ||
229 | domain_callback = NULL; | ||
230 | |||
231 | if (callback || domain_callback) { | ||
226 | spin_unlock_irq(&dev->power.lock); | 232 | spin_unlock_irq(&dev->power.lock); |
227 | 233 | ||
228 | callback(dev); | 234 | if (domain_callback) |
235 | retval = domain_callback(dev); | ||
236 | |||
237 | if (!retval && callback) | ||
238 | callback(dev); | ||
229 | 239 | ||
230 | spin_lock_irq(&dev->power.lock); | 240 | spin_lock_irq(&dev->power.lock); |
231 | } | 241 | } |
@@ -372,12 +382,12 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
372 | 382 | ||
373 | __update_runtime_status(dev, RPM_SUSPENDING); | 383 | __update_runtime_status(dev, RPM_SUSPENDING); |
374 | 384 | ||
375 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) | 385 | if (dev->type && dev->type->pm) |
376 | callback = dev->bus->pm->runtime_suspend; | ||
377 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend) | ||
378 | callback = dev->type->pm->runtime_suspend; | 386 | callback = dev->type->pm->runtime_suspend; |
379 | else if (dev->class && dev->class->pm) | 387 | else if (dev->class && dev->class->pm) |
380 | callback = dev->class->pm->runtime_suspend; | 388 | callback = dev->class->pm->runtime_suspend; |
389 | else if (dev->bus && dev->bus->pm) | ||
390 | callback = dev->bus->pm->runtime_suspend; | ||
381 | else | 391 | else |
382 | callback = NULL; | 392 | callback = NULL; |
383 | 393 | ||
@@ -390,6 +400,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
390 | else | 400 | else |
391 | pm_runtime_cancel_pending(dev); | 401 | pm_runtime_cancel_pending(dev); |
392 | } else { | 402 | } else { |
403 | if (dev->pwr_domain) | ||
404 | rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev); | ||
393 | no_callback: | 405 | no_callback: |
394 | __update_runtime_status(dev, RPM_SUSPENDED); | 406 | __update_runtime_status(dev, RPM_SUSPENDED); |
395 | pm_runtime_deactivate_timer(dev); | 407 | pm_runtime_deactivate_timer(dev); |
@@ -569,12 +581,15 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
569 | 581 | ||
570 | __update_runtime_status(dev, RPM_RESUMING); | 582 | __update_runtime_status(dev, RPM_RESUMING); |
571 | 583 | ||
572 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) | 584 | if (dev->pwr_domain) |
573 | callback = dev->bus->pm->runtime_resume; | 585 | rpm_callback(dev->pwr_domain->ops.runtime_resume, dev); |
574 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) | 586 | |
587 | if (dev->type && dev->type->pm) | ||
575 | callback = dev->type->pm->runtime_resume; | 588 | callback = dev->type->pm->runtime_resume; |
576 | else if (dev->class && dev->class->pm) | 589 | else if (dev->class && dev->class->pm) |
577 | callback = dev->class->pm->runtime_resume; | 590 | callback = dev->class->pm->runtime_resume; |
591 | else if (dev->bus && dev->bus->pm) | ||
592 | callback = dev->bus->pm->runtime_resume; | ||
578 | else | 593 | else |
579 | callback = NULL; | 594 | callback = NULL; |
580 | 595 | ||