diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-10-04 16:08:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2010-10-16 19:57:49 -0400 |
commit | 71c63122c4609a917f14a79c32067a68909fc487 (patch) | |
tree | 03a8e884b838e85ee02482ddea22dd47d32e3dd2 /drivers/base | |
parent | dbeeec5fe868f2e2e92fe94daa2c5a047240fdc4 (diff) |
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: Rafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/runtime.c | 122 |
1 files changed, 54 insertions, 68 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index cd4e100a1362..e957c496a1b1 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -153,7 +153,6 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
153 | return retval; | 153 | return retval; |
154 | } | 154 | } |
155 | 155 | ||
156 | |||
157 | /** | 156 | /** |
158 | * rpm_idle - Notify device bus type if the device can be suspended. | 157 | * rpm_idle - Notify device bus type if the device can be suspended. |
159 | * @dev: Device to notify the bus type about. | 158 | * @dev: Device to notify the bus type about. |
@@ -167,8 +166,8 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
167 | * This function must be called under dev->power.lock with interrupts disabled. | 166 | * This function must be called under dev->power.lock with interrupts disabled. |
168 | */ | 167 | */ |
169 | static int rpm_idle(struct device *dev, int rpmflags) | 168 | static int rpm_idle(struct device *dev, int rpmflags) |
170 | __releases(&dev->power.lock) __acquires(&dev->power.lock) | ||
171 | { | 169 | { |
170 | int (*callback)(struct device *); | ||
172 | int retval; | 171 | int retval; |
173 | 172 | ||
174 | retval = rpm_check_suspend_allowed(dev); | 173 | retval = rpm_check_suspend_allowed(dev); |
@@ -214,23 +213,19 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
214 | 213 | ||
215 | dev->power.idle_notification = true; | 214 | dev->power.idle_notification = true; |
216 | 215 | ||
217 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) { | 216 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) |
218 | spin_unlock_irq(&dev->power.lock); | 217 | callback = dev->bus->pm->runtime_idle; |
219 | 218 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) | |
220 | dev->bus->pm->runtime_idle(dev); | 219 | callback = dev->type->pm->runtime_idle; |
221 | 220 | else if (dev->class && dev->class->pm) | |
222 | spin_lock_irq(&dev->power.lock); | 221 | callback = dev->class->pm->runtime_idle; |
223 | } else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { | 222 | else |
224 | spin_unlock_irq(&dev->power.lock); | 223 | callback = NULL; |
225 | |||
226 | dev->type->pm->runtime_idle(dev); | ||
227 | 224 | ||
228 | spin_lock_irq(&dev->power.lock); | 225 | if (callback) { |
229 | } else if (dev->class && dev->class->pm | ||
230 | && dev->class->pm->runtime_idle) { | ||
231 | spin_unlock_irq(&dev->power.lock); | 226 | spin_unlock_irq(&dev->power.lock); |
232 | 227 | ||
233 | dev->class->pm->runtime_idle(dev); | 228 | callback(dev); |
234 | 229 | ||
235 | spin_lock_irq(&dev->power.lock); | 230 | spin_lock_irq(&dev->power.lock); |
236 | } | 231 | } |
@@ -243,6 +238,29 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
243 | } | 238 | } |
244 | 239 | ||
245 | /** | 240 | /** |
241 | * rpm_callback - Run a given runtime PM callback for a given device. | ||
242 | * @cb: Runtime PM callback to run. | ||
243 | * @dev: Device to run the callback for. | ||
244 | */ | ||
245 | static int rpm_callback(int (*cb)(struct device *), struct device *dev) | ||
246 | __releases(&dev->power.lock) __acquires(&dev->power.lock) | ||
247 | { | ||
248 | int retval; | ||
249 | |||
250 | if (!cb) | ||
251 | return -ENOSYS; | ||
252 | |||
253 | spin_unlock_irq(&dev->power.lock); | ||
254 | |||
255 | retval = cb(dev); | ||
256 | |||
257 | spin_lock_irq(&dev->power.lock); | ||
258 | dev->power.runtime_error = retval; | ||
259 | |||
260 | return retval; | ||
261 | } | ||
262 | |||
263 | /** | ||
246 | * rpm_suspend - Carry out run-time suspend of given device. | 264 | * rpm_suspend - Carry out run-time suspend of given device. |
247 | * @dev: Device to suspend. | 265 | * @dev: Device to suspend. |
248 | * @rpmflags: Flag bits. | 266 | * @rpmflags: Flag bits. |
@@ -261,6 +279,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
261 | static int rpm_suspend(struct device *dev, int rpmflags) | 279 | static int rpm_suspend(struct device *dev, int rpmflags) |
262 | __releases(&dev->power.lock) __acquires(&dev->power.lock) | 280 | __releases(&dev->power.lock) __acquires(&dev->power.lock) |
263 | { | 281 | { |
282 | int (*callback)(struct device *); | ||
264 | struct device *parent = NULL; | 283 | struct device *parent = NULL; |
265 | bool notify = false; | 284 | bool notify = false; |
266 | int retval; | 285 | int retval; |
@@ -351,33 +370,16 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
351 | 370 | ||
352 | __update_runtime_status(dev, RPM_SUSPENDING); | 371 | __update_runtime_status(dev, RPM_SUSPENDING); |
353 | 372 | ||
354 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { | 373 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) |
355 | spin_unlock_irq(&dev->power.lock); | 374 | callback = dev->bus->pm->runtime_suspend; |
356 | 375 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend) | |
357 | retval = dev->bus->pm->runtime_suspend(dev); | 376 | callback = dev->type->pm->runtime_suspend; |
358 | 377 | else if (dev->class && dev->class->pm) | |
359 | spin_lock_irq(&dev->power.lock); | 378 | callback = dev->class->pm->runtime_suspend; |
360 | dev->power.runtime_error = retval; | 379 | else |
361 | } else if (dev->type && dev->type->pm | 380 | callback = NULL; |
362 | && dev->type->pm->runtime_suspend) { | ||
363 | spin_unlock_irq(&dev->power.lock); | ||
364 | |||
365 | retval = dev->type->pm->runtime_suspend(dev); | ||
366 | |||
367 | spin_lock_irq(&dev->power.lock); | ||
368 | dev->power.runtime_error = retval; | ||
369 | } else if (dev->class && dev->class->pm | ||
370 | && dev->class->pm->runtime_suspend) { | ||
371 | spin_unlock_irq(&dev->power.lock); | ||
372 | |||
373 | retval = dev->class->pm->runtime_suspend(dev); | ||
374 | |||
375 | spin_lock_irq(&dev->power.lock); | ||
376 | dev->power.runtime_error = retval; | ||
377 | } else { | ||
378 | retval = -ENOSYS; | ||
379 | } | ||
380 | 381 | ||
382 | retval = rpm_callback(callback, dev); | ||
381 | if (retval) { | 383 | if (retval) { |
382 | __update_runtime_status(dev, RPM_ACTIVE); | 384 | __update_runtime_status(dev, RPM_ACTIVE); |
383 | dev->power.deferred_resume = 0; | 385 | dev->power.deferred_resume = 0; |
@@ -443,6 +445,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
443 | static int rpm_resume(struct device *dev, int rpmflags) | 445 | static int rpm_resume(struct device *dev, int rpmflags) |
444 | __releases(&dev->power.lock) __acquires(&dev->power.lock) | 446 | __releases(&dev->power.lock) __acquires(&dev->power.lock) |
445 | { | 447 | { |
448 | int (*callback)(struct device *); | ||
446 | struct device *parent = NULL; | 449 | struct device *parent = NULL; |
447 | int retval = 0; | 450 | int retval = 0; |
448 | 451 | ||
@@ -563,33 +566,16 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
563 | 566 | ||
564 | __update_runtime_status(dev, RPM_RESUMING); | 567 | __update_runtime_status(dev, RPM_RESUMING); |
565 | 568 | ||
566 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) { | 569 | if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) |
567 | spin_unlock_irq(&dev->power.lock); | 570 | callback = dev->bus->pm->runtime_resume; |
568 | 571 | else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) | |
569 | retval = dev->bus->pm->runtime_resume(dev); | 572 | callback = dev->type->pm->runtime_resume; |
570 | 573 | else if (dev->class && dev->class->pm) | |
571 | spin_lock_irq(&dev->power.lock); | 574 | callback = dev->class->pm->runtime_resume; |
572 | dev->power.runtime_error = retval; | 575 | else |
573 | } else if (dev->type && dev->type->pm | 576 | callback = NULL; |
574 | && dev->type->pm->runtime_resume) { | ||
575 | spin_unlock_irq(&dev->power.lock); | ||
576 | |||
577 | retval = dev->type->pm->runtime_resume(dev); | ||
578 | |||
579 | spin_lock_irq(&dev->power.lock); | ||
580 | dev->power.runtime_error = retval; | ||
581 | } else if (dev->class && dev->class->pm | ||
582 | && dev->class->pm->runtime_resume) { | ||
583 | spin_unlock_irq(&dev->power.lock); | ||
584 | |||
585 | retval = dev->class->pm->runtime_resume(dev); | ||
586 | |||
587 | spin_lock_irq(&dev->power.lock); | ||
588 | dev->power.runtime_error = retval; | ||
589 | } else { | ||
590 | retval = -ENOSYS; | ||
591 | } | ||
592 | 577 | ||
578 | retval = rpm_callback(callback, dev); | ||
593 | if (retval) { | 579 | if (retval) { |
594 | __update_runtime_status(dev, RPM_SUSPENDED); | 580 | __update_runtime_status(dev, RPM_SUSPENDED); |
595 | pm_runtime_cancel_pending(dev); | 581 | pm_runtime_cancel_pending(dev); |