aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-01-11 19:11:14 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-01-11 19:11:14 -0500
commit7f4a3702bda0f9f5d34f0241cc81467a55162d7a (patch)
tree085b220efc86abd24fb44d345bbad2dc44f0f7af
parenta7da4813429cf36abd042e6da72cc6641767d52f (diff)
parent5ff24d601092b222340b28466e263b1c4559407e (diff)
Merge branch 'pm-opp'
* pm-opp: PM / OPP: Use snprintf() instead of sprintf() PM / OPP: Set cpu_dev->id in cpumask first PM / OPP: Fix parsing of opp-microvolt and opp-microamp properties PM / OPP: Parse 'opp-<prop>-<name>' bindings PM / OPP: Parse 'opp-supported-hw' binding PM / OPP: Add missing doc comments ARM: dts: exynos4412: Rename OPP nodes as opp@<opp-hz> PM / OPP: Rename OPP nodes as opp@<opp-hz> PM / OPP: Remove 'operating-points-names' binding PM / OPP: Add {opp-microvolt|opp-microamp}-<name> binding PM / OPP: Add "opp-supported-hw" binding PM / OPP: Add debugfs support
-rw-r--r--Documentation/devicetree/bindings/opp/opp.txt132
-rw-r--r--arch/arm/boot/dts/exynos4412.dtsi28
-rw-r--r--drivers/base/power/opp/Makefile1
-rw-r--r--drivers/base/power/opp/core.c336
-rw-r--r--drivers/base/power/opp/cpu.c3
-rw-r--r--drivers/base/power/opp/debugfs.c219
-rw-r--r--drivers/base/power/opp/opp.h53
-rw-r--r--include/linux/pm_opp.h22
8 files changed, 722 insertions, 72 deletions
diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
index 0cb44dc21f97..601256fe8c0d 100644
--- a/Documentation/devicetree/bindings/opp/opp.txt
+++ b/Documentation/devicetree/bindings/opp/opp.txt
@@ -45,21 +45,10 @@ Devices supporting OPPs must set their "operating-points-v2" property with
45phandle to a OPP table in their DT node. The OPP core will use this phandle to 45phandle to a OPP table in their DT node. The OPP core will use this phandle to
46find the operating points for the device. 46find the operating points for the device.
47 47
48Devices may want to choose OPP tables at runtime and so can provide a list of
49phandles here. But only *one* of them should be chosen at runtime. This must be
50accompanied by a corresponding "operating-points-names" property, to uniquely
51identify the OPP tables.
52
53If required, this can be extended for SoC vendor specfic bindings. Such bindings 48If required, this can be extended for SoC vendor specfic bindings. Such bindings
54should be documented as Documentation/devicetree/bindings/power/<vendor>-opp.txt 49should be documented as Documentation/devicetree/bindings/power/<vendor>-opp.txt
55and should have a compatible description like: "operating-points-v2-<vendor>". 50and should have a compatible description like: "operating-points-v2-<vendor>".
56 51
57Optional properties:
58- operating-points-names: Names of OPP tables (required if multiple OPP
59 tables are present), to uniquely identify them. The same list must be present
60 for all the CPUs which are sharing clock/voltage rails and hence the OPP
61 tables.
62
63* OPP Table Node 52* OPP Table Node
64 53
65This describes the OPPs belonging to a device. This node can have following 54This describes the OPPs belonging to a device. This node can have following
@@ -100,6 +89,14 @@ Optional properties:
100 Entries for multiple regulators must be present in the same order as 89 Entries for multiple regulators must be present in the same order as
101 regulators are specified in device's DT node. 90 regulators are specified in device's DT node.
102 91
92- opp-microvolt-<name>: Named opp-microvolt property. This is exactly similar to
93 the above opp-microvolt property, but allows multiple voltage ranges to be
94 provided for the same OPP. At runtime, the platform can pick a <name> and
95 matching opp-microvolt-<name> property will be enabled for all OPPs. If the
96 platform doesn't pick a specific <name> or the <name> doesn't match with any
97 opp-microvolt-<name> properties, then opp-microvolt property shall be used, if
98 present.
99
103- opp-microamp: The maximum current drawn by the device in microamperes 100- opp-microamp: The maximum current drawn by the device in microamperes
104 considering system specific parameters (such as transients, process, aging, 101 considering system specific parameters (such as transients, process, aging,
105 maximum operating temperature range etc.) as necessary. This may be used to 102 maximum operating temperature range etc.) as necessary. This may be used to
@@ -112,6 +109,9 @@ Optional properties:
112 for few regulators, then this should be marked as zero for them. If it isn't 109 for few regulators, then this should be marked as zero for them. If it isn't
113 required for any regulator, then this property need not be present. 110 required for any regulator, then this property need not be present.
114 111
112- opp-microamp-<name>: Named opp-microamp property. Similar to
113 opp-microvolt-<name> property, but for microamp instead.
114
115- clock-latency-ns: Specifies the maximum possible transition latency (in 115- clock-latency-ns: Specifies the maximum possible transition latency (in
116 nanoseconds) for switching to this OPP from any other OPP. 116 nanoseconds) for switching to this OPP from any other OPP.
117 117
@@ -123,6 +123,26 @@ Optional properties:
123- opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in 123- opp-suspend: Marks the OPP to be used during device suspend. Only one OPP in
124 the table should have this. 124 the table should have this.
125 125
126- opp-supported-hw: This enables us to select only a subset of OPPs from the
127 larger OPP table, based on what version of the hardware we are running on. We
128 still can't have multiple nodes with the same opp-hz value in OPP table.
129
130 It's an user defined array containing a hierarchy of hardware version numbers,
131 supported by the OPP. For example: a platform with hierarchy of three levels
132 of versions (A, B and C), this field should be like <X Y Z>, where X
133 corresponds to Version hierarchy A, Y corresponds to version hierarchy B and Z
134 corresponds to version hierarchy C.
135
136 Each level of hierarchy is represented by a 32 bit value, and so there can be
137 only 32 different supported version per hierarchy. i.e. 1 bit per version. A
138 value of 0xFFFFFFFF will enable the OPP for all versions for that hierarchy
139 level. And a value of 0x00000000 will disable the OPP completely, and so we
140 never want that to happen.
141
142 If 32 values aren't sufficient for a version hierarchy, than that version
143 hierarchy can be contained in multiple 32 bit values. i.e. <X Y Z1 Z2> in the
144 above example, Z1 & Z2 refer to the version hierarchy Z.
145
126- status: Marks the node enabled/disabled. 146- status: Marks the node enabled/disabled.
127 147
128Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together. 148Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together.
@@ -157,20 +177,20 @@ Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together.
157 compatible = "operating-points-v2"; 177 compatible = "operating-points-v2";
158 opp-shared; 178 opp-shared;
159 179
160 opp00 { 180 opp@1000000000 {
161 opp-hz = /bits/ 64 <1000000000>; 181 opp-hz = /bits/ 64 <1000000000>;
162 opp-microvolt = <970000 975000 985000>; 182 opp-microvolt = <970000 975000 985000>;
163 opp-microamp = <70000>; 183 opp-microamp = <70000>;
164 clock-latency-ns = <300000>; 184 clock-latency-ns = <300000>;
165 opp-suspend; 185 opp-suspend;
166 }; 186 };
167 opp01 { 187 opp@1100000000 {
168 opp-hz = /bits/ 64 <1100000000>; 188 opp-hz = /bits/ 64 <1100000000>;
169 opp-microvolt = <980000 1000000 1010000>; 189 opp-microvolt = <980000 1000000 1010000>;
170 opp-microamp = <80000>; 190 opp-microamp = <80000>;
171 clock-latency-ns = <310000>; 191 clock-latency-ns = <310000>;
172 }; 192 };
173 opp02 { 193 opp@1200000000 {
174 opp-hz = /bits/ 64 <1200000000>; 194 opp-hz = /bits/ 64 <1200000000>;
175 opp-microvolt = <1025000>; 195 opp-microvolt = <1025000>;
176 clock-latency-ns = <290000>; 196 clock-latency-ns = <290000>;
@@ -236,20 +256,20 @@ independently.
236 * independently. 256 * independently.
237 */ 257 */
238 258
239 opp00 { 259 opp@1000000000 {
240 opp-hz = /bits/ 64 <1000000000>; 260 opp-hz = /bits/ 64 <1000000000>;
241 opp-microvolt = <970000 975000 985000>; 261 opp-microvolt = <970000 975000 985000>;
242 opp-microamp = <70000>; 262 opp-microamp = <70000>;
243 clock-latency-ns = <300000>; 263 clock-latency-ns = <300000>;
244 opp-suspend; 264 opp-suspend;
245 }; 265 };
246 opp01 { 266 opp@1100000000 {
247 opp-hz = /bits/ 64 <1100000000>; 267 opp-hz = /bits/ 64 <1100000000>;
248 opp-microvolt = <980000 1000000 1010000>; 268 opp-microvolt = <980000 1000000 1010000>;
249 opp-microamp = <80000>; 269 opp-microamp = <80000>;
250 clock-latency-ns = <310000>; 270 clock-latency-ns = <310000>;
251 }; 271 };
252 opp02 { 272 opp@1200000000 {
253 opp-hz = /bits/ 64 <1200000000>; 273 opp-hz = /bits/ 64 <1200000000>;
254 opp-microvolt = <1025000>; 274 opp-microvolt = <1025000>;
255 opp-microamp = <90000; 275 opp-microamp = <90000;
@@ -312,20 +332,20 @@ DVFS state together.
312 compatible = "operating-points-v2"; 332 compatible = "operating-points-v2";
313 opp-shared; 333 opp-shared;
314 334
315 opp00 { 335 opp@1000000000 {
316 opp-hz = /bits/ 64 <1000000000>; 336 opp-hz = /bits/ 64 <1000000000>;
317 opp-microvolt = <970000 975000 985000>; 337 opp-microvolt = <970000 975000 985000>;
318 opp-microamp = <70000>; 338 opp-microamp = <70000>;
319 clock-latency-ns = <300000>; 339 clock-latency-ns = <300000>;
320 opp-suspend; 340 opp-suspend;
321 }; 341 };
322 opp01 { 342 opp@1100000000 {
323 opp-hz = /bits/ 64 <1100000000>; 343 opp-hz = /bits/ 64 <1100000000>;
324 opp-microvolt = <980000 1000000 1010000>; 344 opp-microvolt = <980000 1000000 1010000>;
325 opp-microamp = <80000>; 345 opp-microamp = <80000>;
326 clock-latency-ns = <310000>; 346 clock-latency-ns = <310000>;
327 }; 347 };
328 opp02 { 348 opp@1200000000 {
329 opp-hz = /bits/ 64 <1200000000>; 349 opp-hz = /bits/ 64 <1200000000>;
330 opp-microvolt = <1025000>; 350 opp-microvolt = <1025000>;
331 opp-microamp = <90000>; 351 opp-microamp = <90000>;
@@ -338,20 +358,20 @@ DVFS state together.
338 compatible = "operating-points-v2"; 358 compatible = "operating-points-v2";
339 opp-shared; 359 opp-shared;
340 360
341 opp10 { 361 opp@1300000000 {
342 opp-hz = /bits/ 64 <1300000000>; 362 opp-hz = /bits/ 64 <1300000000>;
343 opp-microvolt = <1045000 1050000 1055000>; 363 opp-microvolt = <1045000 1050000 1055000>;
344 opp-microamp = <95000>; 364 opp-microamp = <95000>;
345 clock-latency-ns = <400000>; 365 clock-latency-ns = <400000>;
346 opp-suspend; 366 opp-suspend;
347 }; 367 };
348 opp11 { 368 opp@1400000000 {
349 opp-hz = /bits/ 64 <1400000000>; 369 opp-hz = /bits/ 64 <1400000000>;
350 opp-microvolt = <1075000>; 370 opp-microvolt = <1075000>;
351 opp-microamp = <100000>; 371 opp-microamp = <100000>;
352 clock-latency-ns = <400000>; 372 clock-latency-ns = <400000>;
353 }; 373 };
354 opp12 { 374 opp@1500000000 {
355 opp-hz = /bits/ 64 <1500000000>; 375 opp-hz = /bits/ 64 <1500000000>;
356 opp-microvolt = <1010000 1100000 1110000>; 376 opp-microvolt = <1010000 1100000 1110000>;
357 opp-microamp = <95000>; 377 opp-microamp = <95000>;
@@ -378,7 +398,7 @@ Example 4: Handling multiple regulators
378 compatible = "operating-points-v2"; 398 compatible = "operating-points-v2";
379 opp-shared; 399 opp-shared;
380 400
381 opp00 { 401 opp@1000000000 {
382 opp-hz = /bits/ 64 <1000000000>; 402 opp-hz = /bits/ 64 <1000000000>;
383 opp-microvolt = <970000>, /* Supply 0 */ 403 opp-microvolt = <970000>, /* Supply 0 */
384 <960000>, /* Supply 1 */ 404 <960000>, /* Supply 1 */
@@ -391,7 +411,7 @@ Example 4: Handling multiple regulators
391 411
392 /* OR */ 412 /* OR */
393 413
394 opp00 { 414 opp@1000000000 {
395 opp-hz = /bits/ 64 <1000000000>; 415 opp-hz = /bits/ 64 <1000000000>;
396 opp-microvolt = <970000 975000 985000>, /* Supply 0 */ 416 opp-microvolt = <970000 975000 985000>, /* Supply 0 */
397 <960000 965000 975000>, /* Supply 1 */ 417 <960000 965000 975000>, /* Supply 1 */
@@ -404,7 +424,7 @@ Example 4: Handling multiple regulators
404 424
405 /* OR */ 425 /* OR */
406 426
407 opp00 { 427 opp@1000000000 {
408 opp-hz = /bits/ 64 <1000000000>; 428 opp-hz = /bits/ 64 <1000000000>;
409 opp-microvolt = <970000 975000 985000>, /* Supply 0 */ 429 opp-microvolt = <970000 975000 985000>, /* Supply 0 */
410 <960000 965000 975000>, /* Supply 1 */ 430 <960000 965000 975000>, /* Supply 1 */
@@ -417,7 +437,8 @@ Example 4: Handling multiple regulators
417 }; 437 };
418}; 438};
419 439
420Example 5: Multiple OPP tables 440Example 5: opp-supported-hw
441(example: three level hierarchy of versions: cuts, substrate and process)
421 442
422/ { 443/ {
423 cpus { 444 cpus {
@@ -426,40 +447,73 @@ Example 5: Multiple OPP tables
426 ... 447 ...
427 448
428 cpu-supply = <&cpu_supply> 449 cpu-supply = <&cpu_supply>
429 operating-points-v2 = <&cpu0_opp_table_slow>, <&cpu0_opp_table_fast>; 450 operating-points-v2 = <&cpu0_opp_table_slow>;
430 operating-points-names = "slow", "fast";
431 }; 451 };
432 }; 452 };
433 453
434 cpu0_opp_table_slow: opp_table_slow { 454 opp_table {
435 compatible = "operating-points-v2"; 455 compatible = "operating-points-v2";
436 status = "okay"; 456 status = "okay";
437 opp-shared; 457 opp-shared;
438 458
439 opp00 { 459 opp@600000000 {
460 /*
461 * Supports all substrate and process versions for 0xF
462 * cuts, i.e. only first four cuts.
463 */
464 opp-supported-hw = <0xF 0xFFFFFFFF 0xFFFFFFFF>
440 opp-hz = /bits/ 64 <600000000>; 465 opp-hz = /bits/ 64 <600000000>;
466 opp-microvolt = <900000 915000 925000>;
441 ... 467 ...
442 }; 468 };
443 469
444 opp01 { 470 opp@800000000 {
471 /*
472 * Supports:
473 * - cuts: only one, 6th cut (represented by 6th bit).
474 * - substrate: supports 16 different substrate versions
475 * - process: supports 9 different process versions
476 */
477 opp-supported-hw = <0x20 0xff0000ff 0x0000f4f0>
445 opp-hz = /bits/ 64 <800000000>; 478 opp-hz = /bits/ 64 <800000000>;
479 opp-microvolt = <900000 915000 925000>;
446 ... 480 ...
447 }; 481 };
448 }; 482 };
483};
484
485Example 6: opp-microvolt-<name>, opp-microamp-<name>:
486(example: device with two possible microvolt ranges: slow and fast)
449 487
450 cpu0_opp_table_fast: opp_table_fast { 488/ {
489 cpus {
490 cpu@0 {
491 compatible = "arm,cortex-a7";
492 ...
493
494 operating-points-v2 = <&cpu0_opp_table>;
495 };
496 };
497
498 cpu0_opp_table: opp_table0 {
451 compatible = "operating-points-v2"; 499 compatible = "operating-points-v2";
452 status = "okay";
453 opp-shared; 500 opp-shared;
454 501
455 opp10 { 502 opp@1000000000 {
456 opp-hz = /bits/ 64 <1000000000>; 503 opp-hz = /bits/ 64 <1000000000>;
457 ... 504 opp-microvolt-slow = <900000 915000 925000>;
505 opp-microvolt-fast = <970000 975000 985000>;
506 opp-microamp-slow = <70000>;
507 opp-microamp-fast = <71000>;
458 }; 508 };
459 509
460 opp11 { 510 opp@1200000000 {
461 opp-hz = /bits/ 64 <1100000000>; 511 opp-hz = /bits/ 64 <1200000000>;
462 ... 512 opp-microvolt-slow = <900000 915000 925000>, /* Supply vcc0 */
513 <910000 925000 935000>; /* Supply vcc1 */
514 opp-microvolt-fast = <970000 975000 985000>, /* Supply vcc0 */
515 <960000 965000 975000>; /* Supply vcc1 */
516 opp-microamp = <70000>; /* Will be used for both slow/fast */
463 }; 517 };
464 }; 518 };
465}; 519};
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 294cfe40388d..40beede46e55 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -64,73 +64,73 @@
64 compatible = "operating-points-v2"; 64 compatible = "operating-points-v2";
65 opp-shared; 65 opp-shared;
66 66
67 opp00 { 67 opp@200000000 {
68 opp-hz = /bits/ 64 <200000000>; 68 opp-hz = /bits/ 64 <200000000>;
69 opp-microvolt = <900000>; 69 opp-microvolt = <900000>;
70 clock-latency-ns = <200000>; 70 clock-latency-ns = <200000>;
71 }; 71 };
72 opp01 { 72 opp@300000000 {
73 opp-hz = /bits/ 64 <300000000>; 73 opp-hz = /bits/ 64 <300000000>;
74 opp-microvolt = <900000>; 74 opp-microvolt = <900000>;
75 clock-latency-ns = <200000>; 75 clock-latency-ns = <200000>;
76 }; 76 };
77 opp02 { 77 opp@400000000 {
78 opp-hz = /bits/ 64 <400000000>; 78 opp-hz = /bits/ 64 <400000000>;
79 opp-microvolt = <925000>; 79 opp-microvolt = <925000>;
80 clock-latency-ns = <200000>; 80 clock-latency-ns = <200000>;
81 }; 81 };
82 opp03 { 82 opp@500000000 {
83 opp-hz = /bits/ 64 <500000000>; 83 opp-hz = /bits/ 64 <500000000>;
84 opp-microvolt = <950000>; 84 opp-microvolt = <950000>;
85 clock-latency-ns = <200000>; 85 clock-latency-ns = <200000>;
86 }; 86 };
87 opp04 { 87 opp@600000000 {
88 opp-hz = /bits/ 64 <600000000>; 88 opp-hz = /bits/ 64 <600000000>;
89 opp-microvolt = <975000>; 89 opp-microvolt = <975000>;
90 clock-latency-ns = <200000>; 90 clock-latency-ns = <200000>;
91 }; 91 };
92 opp05 { 92 opp@700000000 {
93 opp-hz = /bits/ 64 <700000000>; 93 opp-hz = /bits/ 64 <700000000>;
94 opp-microvolt = <987500>; 94 opp-microvolt = <987500>;
95 clock-latency-ns = <200000>; 95 clock-latency-ns = <200000>;
96 }; 96 };
97 opp06 { 97 opp@800000000 {
98 opp-hz = /bits/ 64 <800000000>; 98 opp-hz = /bits/ 64 <800000000>;
99 opp-microvolt = <1000000>; 99 opp-microvolt = <1000000>;
100 clock-latency-ns = <200000>; 100 clock-latency-ns = <200000>;
101 opp-suspend; 101 opp-suspend;
102 }; 102 };
103 opp07 { 103 opp@900000000 {
104 opp-hz = /bits/ 64 <900000000>; 104 opp-hz = /bits/ 64 <900000000>;
105 opp-microvolt = <1037500>; 105 opp-microvolt = <1037500>;
106 clock-latency-ns = <200000>; 106 clock-latency-ns = <200000>;
107 }; 107 };
108 opp08 { 108 opp@1000000000 {
109 opp-hz = /bits/ 64 <1000000000>; 109 opp-hz = /bits/ 64 <1000000000>;
110 opp-microvolt = <1087500>; 110 opp-microvolt = <1087500>;
111 clock-latency-ns = <200000>; 111 clock-latency-ns = <200000>;
112 }; 112 };
113 opp09 { 113 opp@1100000000 {
114 opp-hz = /bits/ 64 <1100000000>; 114 opp-hz = /bits/ 64 <1100000000>;
115 opp-microvolt = <1137500>; 115 opp-microvolt = <1137500>;
116 clock-latency-ns = <200000>; 116 clock-latency-ns = <200000>;
117 }; 117 };
118 opp10 { 118 opp@1200000000 {
119 opp-hz = /bits/ 64 <1200000000>; 119 opp-hz = /bits/ 64 <1200000000>;
120 opp-microvolt = <1187500>; 120 opp-microvolt = <1187500>;
121 clock-latency-ns = <200000>; 121 clock-latency-ns = <200000>;
122 }; 122 };
123 opp11 { 123 opp@1300000000 {
124 opp-hz = /bits/ 64 <1300000000>; 124 opp-hz = /bits/ 64 <1300000000>;
125 opp-microvolt = <1250000>; 125 opp-microvolt = <1250000>;
126 clock-latency-ns = <200000>; 126 clock-latency-ns = <200000>;
127 }; 127 };
128 opp12 { 128 opp@1400000000 {
129 opp-hz = /bits/ 64 <1400000000>; 129 opp-hz = /bits/ 64 <1400000000>;
130 opp-microvolt = <1287500>; 130 opp-microvolt = <1287500>;
131 clock-latency-ns = <200000>; 131 clock-latency-ns = <200000>;
132 }; 132 };
133 opp13 { 133 opp@1500000000 {
134 opp-hz = /bits/ 64 <1500000000>; 134 opp-hz = /bits/ 64 <1500000000>;
135 opp-microvolt = <1350000>; 135 opp-microvolt = <1350000>;
136 clock-latency-ns = <200000>; 136 clock-latency-ns = <200000>;
diff --git a/drivers/base/power/opp/Makefile b/drivers/base/power/opp/Makefile
index 33c1e18c41a4..19837ef04d8e 100644
--- a/drivers/base/power/opp/Makefile
+++ b/drivers/base/power/opp/Makefile
@@ -1,2 +1,3 @@
1ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG 1ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
2obj-y += core.o cpu.o 2obj-y += core.o cpu.o
3obj-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index b8e76f75073b..cf351d3dab1c 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -463,6 +463,7 @@ static void _kfree_list_dev_rcu(struct rcu_head *head)
463static void _remove_list_dev(struct device_list_opp *list_dev, 463static void _remove_list_dev(struct device_list_opp *list_dev,
464 struct device_opp *dev_opp) 464 struct device_opp *dev_opp)
465{ 465{
466 opp_debug_unregister(list_dev, dev_opp);
466 list_del(&list_dev->node); 467 list_del(&list_dev->node);
467 call_srcu(&dev_opp->srcu_head.srcu, &list_dev->rcu_head, 468 call_srcu(&dev_opp->srcu_head.srcu, &list_dev->rcu_head,
468 _kfree_list_dev_rcu); 469 _kfree_list_dev_rcu);
@@ -472,6 +473,7 @@ struct device_list_opp *_add_list_dev(const struct device *dev,
472 struct device_opp *dev_opp) 473 struct device_opp *dev_opp)
473{ 474{
474 struct device_list_opp *list_dev; 475 struct device_list_opp *list_dev;
476 int ret;
475 477
476 list_dev = kzalloc(sizeof(*list_dev), GFP_KERNEL); 478 list_dev = kzalloc(sizeof(*list_dev), GFP_KERNEL);
477 if (!list_dev) 479 if (!list_dev)
@@ -481,6 +483,12 @@ struct device_list_opp *_add_list_dev(const struct device *dev,
481 list_dev->dev = dev; 483 list_dev->dev = dev;
482 list_add_rcu(&list_dev->node, &dev_opp->dev_list); 484 list_add_rcu(&list_dev->node, &dev_opp->dev_list);
483 485
486 /* Create debugfs entries for the dev_opp */
487 ret = opp_debug_register(list_dev, dev_opp);
488 if (ret)
489 dev_err(dev, "%s: Failed to register opp debugfs (%d)\n",
490 __func__, ret);
491
484 return list_dev; 492 return list_dev;
485} 493}
486 494
@@ -551,6 +559,12 @@ static void _remove_device_opp(struct device_opp *dev_opp)
551 if (!list_empty(&dev_opp->opp_list)) 559 if (!list_empty(&dev_opp->opp_list))
552 return; 560 return;
553 561
562 if (dev_opp->supported_hw)
563 return;
564
565 if (dev_opp->prop_name)
566 return;
567
554 list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp, 568 list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp,
555 node); 569 node);
556 570
@@ -596,6 +610,7 @@ static void _opp_remove(struct device_opp *dev_opp,
596 */ 610 */
597 if (notify) 611 if (notify)
598 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_REMOVE, opp); 612 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_REMOVE, opp);
613 opp_debug_remove_one(opp);
599 list_del_rcu(&opp->node); 614 list_del_rcu(&opp->node);
600 call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu); 615 call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu);
601 616
@@ -673,6 +688,7 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
673{ 688{
674 struct dev_pm_opp *opp; 689 struct dev_pm_opp *opp;
675 struct list_head *head = &dev_opp->opp_list; 690 struct list_head *head = &dev_opp->opp_list;
691 int ret;
676 692
677 /* 693 /*
678 * Insert new OPP in order of increasing frequency and discard if 694 * Insert new OPP in order of increasing frequency and discard if
@@ -703,6 +719,11 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
703 new_opp->dev_opp = dev_opp; 719 new_opp->dev_opp = dev_opp;
704 list_add_rcu(&new_opp->node, head); 720 list_add_rcu(&new_opp->node, head);
705 721
722 ret = opp_debug_create_one(new_opp, dev_opp);
723 if (ret)
724 dev_err(dev, "%s: Failed to register opp to debugfs (%d)\n",
725 __func__, ret);
726
706 return 0; 727 return 0;
707} 728}
708 729
@@ -776,35 +797,49 @@ unlock:
776} 797}
777 798
778/* TODO: Support multiple regulators */ 799/* TODO: Support multiple regulators */
779static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) 800static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
801 struct device_opp *dev_opp)
780{ 802{
781 u32 microvolt[3] = {0}; 803 u32 microvolt[3] = {0};
782 u32 val; 804 u32 val;
783 int count, ret; 805 int count, ret;
806 struct property *prop = NULL;
807 char name[NAME_MAX];
808
809 /* Search for "opp-microvolt-<name>" */
810 if (dev_opp->prop_name) {
811 snprintf(name, sizeof(name), "opp-microvolt-%s",
812 dev_opp->prop_name);
813 prop = of_find_property(opp->np, name, NULL);
814 }
784 815
785 /* Missing property isn't a problem, but an invalid entry is */ 816 if (!prop) {
786 if (!of_find_property(opp->np, "opp-microvolt", NULL)) 817 /* Search for "opp-microvolt" */
787 return 0; 818 sprintf(name, "opp-microvolt");
819 prop = of_find_property(opp->np, name, NULL);
788 820
789 count = of_property_count_u32_elems(opp->np, "opp-microvolt"); 821 /* Missing property isn't a problem, but an invalid entry is */
822 if (!prop)
823 return 0;
824 }
825
826 count = of_property_count_u32_elems(opp->np, name);
790 if (count < 0) { 827 if (count < 0) {
791 dev_err(dev, "%s: Invalid opp-microvolt property (%d)\n", 828 dev_err(dev, "%s: Invalid %s property (%d)\n",
792 __func__, count); 829 __func__, name, count);
793 return count; 830 return count;
794 } 831 }
795 832
796 /* There can be one or three elements here */ 833 /* There can be one or three elements here */
797 if (count != 1 && count != 3) { 834 if (count != 1 && count != 3) {
798 dev_err(dev, "%s: Invalid number of elements in opp-microvolt property (%d)\n", 835 dev_err(dev, "%s: Invalid number of elements in %s property (%d)\n",
799 __func__, count); 836 __func__, name, count);
800 return -EINVAL; 837 return -EINVAL;
801 } 838 }
802 839
803 ret = of_property_read_u32_array(opp->np, "opp-microvolt", microvolt, 840 ret = of_property_read_u32_array(opp->np, name, microvolt, count);
804 count);
805 if (ret) { 841 if (ret) {
806 dev_err(dev, "%s: error parsing opp-microvolt: %d\n", __func__, 842 dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
807 ret);
808 return -EINVAL; 843 return -EINVAL;
809 } 844 }
810 845
@@ -812,13 +847,272 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev)
812 opp->u_volt_min = microvolt[1]; 847 opp->u_volt_min = microvolt[1];
813 opp->u_volt_max = microvolt[2]; 848 opp->u_volt_max = microvolt[2];
814 849
815 if (!of_property_read_u32(opp->np, "opp-microamp", &val)) 850 /* Search for "opp-microamp-<name>" */
851 prop = NULL;
852 if (dev_opp->prop_name) {
853 snprintf(name, sizeof(name), "opp-microamp-%s",
854 dev_opp->prop_name);
855 prop = of_find_property(opp->np, name, NULL);
856 }
857
858 if (!prop) {
859 /* Search for "opp-microamp" */
860 sprintf(name, "opp-microamp");
861 prop = of_find_property(opp->np, name, NULL);
862 }
863
864 if (prop && !of_property_read_u32(opp->np, name, &val))
816 opp->u_amp = val; 865 opp->u_amp = val;
817 866
818 return 0; 867 return 0;
819} 868}
820 869
821/** 870/**
871 * dev_pm_opp_set_supported_hw() - Set supported platforms
872 * @dev: Device for which supported-hw has to be set.
873 * @versions: Array of hierarchy of versions to match.
874 * @count: Number of elements in the array.
875 *
876 * This is required only for the V2 bindings, and it enables a platform to
877 * specify the hierarchy of versions it supports. OPP layer will then enable
878 * OPPs, which are available for those versions, based on its 'opp-supported-hw'
879 * property.
880 *
881 * Locking: The internal device_opp and opp structures are RCU protected.
882 * Hence this function internally uses RCU updater strategy with mutex locks
883 * to keep the integrity of the internal data structures. Callers should ensure
884 * that this function is *NOT* called under RCU protection or in contexts where
885 * mutex cannot be locked.
886 */
887int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
888 unsigned int count)
889{
890 struct device_opp *dev_opp;
891 int ret = 0;
892
893 /* Hold our list modification lock here */
894 mutex_lock(&dev_opp_list_lock);
895
896 dev_opp = _add_device_opp(dev);
897 if (!dev_opp) {
898 ret = -ENOMEM;
899 goto unlock;
900 }
901
902 /* Make sure there are no concurrent readers while updating dev_opp */
903 WARN_ON(!list_empty(&dev_opp->opp_list));
904
905 /* Do we already have a version hierarchy associated with dev_opp? */
906 if (dev_opp->supported_hw) {
907 dev_err(dev, "%s: Already have supported hardware list\n",
908 __func__);
909 ret = -EBUSY;
910 goto err;
911 }
912
913 dev_opp->supported_hw = kmemdup(versions, count * sizeof(*versions),
914 GFP_KERNEL);
915 if (!dev_opp->supported_hw) {
916 ret = -ENOMEM;
917 goto err;
918 }
919
920 dev_opp->supported_hw_count = count;
921 mutex_unlock(&dev_opp_list_lock);
922 return 0;
923
924err:
925 _remove_device_opp(dev_opp);
926unlock:
927 mutex_unlock(&dev_opp_list_lock);
928
929 return ret;
930}
931EXPORT_SYMBOL_GPL(dev_pm_opp_set_supported_hw);
932
933/**
934 * dev_pm_opp_put_supported_hw() - Releases resources blocked for supported hw
935 * @dev: Device for which supported-hw has to be set.
936 *
937 * This is required only for the V2 bindings, and is called for a matching
938 * dev_pm_opp_set_supported_hw(). Until this is called, the device_opp structure
939 * will not be freed.
940 *
941 * Locking: The internal device_opp and opp structures are RCU protected.
942 * Hence this function internally uses RCU updater strategy with mutex locks
943 * to keep the integrity of the internal data structures. Callers should ensure
944 * that this function is *NOT* called under RCU protection or in contexts where
945 * mutex cannot be locked.
946 */
947void dev_pm_opp_put_supported_hw(struct device *dev)
948{
949 struct device_opp *dev_opp;
950
951 /* Hold our list modification lock here */
952 mutex_lock(&dev_opp_list_lock);
953
954 /* Check for existing list for 'dev' first */
955 dev_opp = _find_device_opp(dev);
956 if (IS_ERR(dev_opp)) {
957 dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));
958 goto unlock;
959 }
960
961 /* Make sure there are no concurrent readers while updating dev_opp */
962 WARN_ON(!list_empty(&dev_opp->opp_list));
963
964 if (!dev_opp->supported_hw) {
965 dev_err(dev, "%s: Doesn't have supported hardware list\n",
966 __func__);
967 goto unlock;
968 }
969
970 kfree(dev_opp->supported_hw);
971 dev_opp->supported_hw = NULL;
972 dev_opp->supported_hw_count = 0;
973
974 /* Try freeing device_opp if this was the last blocking resource */
975 _remove_device_opp(dev_opp);
976
977unlock:
978 mutex_unlock(&dev_opp_list_lock);
979}
980EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
981
982/**
983 * dev_pm_opp_set_prop_name() - Set prop-extn name
984 * @dev: Device for which the regulator has to be set.
985 * @name: name to postfix to properties.
986 *
987 * This is required only for the V2 bindings, and it enables a platform to
988 * specify the extn to be used for certain property names. The properties to
989 * which the extension will apply are opp-microvolt and opp-microamp. OPP core
990 * should postfix the property name with -<name> while looking for them.
991 *
992 * Locking: The internal device_opp and opp structures are RCU protected.
993 * Hence this function internally uses RCU updater strategy with mutex locks
994 * to keep the integrity of the internal data structures. Callers should ensure
995 * that this function is *NOT* called under RCU protection or in contexts where
996 * mutex cannot be locked.
997 */
998int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
999{
1000 struct device_opp *dev_opp;
1001 int ret = 0;
1002
1003 /* Hold our list modification lock here */
1004 mutex_lock(&dev_opp_list_lock);
1005
1006 dev_opp = _add_device_opp(dev);
1007 if (!dev_opp) {
1008 ret = -ENOMEM;
1009 goto unlock;
1010 }
1011
1012 /* Make sure there are no concurrent readers while updating dev_opp */
1013 WARN_ON(!list_empty(&dev_opp->opp_list));
1014
1015 /* Do we already have a prop-name associated with dev_opp? */
1016 if (dev_opp->prop_name) {
1017 dev_err(dev, "%s: Already have prop-name %s\n", __func__,
1018 dev_opp->prop_name);
1019 ret = -EBUSY;
1020 goto err;
1021 }
1022
1023 dev_opp->prop_name = kstrdup(name, GFP_KERNEL);
1024 if (!dev_opp->prop_name) {
1025 ret = -ENOMEM;
1026 goto err;
1027 }
1028
1029 mutex_unlock(&dev_opp_list_lock);
1030 return 0;
1031
1032err:
1033 _remove_device_opp(dev_opp);
1034unlock:
1035 mutex_unlock(&dev_opp_list_lock);
1036
1037 return ret;
1038}
1039EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name);
1040
1041/**
1042 * dev_pm_opp_put_prop_name() - Releases resources blocked for prop-name
1043 * @dev: Device for which the regulator has to be set.
1044 *
1045 * This is required only for the V2 bindings, and is called for a matching
1046 * dev_pm_opp_set_prop_name(). Until this is called, the device_opp structure
1047 * will not be freed.
1048 *
1049 * Locking: The internal device_opp and opp structures are RCU protected.
1050 * Hence this function internally uses RCU updater strategy with mutex locks
1051 * to keep the integrity of the internal data structures. Callers should ensure
1052 * that this function is *NOT* called under RCU protection or in contexts where
1053 * mutex cannot be locked.
1054 */
1055void dev_pm_opp_put_prop_name(struct device *dev)
1056{
1057 struct device_opp *dev_opp;
1058
1059 /* Hold our list modification lock here */
1060 mutex_lock(&dev_opp_list_lock);
1061
1062 /* Check for existing list for 'dev' first */
1063 dev_opp = _find_device_opp(dev);
1064 if (IS_ERR(dev_opp)) {
1065 dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));
1066 goto unlock;
1067 }
1068
1069 /* Make sure there are no concurrent readers while updating dev_opp */
1070 WARN_ON(!list_empty(&dev_opp->opp_list));
1071
1072 if (!dev_opp->prop_name) {
1073 dev_err(dev, "%s: Doesn't have a prop-name\n", __func__);
1074 goto unlock;
1075 }
1076
1077 kfree(dev_opp->prop_name);
1078 dev_opp->prop_name = NULL;
1079
1080 /* Try freeing device_opp if this was the last blocking resource */
1081 _remove_device_opp(dev_opp);
1082
1083unlock:
1084 mutex_unlock(&dev_opp_list_lock);
1085}
1086EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
1087
1088static bool _opp_is_supported(struct device *dev, struct device_opp *dev_opp,
1089 struct device_node *np)
1090{
1091 unsigned int count = dev_opp->supported_hw_count;
1092 u32 version;
1093 int ret;
1094
1095 if (!dev_opp->supported_hw)
1096 return true;
1097
1098 while (count--) {
1099 ret = of_property_read_u32_index(np, "opp-supported-hw", count,
1100 &version);
1101 if (ret) {
1102 dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n",
1103 __func__, count, ret);
1104 return false;
1105 }
1106
1107 /* Both of these are bitwise masks of the versions */
1108 if (!(version & dev_opp->supported_hw[count]))
1109 return false;
1110 }
1111
1112 return true;
1113}
1114
1115/**
822 * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings) 1116 * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
823 * @dev: device for which we do this operation 1117 * @dev: device for which we do this operation
824 * @np: device node 1118 * @np: device node
@@ -864,6 +1158,12 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
864 goto free_opp; 1158 goto free_opp;
865 } 1159 }
866 1160
1161 /* Check if the OPP supports hardware's hierarchy of versions or not */
1162 if (!_opp_is_supported(dev, dev_opp, np)) {
1163 dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate);
1164 goto free_opp;
1165 }
1166
867 /* 1167 /*
868 * Rate is defined as an unsigned long in clk API, and so casting 1168 * Rate is defined as an unsigned long in clk API, and so casting
869 * explicitly to its type. Must be fixed once rate is 64 bit 1169 * explicitly to its type. Must be fixed once rate is 64 bit
@@ -879,7 +1179,7 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
879 if (!of_property_read_u32(np, "clock-latency-ns", &val)) 1179 if (!of_property_read_u32(np, "clock-latency-ns", &val))
880 new_opp->clock_latency_ns = val; 1180 new_opp->clock_latency_ns = val;
881 1181
882 ret = opp_parse_supplies(new_opp, dev); 1182 ret = opp_parse_supplies(new_opp, dev, dev_opp);
883 if (ret) 1183 if (ret)
884 goto free_opp; 1184 goto free_opp;
885 1185
@@ -889,12 +1189,14 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
889 1189
890 /* OPP to select on device suspend */ 1190 /* OPP to select on device suspend */
891 if (of_property_read_bool(np, "opp-suspend")) { 1191 if (of_property_read_bool(np, "opp-suspend")) {
892 if (dev_opp->suspend_opp) 1192 if (dev_opp->suspend_opp) {
893 dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n", 1193 dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n",
894 __func__, dev_opp->suspend_opp->rate, 1194 __func__, dev_opp->suspend_opp->rate,
895 new_opp->rate); 1195 new_opp->rate);
896 else 1196 } else {
1197 new_opp->suspend = true;
897 dev_opp->suspend_opp = new_opp; 1198 dev_opp->suspend_opp = new_opp;
1199 }
898 } 1200 }
899 1201
900 if (new_opp->clock_latency_ns > dev_opp->clock_latency_ns_max) 1202 if (new_opp->clock_latency_ns > dev_opp->clock_latency_ns_max)
diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c
index 7b445e88a0d5..9f0c15570f64 100644
--- a/drivers/base/power/opp/cpu.c
+++ b/drivers/base/power/opp/cpu.c
@@ -214,7 +214,6 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table);
214/* 214/*
215 * Works only for OPP v2 bindings. 215 * Works only for OPP v2 bindings.
216 * 216 *
217 * cpumask should be already set to mask of cpu_dev->id.
218 * Returns -ENOENT if operating-points-v2 bindings aren't supported. 217 * Returns -ENOENT if operating-points-v2 bindings aren't supported.
219 */ 218 */
220int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask) 219int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
@@ -230,6 +229,8 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask
230 return -ENOENT; 229 return -ENOENT;
231 } 230 }
232 231
232 cpumask_set_cpu(cpu_dev->id, cpumask);
233
233 /* OPPs are shared ? */ 234 /* OPPs are shared ? */
234 if (!of_property_read_bool(np, "opp-shared")) 235 if (!of_property_read_bool(np, "opp-shared"))
235 goto put_cpu_node; 236 goto put_cpu_node;
diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c
new file mode 100644
index 000000000000..ddfe4773e922
--- /dev/null
+++ b/drivers/base/power/opp/debugfs.c
@@ -0,0 +1,219 @@
1/*
2 * Generic OPP debugfs interface
3 *
4 * Copyright (C) 2015-2016 Viresh Kumar <viresh.kumar@linaro.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
13#include <linux/debugfs.h>
14#include <linux/device.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/limits.h>
18
19#include "opp.h"
20
21static struct dentry *rootdir;
22
23static void opp_set_dev_name(const struct device *dev, char *name)
24{
25 if (dev->parent)
26 snprintf(name, NAME_MAX, "%s-%s", dev_name(dev->parent),
27 dev_name(dev));
28 else
29 snprintf(name, NAME_MAX, "%s", dev_name(dev));
30}
31
32void opp_debug_remove_one(struct dev_pm_opp *opp)
33{
34 debugfs_remove_recursive(opp->dentry);
35}
36
37int opp_debug_create_one(struct dev_pm_opp *opp, struct device_opp *dev_opp)
38{
39 struct dentry *pdentry = dev_opp->dentry;
40 struct dentry *d;
41 char name[25]; /* 20 chars for 64 bit value + 5 (opp:\0) */
42
43 /* Rate is unique to each OPP, use it to give opp-name */
44 snprintf(name, sizeof(name), "opp:%lu", opp->rate);
45
46 /* Create per-opp directory */
47 d = debugfs_create_dir(name, pdentry);
48 if (!d)
49 return -ENOMEM;
50
51 if (!debugfs_create_bool("available", S_IRUGO, d, &opp->available))
52 return -ENOMEM;
53
54 if (!debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic))
55 return -ENOMEM;
56
57 if (!debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo))
58 return -ENOMEM;
59
60 if (!debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend))
61 return -ENOMEM;
62
63 if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate))
64 return -ENOMEM;
65
66 if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d, &opp->u_volt))
67 return -ENOMEM;
68
69 if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d, &opp->u_volt_min))
70 return -ENOMEM;
71
72 if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d, &opp->u_volt_max))
73 return -ENOMEM;
74
75 if (!debugfs_create_ulong("u_amp", S_IRUGO, d, &opp->u_amp))
76 return -ENOMEM;
77
78 if (!debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
79 &opp->clock_latency_ns))
80 return -ENOMEM;
81
82 opp->dentry = d;
83 return 0;
84}
85
86static int device_opp_debug_create_dir(struct device_list_opp *list_dev,
87 struct device_opp *dev_opp)
88{
89 const struct device *dev = list_dev->dev;
90 struct dentry *d;
91
92 opp_set_dev_name(dev, dev_opp->dentry_name);
93
94 /* Create device specific directory */
95 d = debugfs_create_dir(dev_opp->dentry_name, rootdir);
96 if (!d) {
97 dev_err(dev, "%s: Failed to create debugfs dir\n", __func__);
98 return -ENOMEM;
99 }
100
101 list_dev->dentry = d;
102 dev_opp->dentry = d;
103
104 return 0;
105}
106
107static int device_opp_debug_create_link(struct device_list_opp *list_dev,
108 struct device_opp *dev_opp)
109{
110 const struct device *dev = list_dev->dev;
111 char name[NAME_MAX];
112 struct dentry *d;
113
114 opp_set_dev_name(list_dev->dev, name);
115
116 /* Create device specific directory link */
117 d = debugfs_create_symlink(name, rootdir, dev_opp->dentry_name);
118 if (!d) {
119 dev_err(dev, "%s: Failed to create link\n", __func__);
120 return -ENOMEM;
121 }
122
123 list_dev->dentry = d;
124
125 return 0;
126}
127
128/**
129 * opp_debug_register - add a device opp node to the debugfs 'opp' directory
130 * @list_dev: list-dev pointer for device
131 * @dev_opp: the device-opp being added
132 *
133 * Dynamically adds device specific directory in debugfs 'opp' directory. If the
134 * device-opp is shared with other devices, then links will be created for all
135 * devices except the first.
136 *
137 * Return: 0 on success, otherwise negative error.
138 */
139int opp_debug_register(struct device_list_opp *list_dev,
140 struct device_opp *dev_opp)
141{
142 if (!rootdir) {
143 pr_debug("%s: Uninitialized rootdir\n", __func__);
144 return -EINVAL;
145 }
146
147 if (dev_opp->dentry)
148 return device_opp_debug_create_link(list_dev, dev_opp);
149
150 return device_opp_debug_create_dir(list_dev, dev_opp);
151}
152
153static void opp_migrate_dentry(struct device_list_opp *list_dev,
154 struct device_opp *dev_opp)
155{
156 struct device_list_opp *new_dev;
157 const struct device *dev;
158 struct dentry *dentry;
159
160 /* Look for next list-dev */
161 list_for_each_entry(new_dev, &dev_opp->dev_list, node)
162 if (new_dev != list_dev)
163 break;
164
165 /* new_dev is guaranteed to be valid here */
166 dev = new_dev->dev;
167 debugfs_remove_recursive(new_dev->dentry);
168
169 opp_set_dev_name(dev, dev_opp->dentry_name);
170
171 dentry = debugfs_rename(rootdir, list_dev->dentry, rootdir,
172 dev_opp->dentry_name);
173 if (!dentry) {
174 dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
175 __func__, dev_name(list_dev->dev), dev_name(dev));
176 return;
177 }
178
179 new_dev->dentry = dentry;
180 dev_opp->dentry = dentry;
181}
182
183/**
184 * opp_debug_unregister - remove a device opp node from debugfs opp directory
185 * @list_dev: list-dev pointer for device
186 * @dev_opp: the device-opp being removed
187 *
188 * Dynamically removes device specific directory from debugfs 'opp' directory.
189 */
190void opp_debug_unregister(struct device_list_opp *list_dev,
191 struct device_opp *dev_opp)
192{
193 if (list_dev->dentry == dev_opp->dentry) {
194 /* Move the real dentry object under another device */
195 if (!list_is_singular(&dev_opp->dev_list)) {
196 opp_migrate_dentry(list_dev, dev_opp);
197 goto out;
198 }
199 dev_opp->dentry = NULL;
200 }
201
202 debugfs_remove_recursive(list_dev->dentry);
203
204out:
205 list_dev->dentry = NULL;
206}
207
208static int __init opp_debug_init(void)
209{
210 /* Create /sys/kernel/debug/opp directory */
211 rootdir = debugfs_create_dir("opp", NULL);
212 if (!rootdir) {
213 pr_err("%s: Failed to create root directory\n", __func__);
214 return -ENOMEM;
215 }
216
217 return 0;
218}
219core_initcall(opp_debug_init);
diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h
index 7366b2aa8997..690638ef36ee 100644
--- a/drivers/base/power/opp/opp.h
+++ b/drivers/base/power/opp/opp.h
@@ -17,6 +17,7 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/limits.h>
20#include <linux/pm_opp.h> 21#include <linux/pm_opp.h>
21#include <linux/rculist.h> 22#include <linux/rculist.h>
22#include <linux/rcupdate.h> 23#include <linux/rcupdate.h>
@@ -50,9 +51,10 @@ extern struct mutex dev_opp_list_lock;
50 * are protected by the dev_opp_list_lock for integrity. 51 * are protected by the dev_opp_list_lock for integrity.
51 * IMPORTANT: the opp nodes should be maintained in increasing 52 * IMPORTANT: the opp nodes should be maintained in increasing
52 * order. 53 * order.
53 * @dynamic: not-created from static DT entries.
54 * @available: true/false - marks if this OPP as available or not 54 * @available: true/false - marks if this OPP as available or not
55 * @dynamic: not-created from static DT entries.
55 * @turbo: true if turbo (boost) OPP 56 * @turbo: true if turbo (boost) OPP
57 * @suspend: true if suspend OPP
56 * @rate: Frequency in hertz 58 * @rate: Frequency in hertz
57 * @u_volt: Target voltage in microvolts corresponding to this OPP 59 * @u_volt: Target voltage in microvolts corresponding to this OPP
58 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP 60 * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
@@ -63,6 +65,7 @@ extern struct mutex dev_opp_list_lock;
63 * @dev_opp: points back to the device_opp struct this opp belongs to 65 * @dev_opp: points back to the device_opp struct this opp belongs to
64 * @rcu_head: RCU callback head used for deferred freeing 66 * @rcu_head: RCU callback head used for deferred freeing
65 * @np: OPP's device node. 67 * @np: OPP's device node.
68 * @dentry: debugfs dentry pointer (per opp)
66 * 69 *
67 * This structure stores the OPP information for a given device. 70 * This structure stores the OPP information for a given device.
68 */ 71 */
@@ -72,6 +75,7 @@ struct dev_pm_opp {
72 bool available; 75 bool available;
73 bool dynamic; 76 bool dynamic;
74 bool turbo; 77 bool turbo;
78 bool suspend;
75 unsigned long rate; 79 unsigned long rate;
76 80
77 unsigned long u_volt; 81 unsigned long u_volt;
@@ -84,6 +88,10 @@ struct dev_pm_opp {
84 struct rcu_head rcu_head; 88 struct rcu_head rcu_head;
85 89
86 struct device_node *np; 90 struct device_node *np;
91
92#ifdef CONFIG_DEBUG_FS
93 struct dentry *dentry;
94#endif
87}; 95};
88 96
89/** 97/**
@@ -91,6 +99,7 @@ struct dev_pm_opp {
91 * @node: list node 99 * @node: list node
92 * @dev: device to which the struct object belongs 100 * @dev: device to which the struct object belongs
93 * @rcu_head: RCU callback head used for deferred freeing 101 * @rcu_head: RCU callback head used for deferred freeing
102 * @dentry: debugfs dentry pointer (per device)
94 * 103 *
95 * This is an internal data structure maintaining the list of devices that are 104 * This is an internal data structure maintaining the list of devices that are
96 * managed by 'struct device_opp'. 105 * managed by 'struct device_opp'.
@@ -99,6 +108,10 @@ struct device_list_opp {
99 struct list_head node; 108 struct list_head node;
100 const struct device *dev; 109 const struct device *dev;
101 struct rcu_head rcu_head; 110 struct rcu_head rcu_head;
111
112#ifdef CONFIG_DEBUG_FS
113 struct dentry *dentry;
114#endif
102}; 115};
103 116
104/** 117/**
@@ -113,7 +126,14 @@ struct device_list_opp {
113 * @dev_list: list of devices that share these OPPs 126 * @dev_list: list of devices that share these OPPs
114 * @opp_list: list of opps 127 * @opp_list: list of opps
115 * @np: struct device_node pointer for opp's DT node. 128 * @np: struct device_node pointer for opp's DT node.
129 * @clock_latency_ns_max: Max clock latency in nanoseconds.
116 * @shared_opp: OPP is shared between multiple devices. 130 * @shared_opp: OPP is shared between multiple devices.
131 * @suspend_opp: Pointer to OPP to be used during device suspend.
132 * @supported_hw: Array of version number to support.
133 * @supported_hw_count: Number of elements in supported_hw array.
134 * @prop_name: A name to postfix to many DT properties, while parsing them.
135 * @dentry: debugfs dentry pointer of the real device directory (not links).
136 * @dentry_name: Name of the real dentry.
117 * 137 *
118 * This is an internal data structure maintaining the link to opps attached to 138 * This is an internal data structure maintaining the link to opps attached to
119 * a device. This structure is not meant to be shared to users as it is 139 * a device. This structure is not meant to be shared to users as it is
@@ -135,6 +155,15 @@ struct device_opp {
135 unsigned long clock_latency_ns_max; 155 unsigned long clock_latency_ns_max;
136 bool shared_opp; 156 bool shared_opp;
137 struct dev_pm_opp *suspend_opp; 157 struct dev_pm_opp *suspend_opp;
158
159 unsigned int *supported_hw;
160 unsigned int supported_hw_count;
161 const char *prop_name;
162
163#ifdef CONFIG_DEBUG_FS
164 struct dentry *dentry;
165 char dentry_name[NAME_MAX];
166#endif
138}; 167};
139 168
140/* Routines internal to opp core */ 169/* Routines internal to opp core */
@@ -143,4 +172,26 @@ struct device_list_opp *_add_list_dev(const struct device *dev,
143 struct device_opp *dev_opp); 172 struct device_opp *dev_opp);
144struct device_node *_of_get_opp_desc_node(struct device *dev); 173struct device_node *_of_get_opp_desc_node(struct device *dev);
145 174
175#ifdef CONFIG_DEBUG_FS
176void opp_debug_remove_one(struct dev_pm_opp *opp);
177int opp_debug_create_one(struct dev_pm_opp *opp, struct device_opp *dev_opp);
178int opp_debug_register(struct device_list_opp *list_dev,
179 struct device_opp *dev_opp);
180void opp_debug_unregister(struct device_list_opp *list_dev,
181 struct device_opp *dev_opp);
182#else
183static inline void opp_debug_remove_one(struct dev_pm_opp *opp) {}
184
185static inline int opp_debug_create_one(struct dev_pm_opp *opp,
186 struct device_opp *dev_opp)
187{ return 0; }
188static inline int opp_debug_register(struct device_list_opp *list_dev,
189 struct device_opp *dev_opp)
190{ return 0; }
191
192static inline void opp_debug_unregister(struct device_list_opp *list_dev,
193 struct device_opp *dev_opp)
194{ }
195#endif /* DEBUG_FS */
196
146#endif /* __DRIVER_OPP_H__ */ 197#endif /* __DRIVER_OPP_H__ */
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 9a2e50337af9..95403d2ccaf5 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -55,6 +55,11 @@ int dev_pm_opp_enable(struct device *dev, unsigned long freq);
55int dev_pm_opp_disable(struct device *dev, unsigned long freq); 55int dev_pm_opp_disable(struct device *dev, unsigned long freq);
56 56
57struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); 57struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev);
58int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
59 unsigned int count);
60void dev_pm_opp_put_supported_hw(struct device *dev);
61int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
62void dev_pm_opp_put_prop_name(struct device *dev);
58#else 63#else
59static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) 64static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
60{ 65{
@@ -129,6 +134,23 @@ static inline struct srcu_notifier_head *dev_pm_opp_get_notifier(
129{ 134{
130 return ERR_PTR(-EINVAL); 135 return ERR_PTR(-EINVAL);
131} 136}
137
138static inline int dev_pm_opp_set_supported_hw(struct device *dev,
139 const u32 *versions,
140 unsigned int count)
141{
142 return -EINVAL;
143}
144
145static inline void dev_pm_opp_put_supported_hw(struct device *dev) {}
146
147static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
148{
149 return -EINVAL;
150}
151
152static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
153
132#endif /* CONFIG_PM_OPP */ 154#endif /* CONFIG_PM_OPP */
133 155
134#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 156#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)