diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/base/power/main.c | 97 |
1 files changed, 77 insertions, 20 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1a216c114a0f..c448d5972a0b 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
| @@ -161,6 +161,32 @@ void device_pm_move_last(struct device *dev) | |||
| 161 | list_move_tail(&dev->power.entry, &dpm_list); | 161 | list_move_tail(&dev->power.entry, &dpm_list); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static ktime_t initcall_debug_start(struct device *dev) | ||
| 165 | { | ||
| 166 | ktime_t calltime = ktime_set(0, 0); | ||
| 167 | |||
| 168 | if (initcall_debug) { | ||
| 169 | pr_info("calling %s+ @ %i\n", | ||
| 170 | dev_name(dev), task_pid_nr(current)); | ||
| 171 | calltime = ktime_get(); | ||
| 172 | } | ||
| 173 | |||
| 174 | return calltime; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void initcall_debug_report(struct device *dev, ktime_t calltime, | ||
| 178 | int error) | ||
| 179 | { | ||
| 180 | ktime_t delta, rettime; | ||
| 181 | |||
| 182 | if (initcall_debug) { | ||
| 183 | rettime = ktime_get(); | ||
| 184 | delta = ktime_sub(rettime, calltime); | ||
| 185 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), | ||
| 186 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 164 | /** | 190 | /** |
| 165 | * pm_op - Execute the PM operation appropriate for given PM event. | 191 | * pm_op - Execute the PM operation appropriate for given PM event. |
| 166 | * @dev: Device to handle. | 192 | * @dev: Device to handle. |
| @@ -172,13 +198,9 @@ static int pm_op(struct device *dev, | |||
| 172 | pm_message_t state) | 198 | pm_message_t state) |
| 173 | { | 199 | { |
| 174 | int error = 0; | 200 | int error = 0; |
| 175 | ktime_t calltime, delta, rettime; | 201 | ktime_t calltime; |
| 176 | 202 | ||
| 177 | if (initcall_debug) { | 203 | calltime = initcall_debug_start(dev); |
| 178 | pr_info("calling %s+ @ %i\n", | ||
| 179 | dev_name(dev), task_pid_nr(current)); | ||
| 180 | calltime = ktime_get(); | ||
| 181 | } | ||
| 182 | 204 | ||
| 183 | switch (state.event) { | 205 | switch (state.event) { |
| 184 | #ifdef CONFIG_SUSPEND | 206 | #ifdef CONFIG_SUSPEND |
| @@ -227,12 +249,7 @@ static int pm_op(struct device *dev, | |||
| 227 | error = -EINVAL; | 249 | error = -EINVAL; |
| 228 | } | 250 | } |
| 229 | 251 | ||
| 230 | if (initcall_debug) { | 252 | initcall_debug_report(dev, calltime, error); |
| 231 | rettime = ktime_get(); | ||
| 232 | delta = ktime_sub(rettime, calltime); | ||
| 233 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), | ||
| 234 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | ||
| 235 | } | ||
| 236 | 253 | ||
| 237 | return error; | 254 | return error; |
| 238 | } | 255 | } |
| @@ -309,8 +326,9 @@ static int pm_noirq_op(struct device *dev, | |||
| 309 | if (initcall_debug) { | 326 | if (initcall_debug) { |
| 310 | rettime = ktime_get(); | 327 | rettime = ktime_get(); |
| 311 | delta = ktime_sub(rettime, calltime); | 328 | delta = ktime_sub(rettime, calltime); |
| 312 | printk("initcall %s_i+ returned %d after %Ld usecs\n", dev_name(dev), | 329 | printk("initcall %s_i+ returned %d after %Ld usecs\n", |
| 313 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | 330 | dev_name(dev), error, |
| 331 | (unsigned long long)ktime_to_ns(delta) >> 10); | ||
| 314 | } | 332 | } |
| 315 | 333 | ||
| 316 | return error; | 334 | return error; |
| @@ -408,6 +426,26 @@ void dpm_resume_noirq(pm_message_t state) | |||
| 408 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); | 426 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); |
| 409 | 427 | ||
| 410 | /** | 428 | /** |
| 429 | * legacy_resume - Execute a legacy (bus or class) resume callback for device. | ||
| 430 | * dev: Device to resume. | ||
| 431 | * cb: Resume callback to execute. | ||
| 432 | */ | ||
| 433 | static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) | ||
| 434 | { | ||
| 435 | int error; | ||
| 436 | ktime_t calltime; | ||
| 437 | |||
| 438 | calltime = initcall_debug_start(dev); | ||
| 439 | |||
| 440 | error = cb(dev); | ||
| 441 | suspend_report_result(cb, error); | ||
| 442 | |||
| 443 | initcall_debug_report(dev, calltime, error); | ||
| 444 | |||
| 445 | return error; | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 411 | * device_resume - Execute "resume" callbacks for given device. | 449 | * device_resume - Execute "resume" callbacks for given device. |
| 412 | * @dev: Device to handle. | 450 | * @dev: Device to handle. |
| 413 | * @state: PM transition of the system being carried out. | 451 | * @state: PM transition of the system being carried out. |
| @@ -427,7 +465,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
| 427 | error = pm_op(dev, dev->bus->pm, state); | 465 | error = pm_op(dev, dev->bus->pm, state); |
| 428 | } else if (dev->bus->resume) { | 466 | } else if (dev->bus->resume) { |
| 429 | pm_dev_dbg(dev, state, "legacy "); | 467 | pm_dev_dbg(dev, state, "legacy "); |
| 430 | error = dev->bus->resume(dev); | 468 | error = legacy_resume(dev, dev->bus->resume); |
| 431 | } | 469 | } |
| 432 | if (error) | 470 | if (error) |
| 433 | goto End; | 471 | goto End; |
| @@ -448,7 +486,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
| 448 | error = pm_op(dev, dev->class->pm, state); | 486 | error = pm_op(dev, dev->class->pm, state); |
| 449 | } else if (dev->class->resume) { | 487 | } else if (dev->class->resume) { |
| 450 | pm_dev_dbg(dev, state, "legacy class "); | 488 | pm_dev_dbg(dev, state, "legacy class "); |
| 451 | error = dev->class->resume(dev); | 489 | error = legacy_resume(dev, dev->class->resume); |
| 452 | } | 490 | } |
| 453 | } | 491 | } |
| 454 | End: | 492 | End: |
| @@ -648,6 +686,27 @@ int dpm_suspend_noirq(pm_message_t state) | |||
| 648 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); | 686 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); |
| 649 | 687 | ||
| 650 | /** | 688 | /** |
| 689 | * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. | ||
| 690 | * dev: Device to suspend. | ||
| 691 | * cb: Suspend callback to execute. | ||
| 692 | */ | ||
| 693 | static int legacy_suspend(struct device *dev, pm_message_t state, | ||
| 694 | int (*cb)(struct device *dev, pm_message_t state)) | ||
| 695 | { | ||
| 696 | int error; | ||
| 697 | ktime_t calltime; | ||
| 698 | |||
| 699 | calltime = initcall_debug_start(dev); | ||
| 700 | |||
| 701 | error = cb(dev, state); | ||
| 702 | suspend_report_result(cb, error); | ||
| 703 | |||
| 704 | initcall_debug_report(dev, calltime, error); | ||
| 705 | |||
| 706 | return error; | ||
| 707 | } | ||
| 708 | |||
| 709 | /** | ||
| 651 | * device_suspend - Execute "suspend" callbacks for given device. | 710 | * device_suspend - Execute "suspend" callbacks for given device. |
| 652 | * @dev: Device to handle. | 711 | * @dev: Device to handle. |
| 653 | * @state: PM transition of the system being carried out. | 712 | * @state: PM transition of the system being carried out. |
| @@ -664,8 +723,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
| 664 | error = pm_op(dev, dev->class->pm, state); | 723 | error = pm_op(dev, dev->class->pm, state); |
| 665 | } else if (dev->class->suspend) { | 724 | } else if (dev->class->suspend) { |
| 666 | pm_dev_dbg(dev, state, "legacy class "); | 725 | pm_dev_dbg(dev, state, "legacy class "); |
| 667 | error = dev->class->suspend(dev, state); | 726 | error = legacy_suspend(dev, state, dev->class->suspend); |
| 668 | suspend_report_result(dev->class->suspend, error); | ||
| 669 | } | 727 | } |
| 670 | if (error) | 728 | if (error) |
| 671 | goto End; | 729 | goto End; |
| @@ -686,8 +744,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
| 686 | error = pm_op(dev, dev->bus->pm, state); | 744 | error = pm_op(dev, dev->bus->pm, state); |
| 687 | } else if (dev->bus->suspend) { | 745 | } else if (dev->bus->suspend) { |
| 688 | pm_dev_dbg(dev, state, "legacy "); | 746 | pm_dev_dbg(dev, state, "legacy "); |
| 689 | error = dev->bus->suspend(dev, state); | 747 | error = legacy_suspend(dev, state, dev->bus->suspend); |
| 690 | suspend_report_result(dev->bus->suspend, error); | ||
| 691 | } | 748 | } |
| 692 | } | 749 | } |
| 693 | End: | 750 | End: |
