diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-12-17 19:57:47 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2009-12-17 19:57:47 -0500 |
commit | ecf762b2581e12ac761d12a6e4e297c2224aa899 (patch) | |
tree | 272bcdc3576d64d6b0f3131c245770a7137a77e7 /drivers/base | |
parent | 875ab0b74e85d6801a49392447d26e0b28688d86 (diff) |
PM: Measure device suspend and resume times
Measure and print the time of suspending and resuming all devices.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/main.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index c448d5972a0b..8052dafc0ba9 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -372,6 +372,23 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, | |||
372 | kobject_name(&dev->kobj), pm_verb(state.event), info, error); | 372 | kobject_name(&dev->kobj), pm_verb(state.event), info, error); |
373 | } | 373 | } |
374 | 374 | ||
375 | static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) | ||
376 | { | ||
377 | ktime_t calltime; | ||
378 | s64 usecs64; | ||
379 | int usecs; | ||
380 | |||
381 | calltime = ktime_get(); | ||
382 | usecs64 = ktime_to_ns(ktime_sub(calltime, starttime)); | ||
383 | do_div(usecs64, NSEC_PER_USEC); | ||
384 | usecs = usecs64; | ||
385 | if (usecs == 0) | ||
386 | usecs = 1; | ||
387 | pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n", | ||
388 | info ?: "", info ? " " : "", pm_verb(state.event), | ||
389 | usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); | ||
390 | } | ||
391 | |||
375 | /*------------------------- Resume routines -------------------------*/ | 392 | /*------------------------- Resume routines -------------------------*/ |
376 | 393 | ||
377 | /** | 394 | /** |
@@ -408,6 +425,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) | |||
408 | void dpm_resume_noirq(pm_message_t state) | 425 | void dpm_resume_noirq(pm_message_t state) |
409 | { | 426 | { |
410 | struct device *dev; | 427 | struct device *dev; |
428 | ktime_t starttime = ktime_get(); | ||
411 | 429 | ||
412 | mutex_lock(&dpm_list_mtx); | 430 | mutex_lock(&dpm_list_mtx); |
413 | transition_started = false; | 431 | transition_started = false; |
@@ -421,6 +439,7 @@ void dpm_resume_noirq(pm_message_t state) | |||
421 | pm_dev_err(dev, state, " early", error); | 439 | pm_dev_err(dev, state, " early", error); |
422 | } | 440 | } |
423 | mutex_unlock(&dpm_list_mtx); | 441 | mutex_unlock(&dpm_list_mtx); |
442 | dpm_show_time(starttime, state, "early"); | ||
424 | resume_device_irqs(); | 443 | resume_device_irqs(); |
425 | } | 444 | } |
426 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); | 445 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); |
@@ -506,6 +525,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
506 | static void dpm_resume(pm_message_t state) | 525 | static void dpm_resume(pm_message_t state) |
507 | { | 526 | { |
508 | struct list_head list; | 527 | struct list_head list; |
528 | ktime_t starttime = ktime_get(); | ||
509 | 529 | ||
510 | INIT_LIST_HEAD(&list); | 530 | INIT_LIST_HEAD(&list); |
511 | mutex_lock(&dpm_list_mtx); | 531 | mutex_lock(&dpm_list_mtx); |
@@ -534,6 +554,7 @@ static void dpm_resume(pm_message_t state) | |||
534 | } | 554 | } |
535 | list_splice(&list, &dpm_list); | 555 | list_splice(&list, &dpm_list); |
536 | mutex_unlock(&dpm_list_mtx); | 556 | mutex_unlock(&dpm_list_mtx); |
557 | dpm_show_time(starttime, state, NULL); | ||
537 | } | 558 | } |
538 | 559 | ||
539 | /** | 560 | /** |
@@ -666,6 +687,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) | |||
666 | int dpm_suspend_noirq(pm_message_t state) | 687 | int dpm_suspend_noirq(pm_message_t state) |
667 | { | 688 | { |
668 | struct device *dev; | 689 | struct device *dev; |
690 | ktime_t starttime = ktime_get(); | ||
669 | int error = 0; | 691 | int error = 0; |
670 | 692 | ||
671 | suspend_device_irqs(); | 693 | suspend_device_irqs(); |
@@ -681,6 +703,8 @@ int dpm_suspend_noirq(pm_message_t state) | |||
681 | mutex_unlock(&dpm_list_mtx); | 703 | mutex_unlock(&dpm_list_mtx); |
682 | if (error) | 704 | if (error) |
683 | dpm_resume_noirq(resume_event(state)); | 705 | dpm_resume_noirq(resume_event(state)); |
706 | else | ||
707 | dpm_show_time(starttime, state, "late"); | ||
684 | return error; | 708 | return error; |
685 | } | 709 | } |
686 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); | 710 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); |
@@ -760,6 +784,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
760 | static int dpm_suspend(pm_message_t state) | 784 | static int dpm_suspend(pm_message_t state) |
761 | { | 785 | { |
762 | struct list_head list; | 786 | struct list_head list; |
787 | ktime_t starttime = ktime_get(); | ||
763 | int error = 0; | 788 | int error = 0; |
764 | 789 | ||
765 | INIT_LIST_HEAD(&list); | 790 | INIT_LIST_HEAD(&list); |
@@ -785,6 +810,8 @@ static int dpm_suspend(pm_message_t state) | |||
785 | } | 810 | } |
786 | list_splice(&list, dpm_list.prev); | 811 | list_splice(&list, dpm_list.prev); |
787 | mutex_unlock(&dpm_list_mtx); | 812 | mutex_unlock(&dpm_list_mtx); |
813 | if (!error) | ||
814 | dpm_show_time(starttime, state, NULL); | ||
788 | return error; | 815 | return error; |
789 | } | 816 | } |
790 | 817 | ||