diff options
author | Shuah Khan <shuah.kh@samsung.com> | 2013-07-26 15:30:20 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-26 21:18:35 -0400 |
commit | 536446772f1181f3afdf332780b5325d1b6980c6 (patch) | |
tree | 76b69430ab47c9f44869132b9a1794d6f37f56fa /drivers/base | |
parent | 3831261eb08557a1390b29c1038a0217232d8fdb (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.c | 77 |
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 | ||
57 | static int async_error; | 58 | static int async_error; |
58 | 59 | ||
60 | static 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 | ||
174 | static void initcall_debug_report(struct device *dev, ktime_t calltime, | 199 | static 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 | ||
312 | static 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 | |||
336 | static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) | 342 | static 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 | */ |
1029 | static int legacy_suspend(struct device *dev, pm_message_t state, | 1035 | static 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 | } |