aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorShuah Khan <shuah.kh@samsung.com>2013-07-26 15:30:20 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-26 21:18:35 -0400
commit536446772f1181f3afdf332780b5325d1b6980c6 (patch)
tree76b69430ab47c9f44869132b9a1794d6f37f56fa /drivers/base
parent3831261eb08557a1390b29c1038a0217232d8fdb (diff)
PM / Sleep: new trace event to print device suspend and resume times
A new trace event is added to PM events to print the time it takes to suspend and resume a device. It generates trace messages that include device, driver, parent information in addition to the type of PM ops invoked as well as the PM event and error status from the PM ops. Example trace below: bash-2239 [000] .... 290.883035: device_pm_report_time: backlight acpi_video0 parent=0000:00:02.0 state=freeze ops=class nsecs=332 err=0 bash-2239 [000] .... 290.883041: device_pm_report_time: rfkill rf kill3 parent=phy0 state=freeze ops=legacy class nsecs=216 err=0 bash-2239 [001] .... 290.973892: device_pm_report_time: ieee80211 phy0 parent=0000:01:00.0 state=freeze ops=legacy class nsecs=90846477 err=0 bash-2239 [001] .... 293.660129: device_pm_report_time: ieee80211 phy0 parent=0000:01:00.0 state=restore ops=legacy class nsecs=101295162 err=0 bash-2239 [001] .... 293.660147: device_pm_report_time: rfkill rfkill3 parent=phy0 state=restore ops=legacy class nsecs=1804 err=0 bash-2239 [001] .... 293.660157: device_pm_report_time: backlight acpi_video0 parent=0000:00:02.0 state=restore ops=class nsecs=757 err=0 Signed-off-by: Shuah Khan <shuah.kh@samsung.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/main.c77
1 files changed, 43 insertions, 34 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 5a9b6569dd74..9f098a82cf04 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/async.h> 29#include <linux/async.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31#include <trace/events/power.h>
31#include <linux/cpuidle.h> 32#include <linux/cpuidle.h>
32#include "../base.h" 33#include "../base.h"
33#include "power.h" 34#include "power.h"
@@ -56,6 +57,30 @@ static pm_message_t pm_transition;
56 57
57static int async_error; 58static int async_error;
58 59
60static char *pm_verb(int event)
61{
62 switch (event) {
63 case PM_EVENT_SUSPEND:
64 return "suspend";
65 case PM_EVENT_RESUME:
66 return "resume";
67 case PM_EVENT_FREEZE:
68 return "freeze";
69 case PM_EVENT_QUIESCE:
70 return "quiesce";
71 case PM_EVENT_HIBERNATE:
72 return "hibernate";
73 case PM_EVENT_THAW:
74 return "thaw";
75 case PM_EVENT_RESTORE:
76 return "restore";
77 case PM_EVENT_RECOVER:
78 return "recover";
79 default:
80 return "(unknown PM event)";
81 }
82}
83
59/** 84/**
60 * device_pm_sleep_init - Initialize system suspend-related device fields. 85 * device_pm_sleep_init - Initialize system suspend-related device fields.
61 * @dev: Device object being initialized. 86 * @dev: Device object being initialized.
@@ -172,16 +197,21 @@ static ktime_t initcall_debug_start(struct device *dev)
172} 197}
173 198
174static void initcall_debug_report(struct device *dev, ktime_t calltime, 199static void initcall_debug_report(struct device *dev, ktime_t calltime,
175 int error) 200 int error, pm_message_t state, char *info)
176{ 201{
177 ktime_t delta, rettime; 202 ktime_t rettime;
203 s64 nsecs;
204
205 rettime = ktime_get();
206 nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
178 207
179 if (pm_print_times_enabled) { 208 if (pm_print_times_enabled) {
180 rettime = ktime_get();
181 delta = ktime_sub(rettime, calltime);
182 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), 209 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
183 error, (unsigned long long)ktime_to_ns(delta) >> 10); 210 error, (unsigned long long)nsecs >> 10);
184 } 211 }
212
213 trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event),
214 error);
185} 215}
186 216
187/** 217/**
@@ -309,30 +339,6 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat
309 return NULL; 339 return NULL;
310} 340}
311 341
312static char *pm_verb(int event)
313{
314 switch (event) {
315 case PM_EVENT_SUSPEND:
316 return "suspend";
317 case PM_EVENT_RESUME:
318 return "resume";
319 case PM_EVENT_FREEZE:
320 return "freeze";
321 case PM_EVENT_QUIESCE:
322 return "quiesce";
323 case PM_EVENT_HIBERNATE:
324 return "hibernate";
325 case PM_EVENT_THAW:
326 return "thaw";
327 case PM_EVENT_RESTORE:
328 return "restore";
329 case PM_EVENT_RECOVER:
330 return "recover";
331 default:
332 return "(unknown PM event)";
333 }
334}
335
336static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) 342static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info)
337{ 343{
338 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), 344 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
@@ -379,7 +385,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
379 error = cb(dev); 385 error = cb(dev);
380 suspend_report_result(cb, error); 386 suspend_report_result(cb, error);
381 387
382 initcall_debug_report(dev, calltime, error); 388 initcall_debug_report(dev, calltime, error, state, info);
383 389
384 return error; 390 return error;
385} 391}
@@ -1027,7 +1033,8 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
1027 * @cb: Suspend callback to execute. 1033 * @cb: Suspend callback to execute.
1028 */ 1034 */
1029static int legacy_suspend(struct device *dev, pm_message_t state, 1035static int legacy_suspend(struct device *dev, pm_message_t state,
1030 int (*cb)(struct device *dev, pm_message_t state)) 1036 int (*cb)(struct device *dev, pm_message_t state),
1037 char *info)
1031{ 1038{
1032 int error; 1039 int error;
1033 ktime_t calltime; 1040 ktime_t calltime;
@@ -1037,7 +1044,7 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
1037 error = cb(dev, state); 1044 error = cb(dev, state);
1038 suspend_report_result(cb, error); 1045 suspend_report_result(cb, error);
1039 1046
1040 initcall_debug_report(dev, calltime, error); 1047 initcall_debug_report(dev, calltime, error, state, info);
1041 1048
1042 return error; 1049 return error;
1043} 1050}
@@ -1097,7 +1104,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1097 goto Run; 1104 goto Run;
1098 } else if (dev->class->suspend) { 1105 } else if (dev->class->suspend) {
1099 pm_dev_dbg(dev, state, "legacy class "); 1106 pm_dev_dbg(dev, state, "legacy class ");
1100 error = legacy_suspend(dev, state, dev->class->suspend); 1107 error = legacy_suspend(dev, state, dev->class->suspend,
1108 "legacy class ");
1101 goto End; 1109 goto End;
1102 } 1110 }
1103 } 1111 }
@@ -1108,7 +1116,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1108 callback = pm_op(dev->bus->pm, state); 1116 callback = pm_op(dev->bus->pm, state);
1109 } else if (dev->bus->suspend) { 1117 } else if (dev->bus->suspend) {
1110 pm_dev_dbg(dev, state, "legacy bus "); 1118 pm_dev_dbg(dev, state, "legacy bus ");
1111 error = legacy_suspend(dev, state, dev->bus->suspend); 1119 error = legacy_suspend(dev, state, dev->bus->suspend,
1120 "legacy bus ");
1112 goto End; 1121 goto End;
1113 } 1122 }
1114 } 1123 }