aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-10 09:38:30 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2011-01-12 09:33:00 -0500
commit02fa3ec01a0df7a8ccc356d8e245a9a1423b3596 (patch)
treec80875047e60cc495892bd61d51b0cba6e7ee23b
parent3a93f2a9f4d8f73d74c0e552feb68a10f778a219 (diff)
regulator: Add basic trace facilities
Provide some basic trace facilities to the regulator API. We generate events on regulator enable, disable and voltage setting over the actual hardware operations (which are assumed to be the expensive ones which require interaction with the actual device). This is intended to facilitate debug of the performance and behaviour with consumers allowing unified traces to be generated including the regulator operations within the context of the other components of the system. For enable we log the explicit delay for the voltage ramp separately to the interaction with the hardware to highlight the time consumed in I/O. We should add a similar delay for voltage changes, though there the relatively small magnitude of the changes in the context of the I/O costs makes it much less critical for most regulators. Only hardware interactions are currently traced as the primary focus is on the performance and synchronisation of actual hardware interactions. Additional tracepoints for debugging of the logical operations can be added later if required. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--drivers/regulator/core.c17
-rw-r--r--include/trace/events/regulator.h141
2 files changed, 158 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 67d3a61f378..8a5d0ae191b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -25,6 +25,9 @@
25#include <linux/regulator/driver.h> 25#include <linux/regulator/driver.h>
26#include <linux/regulator/machine.h> 26#include <linux/regulator/machine.h>
27 27
28#define CREATE_TRACE_POINTS
29#include <trace/events/regulator.h>
30
28#include "dummy.h" 31#include "dummy.h"
29 32
30#define REGULATOR_VERSION "0.5" 33#define REGULATOR_VERSION "0.5"
@@ -1310,6 +1313,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
1310 delay = 0; 1313 delay = 0;
1311 } 1314 }
1312 1315
1316 trace_regulator_enable(rdev_get_name(rdev));
1317
1313 /* Allow the regulator to ramp; it would be useful 1318 /* Allow the regulator to ramp; it would be useful
1314 * to extend this for bulk operations so that the 1319 * to extend this for bulk operations so that the
1315 * regulators can ramp together. */ 1320 * regulators can ramp together. */
@@ -1317,6 +1322,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
1317 if (ret < 0) 1322 if (ret < 0)
1318 return ret; 1323 return ret;
1319 1324
1325 trace_regulator_enable_delay(rdev_get_name(rdev));
1326
1320 if (delay >= 1000) { 1327 if (delay >= 1000) {
1321 mdelay(delay / 1000); 1328 mdelay(delay / 1000);
1322 udelay(delay % 1000); 1329 udelay(delay % 1000);
@@ -1324,6 +1331,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
1324 udelay(delay); 1331 udelay(delay);
1325 } 1332 }
1326 1333
1334 trace_regulator_enable_complete(rdev_get_name(rdev));
1335
1327 } else if (ret < 0) { 1336 } else if (ret < 0) {
1328 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", 1337 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
1329 __func__, rdev_get_name(rdev), ret); 1338 __func__, rdev_get_name(rdev), ret);
@@ -1379,6 +1388,8 @@ static int _regulator_disable(struct regulator_dev *rdev,
1379 /* we are last user */ 1388 /* we are last user */
1380 if (_regulator_can_change_status(rdev) && 1389 if (_regulator_can_change_status(rdev) &&
1381 rdev->desc->ops->disable) { 1390 rdev->desc->ops->disable) {
1391 trace_regulator_disable(rdev_get_name(rdev));
1392
1382 ret = rdev->desc->ops->disable(rdev); 1393 ret = rdev->desc->ops->disable(rdev);
1383 if (ret < 0) { 1394 if (ret < 0) {
1384 printk(KERN_ERR "%s: failed to disable %s\n", 1395 printk(KERN_ERR "%s: failed to disable %s\n",
@@ -1386,6 +1397,8 @@ static int _regulator_disable(struct regulator_dev *rdev,
1386 return ret; 1397 return ret;
1387 } 1398 }
1388 1399
1400 trace_regulator_disable_complete(rdev_get_name(rdev));
1401
1389 _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, 1402 _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
1390 NULL); 1403 NULL);
1391 } 1404 }
@@ -1645,6 +1658,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1645 regulator->min_uV = min_uV; 1658 regulator->min_uV = min_uV;
1646 regulator->max_uV = max_uV; 1659 regulator->max_uV = max_uV;
1647 1660
1661 trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
1662
1648 ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); 1663 ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector);
1649 1664
1650 if (rdev->desc->ops->list_voltage) 1665 if (rdev->desc->ops->list_voltage)
@@ -1652,6 +1667,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1652 else 1667 else
1653 selector = -1; 1668 selector = -1;
1654 1669
1670 trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
1671
1655out: 1672out:
1656 _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); 1673 _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
1657 mutex_unlock(&rdev->mutex); 1674 mutex_unlock(&rdev->mutex);
diff --git a/include/trace/events/regulator.h b/include/trace/events/regulator.h
new file mode 100644
index 00000000000..37502a7404b
--- /dev/null
+++ b/include/trace/events/regulator.h
@@ -0,0 +1,141 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM regulator
3
4#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_REGULATOR_H
6
7#include <linux/ktime.h>
8#include <linux/tracepoint.h>
9
10/*
11 * Events which just log themselves and the regulator name for enable/disable
12 * type tracking.
13 */
14DECLARE_EVENT_CLASS(regulator_basic,
15
16 TP_PROTO(const char *name),
17
18 TP_ARGS(name),
19
20 TP_STRUCT__entry(
21 __string( name, name )
22 ),
23
24 TP_fast_assign(
25 __assign_str(name, name);
26 ),
27
28 TP_printk("name=%s", __get_str(name))
29
30);
31
32DEFINE_EVENT(regulator_basic, regulator_enable,
33
34 TP_PROTO(const char *name),
35
36 TP_ARGS(name)
37
38);
39
40DEFINE_EVENT(regulator_basic, regulator_enable_delay,
41
42 TP_PROTO(const char *name),
43
44 TP_ARGS(name)
45
46);
47
48DEFINE_EVENT(regulator_basic, regulator_enable_complete,
49
50 TP_PROTO(const char *name),
51
52 TP_ARGS(name)
53
54);
55
56DEFINE_EVENT(regulator_basic, regulator_disable,
57
58 TP_PROTO(const char *name),
59
60 TP_ARGS(name)
61
62);
63
64DEFINE_EVENT(regulator_basic, regulator_disable_complete,
65
66 TP_PROTO(const char *name),
67
68 TP_ARGS(name)
69
70);
71
72/*
73 * Events that take a range of numerical values, mostly for voltages
74 * and so on.
75 */
76DECLARE_EVENT_CLASS(regulator_range,
77
78 TP_PROTO(const char *name, int min, int max),
79
80 TP_ARGS(name, min, max),
81
82 TP_STRUCT__entry(
83 __string( name, name )
84 __field( int, min )
85 __field( int, max )
86 ),
87
88 TP_fast_assign(
89 __assign_str(name, name);
90 __entry->min = min;
91 __entry->max = max;
92 ),
93
94 TP_printk("name=%s (%d-%d)", __get_str(name),
95 (int)__entry->min, (int)__entry->max)
96);
97
98DEFINE_EVENT(regulator_range, regulator_set_voltage,
99
100 TP_PROTO(const char *name, int min, int max),
101
102 TP_ARGS(name, min, max)
103
104);
105
106
107/*
108 * Events that take a single value, mostly for readback and refcounts.
109 */
110DECLARE_EVENT_CLASS(regulator_value,
111
112 TP_PROTO(const char *name, unsigned int val),
113
114 TP_ARGS(name, val),
115
116 TP_STRUCT__entry(
117 __string( name, name )
118 __field( unsigned int, val )
119 ),
120
121 TP_fast_assign(
122 __assign_str(name, name);
123 __entry->val = val;
124 ),
125
126 TP_printk("name=%s, val=%u", __get_str(name),
127 (int)__entry->val)
128);
129
130DEFINE_EVENT(regulator_value, regulator_set_voltage_complete,
131
132 TP_PROTO(const char *name, unsigned int value),
133
134 TP_ARGS(name, value)
135
136);
137
138#endif /* _TRACE_POWER_H */
139
140/* This part must be outside protection */
141#include <trace/define_trace.h>