diff options
-rw-r--r-- | Documentation/devicetree/bindings/opp/opp.txt | 44 | ||||
-rw-r--r-- | Documentation/power/pm_qos_interface.txt | 13 | ||||
-rw-r--r-- | Documentation/power/runtime_pm.txt | 6 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 178 | ||||
-rw-r--r-- | drivers/base/power/opp/core.c | 3 | ||||
-rw-r--r-- | drivers/base/power/qos.c | 50 | ||||
-rw-r--r-- | include/linux/pm_qos.h | 8 |
7 files changed, 125 insertions, 177 deletions
diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt index 9f5ca4457b5f..7951961ef356 100644 --- a/Documentation/devicetree/bindings/opp/opp.txt +++ b/Documentation/devicetree/bindings/opp/opp.txt | |||
@@ -188,14 +188,14 @@ Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together. | |||
188 | 188 | ||
189 | opp@1000000000 { | 189 | opp@1000000000 { |
190 | opp-hz = /bits/ 64 <1000000000>; | 190 | opp-hz = /bits/ 64 <1000000000>; |
191 | opp-microvolt = <970000 975000 985000>; | 191 | opp-microvolt = <975000 970000 985000>; |
192 | opp-microamp = <70000>; | 192 | opp-microamp = <70000>; |
193 | clock-latency-ns = <300000>; | 193 | clock-latency-ns = <300000>; |
194 | opp-suspend; | 194 | opp-suspend; |
195 | }; | 195 | }; |
196 | opp@1100000000 { | 196 | opp@1100000000 { |
197 | opp-hz = /bits/ 64 <1100000000>; | 197 | opp-hz = /bits/ 64 <1100000000>; |
198 | opp-microvolt = <980000 1000000 1010000>; | 198 | opp-microvolt = <1000000 980000 1010000>; |
199 | opp-microamp = <80000>; | 199 | opp-microamp = <80000>; |
200 | clock-latency-ns = <310000>; | 200 | clock-latency-ns = <310000>; |
201 | }; | 201 | }; |
@@ -267,14 +267,14 @@ independently. | |||
267 | 267 | ||
268 | opp@1000000000 { | 268 | opp@1000000000 { |
269 | opp-hz = /bits/ 64 <1000000000>; | 269 | opp-hz = /bits/ 64 <1000000000>; |
270 | opp-microvolt = <970000 975000 985000>; | 270 | opp-microvolt = <975000 970000 985000>; |
271 | opp-microamp = <70000>; | 271 | opp-microamp = <70000>; |
272 | clock-latency-ns = <300000>; | 272 | clock-latency-ns = <300000>; |
273 | opp-suspend; | 273 | opp-suspend; |
274 | }; | 274 | }; |
275 | opp@1100000000 { | 275 | opp@1100000000 { |
276 | opp-hz = /bits/ 64 <1100000000>; | 276 | opp-hz = /bits/ 64 <1100000000>; |
277 | opp-microvolt = <980000 1000000 1010000>; | 277 | opp-microvolt = <1000000 980000 1010000>; |
278 | opp-microamp = <80000>; | 278 | opp-microamp = <80000>; |
279 | clock-latency-ns = <310000>; | 279 | clock-latency-ns = <310000>; |
280 | }; | 280 | }; |
@@ -343,14 +343,14 @@ DVFS state together. | |||
343 | 343 | ||
344 | opp@1000000000 { | 344 | opp@1000000000 { |
345 | opp-hz = /bits/ 64 <1000000000>; | 345 | opp-hz = /bits/ 64 <1000000000>; |
346 | opp-microvolt = <970000 975000 985000>; | 346 | opp-microvolt = <975000 970000 985000>; |
347 | opp-microamp = <70000>; | 347 | opp-microamp = <70000>; |
348 | clock-latency-ns = <300000>; | 348 | clock-latency-ns = <300000>; |
349 | opp-suspend; | 349 | opp-suspend; |
350 | }; | 350 | }; |
351 | opp@1100000000 { | 351 | opp@1100000000 { |
352 | opp-hz = /bits/ 64 <1100000000>; | 352 | opp-hz = /bits/ 64 <1100000000>; |
353 | opp-microvolt = <980000 1000000 1010000>; | 353 | opp-microvolt = <1000000 980000 1010000>; |
354 | opp-microamp = <80000>; | 354 | opp-microamp = <80000>; |
355 | clock-latency-ns = <310000>; | 355 | clock-latency-ns = <310000>; |
356 | }; | 356 | }; |
@@ -369,7 +369,7 @@ DVFS state together. | |||
369 | 369 | ||
370 | opp@1300000000 { | 370 | opp@1300000000 { |
371 | opp-hz = /bits/ 64 <1300000000>; | 371 | opp-hz = /bits/ 64 <1300000000>; |
372 | opp-microvolt = <1045000 1050000 1055000>; | 372 | opp-microvolt = <1050000 1045000 1055000>; |
373 | opp-microamp = <95000>; | 373 | opp-microamp = <95000>; |
374 | clock-latency-ns = <400000>; | 374 | clock-latency-ns = <400000>; |
375 | opp-suspend; | 375 | opp-suspend; |
@@ -382,7 +382,7 @@ DVFS state together. | |||
382 | }; | 382 | }; |
383 | opp@1500000000 { | 383 | opp@1500000000 { |
384 | opp-hz = /bits/ 64 <1500000000>; | 384 | opp-hz = /bits/ 64 <1500000000>; |
385 | opp-microvolt = <1010000 1100000 1110000>; | 385 | opp-microvolt = <1100000 1010000 1110000>; |
386 | opp-microamp = <95000>; | 386 | opp-microamp = <95000>; |
387 | clock-latency-ns = <400000>; | 387 | clock-latency-ns = <400000>; |
388 | turbo-mode; | 388 | turbo-mode; |
@@ -424,9 +424,9 @@ Example 4: Handling multiple regulators | |||
424 | 424 | ||
425 | opp@1000000000 { | 425 | opp@1000000000 { |
426 | opp-hz = /bits/ 64 <1000000000>; | 426 | opp-hz = /bits/ 64 <1000000000>; |
427 | opp-microvolt = <970000 975000 985000>, /* Supply 0 */ | 427 | opp-microvolt = <975000 970000 985000>, /* Supply 0 */ |
428 | <960000 965000 975000>, /* Supply 1 */ | 428 | <965000 960000 975000>, /* Supply 1 */ |
429 | <960000 965000 975000>; /* Supply 2 */ | 429 | <965000 960000 975000>; /* Supply 2 */ |
430 | opp-microamp = <70000>, /* Supply 0 */ | 430 | opp-microamp = <70000>, /* Supply 0 */ |
431 | <70000>, /* Supply 1 */ | 431 | <70000>, /* Supply 1 */ |
432 | <70000>; /* Supply 2 */ | 432 | <70000>; /* Supply 2 */ |
@@ -437,9 +437,9 @@ Example 4: Handling multiple regulators | |||
437 | 437 | ||
438 | opp@1000000000 { | 438 | opp@1000000000 { |
439 | opp-hz = /bits/ 64 <1000000000>; | 439 | opp-hz = /bits/ 64 <1000000000>; |
440 | opp-microvolt = <970000 975000 985000>, /* Supply 0 */ | 440 | opp-microvolt = <975000 970000 985000>, /* Supply 0 */ |
441 | <960000 965000 975000>, /* Supply 1 */ | 441 | <965000 960000 975000>, /* Supply 1 */ |
442 | <960000 965000 975000>; /* Supply 2 */ | 442 | <965000 960000 975000>; /* Supply 2 */ |
443 | opp-microamp = <70000>, /* Supply 0 */ | 443 | opp-microamp = <70000>, /* Supply 0 */ |
444 | <0>, /* Supply 1 doesn't need this */ | 444 | <0>, /* Supply 1 doesn't need this */ |
445 | <70000>; /* Supply 2 */ | 445 | <70000>; /* Supply 2 */ |
@@ -474,7 +474,7 @@ Example 5: opp-supported-hw | |||
474 | */ | 474 | */ |
475 | opp-supported-hw = <0xF 0xFFFFFFFF 0xFFFFFFFF> | 475 | opp-supported-hw = <0xF 0xFFFFFFFF 0xFFFFFFFF> |
476 | opp-hz = /bits/ 64 <600000000>; | 476 | opp-hz = /bits/ 64 <600000000>; |
477 | opp-microvolt = <900000 915000 925000>; | 477 | opp-microvolt = <915000 900000 925000>; |
478 | ... | 478 | ... |
479 | }; | 479 | }; |
480 | 480 | ||
@@ -487,7 +487,7 @@ Example 5: opp-supported-hw | |||
487 | */ | 487 | */ |
488 | opp-supported-hw = <0x20 0xff0000ff 0x0000f4f0> | 488 | opp-supported-hw = <0x20 0xff0000ff 0x0000f4f0> |
489 | opp-hz = /bits/ 64 <800000000>; | 489 | opp-hz = /bits/ 64 <800000000>; |
490 | opp-microvolt = <900000 915000 925000>; | 490 | opp-microvolt = <915000 900000 925000>; |
491 | ... | 491 | ... |
492 | }; | 492 | }; |
493 | }; | 493 | }; |
@@ -512,18 +512,18 @@ Example 6: opp-microvolt-<name>, opp-microamp-<name>: | |||
512 | 512 | ||
513 | opp@1000000000 { | 513 | opp@1000000000 { |
514 | opp-hz = /bits/ 64 <1000000000>; | 514 | opp-hz = /bits/ 64 <1000000000>; |
515 | opp-microvolt-slow = <900000 915000 925000>; | 515 | opp-microvolt-slow = <915000 900000 925000>; |
516 | opp-microvolt-fast = <970000 975000 985000>; | 516 | opp-microvolt-fast = <975000 970000 985000>; |
517 | opp-microamp-slow = <70000>; | 517 | opp-microamp-slow = <70000>; |
518 | opp-microamp-fast = <71000>; | 518 | opp-microamp-fast = <71000>; |
519 | }; | 519 | }; |
520 | 520 | ||
521 | opp@1200000000 { | 521 | opp@1200000000 { |
522 | opp-hz = /bits/ 64 <1200000000>; | 522 | opp-hz = /bits/ 64 <1200000000>; |
523 | opp-microvolt-slow = <900000 915000 925000>, /* Supply vcc0 */ | 523 | opp-microvolt-slow = <915000 900000 925000>, /* Supply vcc0 */ |
524 | <910000 925000 935000>; /* Supply vcc1 */ | 524 | <925000 910000 935000>; /* Supply vcc1 */ |
525 | opp-microvolt-fast = <970000 975000 985000>, /* Supply vcc0 */ | 525 | opp-microvolt-fast = <975000 970000 985000>, /* Supply vcc0 */ |
526 | <960000 965000 975000>; /* Supply vcc1 */ | 526 | <965000 960000 975000>; /* Supply vcc1 */ |
527 | opp-microamp = <70000>; /* Will be used for both slow/fast */ | 527 | opp-microamp = <70000>; /* Will be used for both slow/fast */ |
528 | }; | 528 | }; |
529 | }; | 529 | }; |
diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 129f7c0e1483..21d2d48f87a2 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt | |||
@@ -163,8 +163,7 @@ of flags and remove sysfs attributes pm_qos_no_power_off and pm_qos_remote_wakeu | |||
163 | under the device's power directory. | 163 | under the device's power directory. |
164 | 164 | ||
165 | Notification mechanisms: | 165 | Notification mechanisms: |
166 | The per-device PM QoS framework has 2 different and distinct notification trees: | 166 | The per-device PM QoS framework has a per-device notification tree. |
167 | a per-device notification tree and a global notification tree. | ||
168 | 167 | ||
169 | int dev_pm_qos_add_notifier(device, notifier): | 168 | int dev_pm_qos_add_notifier(device, notifier): |
170 | Adds a notification callback function for the device. | 169 | Adds a notification callback function for the device. |
@@ -174,16 +173,6 @@ is changed (for resume latency device PM QoS only). | |||
174 | int dev_pm_qos_remove_notifier(device, notifier): | 173 | int dev_pm_qos_remove_notifier(device, notifier): |
175 | Removes the notification callback function for the device. | 174 | Removes the notification callback function for the device. |
176 | 175 | ||
177 | int dev_pm_qos_add_global_notifier(notifier): | ||
178 | Adds a notification callback function in the global notification tree of the | ||
179 | framework. | ||
180 | The callback is called when the aggregated value for any device is changed | ||
181 | (for resume latency device PM QoS only). | ||
182 | |||
183 | int dev_pm_qos_remove_global_notifier(notifier): | ||
184 | Removes the notification callback function from the global notification tree | ||
185 | of the framework. | ||
186 | |||
187 | 176 | ||
188 | Active state latency tolerance | 177 | Active state latency tolerance |
189 | 178 | ||
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 4870980e967e..64546eb9a16a 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
@@ -100,7 +100,7 @@ knows what to do to handle the device). | |||
100 | * If the suspend callback returns an error code different from -EBUSY and | 100 | * If the suspend callback returns an error code different from -EBUSY and |
101 | -EAGAIN, the PM core regards this as a fatal error and will refuse to run | 101 | -EAGAIN, the PM core regards this as a fatal error and will refuse to run |
102 | the helper functions described in Section 4 for the device until its status | 102 | the helper functions described in Section 4 for the device until its status |
103 | is directly set to either'active', or 'suspended' (the PM core provides | 103 | is directly set to either 'active', or 'suspended' (the PM core provides |
104 | special helper functions for this purpose). | 104 | special helper functions for this purpose). |
105 | 105 | ||
106 | In particular, if the driver requires remote wakeup capability (i.e. hardware | 106 | In particular, if the driver requires remote wakeup capability (i.e. hardware |
@@ -217,7 +217,7 @@ defined in include/linux/pm.h: | |||
217 | one to complete | 217 | one to complete |
218 | 218 | ||
219 | spinlock_t lock; | 219 | spinlock_t lock; |
220 | - lock used for synchronisation | 220 | - lock used for synchronization |
221 | 221 | ||
222 | atomic_t usage_count; | 222 | atomic_t usage_count; |
223 | - the usage counter of the device | 223 | - the usage counter of the device |
@@ -565,7 +565,7 @@ appropriate to ensure that the device is not put back to sleep during the | |||
565 | probe. This can happen with systems such as the network device layer. | 565 | probe. This can happen with systems such as the network device layer. |
566 | 566 | ||
567 | It may be desirable to suspend the device once ->probe() has finished. | 567 | It may be desirable to suspend the device once ->probe() has finished. |
568 | Therefore the driver core uses the asyncronous pm_request_idle() to submit a | 568 | Therefore the driver core uses the asynchronous pm_request_idle() to submit a |
569 | request to execute the subsystem-level idle callback for the device at that | 569 | request to execute the subsystem-level idle callback for the device at that |
570 | time. A driver that makes use of the runtime autosuspend feature, may want to | 570 | time. A driver that makes use of the runtime autosuspend feature, may want to |
571 | update the last busy mark before returning from ->probe(). | 571 | update the last busy mark before returning from ->probe(). |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 3a75fb1b4126..e697dec9d25b 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -274,6 +274,93 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) | |||
274 | } | 274 | } |
275 | 275 | ||
276 | /** | 276 | /** |
277 | * genpd_power_off - Remove power from a given PM domain. | ||
278 | * @genpd: PM domain to power down. | ||
279 | * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the | ||
280 | * RPM status of the releated device is in an intermediate state, not yet turned | ||
281 | * into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not | ||
282 | * be RPM_SUSPENDED, while it tries to power off the PM domain. | ||
283 | * | ||
284 | * If all of the @genpd's devices have been suspended and all of its subdomains | ||
285 | * have been powered down, remove power from @genpd. | ||
286 | */ | ||
287 | static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, | ||
288 | unsigned int depth) | ||
289 | { | ||
290 | struct pm_domain_data *pdd; | ||
291 | struct gpd_link *link; | ||
292 | unsigned int not_suspended = 0; | ||
293 | |||
294 | /* | ||
295 | * Do not try to power off the domain in the following situations: | ||
296 | * (1) The domain is already in the "power off" state. | ||
297 | * (2) System suspend is in progress. | ||
298 | */ | ||
299 | if (genpd->status == GPD_STATE_POWER_OFF | ||
300 | || genpd->prepared_count > 0) | ||
301 | return 0; | ||
302 | |||
303 | if (atomic_read(&genpd->sd_count) > 0) | ||
304 | return -EBUSY; | ||
305 | |||
306 | list_for_each_entry(pdd, &genpd->dev_list, list_node) { | ||
307 | enum pm_qos_flags_status stat; | ||
308 | |||
309 | stat = dev_pm_qos_flags(pdd->dev, | ||
310 | PM_QOS_FLAG_NO_POWER_OFF | ||
311 | | PM_QOS_FLAG_REMOTE_WAKEUP); | ||
312 | if (stat > PM_QOS_FLAGS_NONE) | ||
313 | return -EBUSY; | ||
314 | |||
315 | /* | ||
316 | * Do not allow PM domain to be powered off, when an IRQ safe | ||
317 | * device is part of a non-IRQ safe domain. | ||
318 | */ | ||
319 | if (!pm_runtime_suspended(pdd->dev) || | ||
320 | irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) | ||
321 | not_suspended++; | ||
322 | } | ||
323 | |||
324 | if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on)) | ||
325 | return -EBUSY; | ||
326 | |||
327 | if (genpd->gov && genpd->gov->power_down_ok) { | ||
328 | if (!genpd->gov->power_down_ok(&genpd->domain)) | ||
329 | return -EAGAIN; | ||
330 | } | ||
331 | |||
332 | if (genpd->power_off) { | ||
333 | int ret; | ||
334 | |||
335 | if (atomic_read(&genpd->sd_count) > 0) | ||
336 | return -EBUSY; | ||
337 | |||
338 | /* | ||
339 | * If sd_count > 0 at this point, one of the subdomains hasn't | ||
340 | * managed to call genpd_power_on() for the master yet after | ||
341 | * incrementing it. In that case genpd_power_on() will wait | ||
342 | * for us to drop the lock, so we can call .power_off() and let | ||
343 | * the genpd_power_on() restore power for us (this shouldn't | ||
344 | * happen very often). | ||
345 | */ | ||
346 | ret = _genpd_power_off(genpd, true); | ||
347 | if (ret) | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | genpd->status = GPD_STATE_POWER_OFF; | ||
352 | |||
353 | list_for_each_entry(link, &genpd->slave_links, slave_node) { | ||
354 | genpd_sd_counter_dec(link->master); | ||
355 | genpd_lock_nested(link->master, depth + 1); | ||
356 | genpd_power_off(link->master, false, depth + 1); | ||
357 | genpd_unlock(link->master); | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | /** | ||
277 | * genpd_power_on - Restore power to a given PM domain and its masters. | 364 | * genpd_power_on - Restore power to a given PM domain and its masters. |
278 | * @genpd: PM domain to power up. | 365 | * @genpd: PM domain to power up. |
279 | * @depth: nesting count for lockdep. | 366 | * @depth: nesting count for lockdep. |
@@ -321,7 +408,9 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) | |||
321 | &genpd->slave_links, | 408 | &genpd->slave_links, |
322 | slave_node) { | 409 | slave_node) { |
323 | genpd_sd_counter_dec(link->master); | 410 | genpd_sd_counter_dec(link->master); |
324 | genpd_queue_power_off_work(link->master); | 411 | genpd_lock_nested(link->master, depth + 1); |
412 | genpd_power_off(link->master, false, depth + 1); | ||
413 | genpd_unlock(link->master); | ||
325 | } | 414 | } |
326 | 415 | ||
327 | return ret; | 416 | return ret; |
@@ -368,87 +457,6 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, | |||
368 | } | 457 | } |
369 | 458 | ||
370 | /** | 459 | /** |
371 | * genpd_power_off - Remove power from a given PM domain. | ||
372 | * @genpd: PM domain to power down. | ||
373 | * @is_async: PM domain is powered down from a scheduled work | ||
374 | * | ||
375 | * If all of the @genpd's devices have been suspended and all of its subdomains | ||
376 | * have been powered down, remove power from @genpd. | ||
377 | */ | ||
378 | static int genpd_power_off(struct generic_pm_domain *genpd, bool is_async) | ||
379 | { | ||
380 | struct pm_domain_data *pdd; | ||
381 | struct gpd_link *link; | ||
382 | unsigned int not_suspended = 0; | ||
383 | |||
384 | /* | ||
385 | * Do not try to power off the domain in the following situations: | ||
386 | * (1) The domain is already in the "power off" state. | ||
387 | * (2) System suspend is in progress. | ||
388 | */ | ||
389 | if (genpd->status == GPD_STATE_POWER_OFF | ||
390 | || genpd->prepared_count > 0) | ||
391 | return 0; | ||
392 | |||
393 | if (atomic_read(&genpd->sd_count) > 0) | ||
394 | return -EBUSY; | ||
395 | |||
396 | list_for_each_entry(pdd, &genpd->dev_list, list_node) { | ||
397 | enum pm_qos_flags_status stat; | ||
398 | |||
399 | stat = dev_pm_qos_flags(pdd->dev, | ||
400 | PM_QOS_FLAG_NO_POWER_OFF | ||
401 | | PM_QOS_FLAG_REMOTE_WAKEUP); | ||
402 | if (stat > PM_QOS_FLAGS_NONE) | ||
403 | return -EBUSY; | ||
404 | |||
405 | /* | ||
406 | * Do not allow PM domain to be powered off, when an IRQ safe | ||
407 | * device is part of a non-IRQ safe domain. | ||
408 | */ | ||
409 | if (!pm_runtime_suspended(pdd->dev) || | ||
410 | irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) | ||
411 | not_suspended++; | ||
412 | } | ||
413 | |||
414 | if (not_suspended > 1 || (not_suspended == 1 && is_async)) | ||
415 | return -EBUSY; | ||
416 | |||
417 | if (genpd->gov && genpd->gov->power_down_ok) { | ||
418 | if (!genpd->gov->power_down_ok(&genpd->domain)) | ||
419 | return -EAGAIN; | ||
420 | } | ||
421 | |||
422 | if (genpd->power_off) { | ||
423 | int ret; | ||
424 | |||
425 | if (atomic_read(&genpd->sd_count) > 0) | ||
426 | return -EBUSY; | ||
427 | |||
428 | /* | ||
429 | * If sd_count > 0 at this point, one of the subdomains hasn't | ||
430 | * managed to call genpd_power_on() for the master yet after | ||
431 | * incrementing it. In that case genpd_power_on() will wait | ||
432 | * for us to drop the lock, so we can call .power_off() and let | ||
433 | * the genpd_power_on() restore power for us (this shouldn't | ||
434 | * happen very often). | ||
435 | */ | ||
436 | ret = _genpd_power_off(genpd, true); | ||
437 | if (ret) | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | genpd->status = GPD_STATE_POWER_OFF; | ||
442 | |||
443 | list_for_each_entry(link, &genpd->slave_links, slave_node) { | ||
444 | genpd_sd_counter_dec(link->master); | ||
445 | genpd_queue_power_off_work(link->master); | ||
446 | } | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | /** | ||
452 | * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0. | 460 | * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0. |
453 | * @work: Work structure used for scheduling the execution of this function. | 461 | * @work: Work structure used for scheduling the execution of this function. |
454 | */ | 462 | */ |
@@ -459,7 +467,7 @@ static void genpd_power_off_work_fn(struct work_struct *work) | |||
459 | genpd = container_of(work, struct generic_pm_domain, power_off_work); | 467 | genpd = container_of(work, struct generic_pm_domain, power_off_work); |
460 | 468 | ||
461 | genpd_lock(genpd); | 469 | genpd_lock(genpd); |
462 | genpd_power_off(genpd, true); | 470 | genpd_power_off(genpd, false, 0); |
463 | genpd_unlock(genpd); | 471 | genpd_unlock(genpd); |
464 | } | 472 | } |
465 | 473 | ||
@@ -578,7 +586,7 @@ static int genpd_runtime_suspend(struct device *dev) | |||
578 | return 0; | 586 | return 0; |
579 | 587 | ||
580 | genpd_lock(genpd); | 588 | genpd_lock(genpd); |
581 | genpd_power_off(genpd, false); | 589 | genpd_power_off(genpd, true, 0); |
582 | genpd_unlock(genpd); | 590 | genpd_unlock(genpd); |
583 | 591 | ||
584 | return 0; | 592 | return 0; |
@@ -658,7 +666,7 @@ err_poweroff: | |||
658 | if (!pm_runtime_is_irq_safe(dev) || | 666 | if (!pm_runtime_is_irq_safe(dev) || |
659 | (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) { | 667 | (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) { |
660 | genpd_lock(genpd); | 668 | genpd_lock(genpd); |
661 | genpd_power_off(genpd, 0); | 669 | genpd_power_off(genpd, true, 0); |
662 | genpd_unlock(genpd); | 670 | genpd_unlock(genpd); |
663 | } | 671 | } |
664 | 672 | ||
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 91ec3232d630..dae61720b314 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c | |||
@@ -231,7 +231,8 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) | |||
231 | * The caller needs to ensure that opp_table (and hence the regulator) | 231 | * The caller needs to ensure that opp_table (and hence the regulator) |
232 | * isn't freed, while we are executing this routine. | 232 | * isn't freed, while we are executing this routine. |
233 | */ | 233 | */ |
234 | for (i = 0; reg = regulators[i], i < count; i++) { | 234 | for (i = 0; i < count; i++) { |
235 | reg = regulators[i]; | ||
235 | ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max); | 236 | ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max); |
236 | if (ret > 0) | 237 | if (ret > 0) |
237 | latency_ns += ret * 1000; | 238 | latency_ns += ret * 1000; |
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index d888d9869b6a..271bec73185e 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -17,12 +17,9 @@ | |||
17 | * | 17 | * |
18 | * This QoS design is best effort based. Dependents register their QoS needs. | 18 | * This QoS design is best effort based. Dependents register their QoS needs. |
19 | * Watchers register to keep track of the current QoS needs of the system. | 19 | * Watchers register to keep track of the current QoS needs of the system. |
20 | * Watchers can register different types of notification callbacks: | 20 | * Watchers can register a per-device notification callback using the |
21 | * . a per-device notification callback using the dev_pm_qos_*_notifier API. | 21 | * dev_pm_qos_*_notifier API. The notification chain data is stored in the |
22 | * The notification chain data is stored in the per-device constraint | 22 | * per-device constraint data struct. |
23 | * data struct. | ||
24 | * . a system-wide notification callback using the dev_pm_qos_*_global_notifier | ||
25 | * API. The notification chain data is stored in a static variable. | ||
26 | * | 23 | * |
27 | * Note about the per-device constraint data struct allocation: | 24 | * Note about the per-device constraint data struct allocation: |
28 | * . The per-device constraints data struct ptr is tored into the device | 25 | * . The per-device constraints data struct ptr is tored into the device |
@@ -49,8 +46,6 @@ | |||
49 | static DEFINE_MUTEX(dev_pm_qos_mtx); | 46 | static DEFINE_MUTEX(dev_pm_qos_mtx); |
50 | static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx); | 47 | static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx); |
51 | 48 | ||
52 | static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); | ||
53 | |||
54 | /** | 49 | /** |
55 | * __dev_pm_qos_flags - Check PM QoS flags for a given device. | 50 | * __dev_pm_qos_flags - Check PM QoS flags for a given device. |
56 | * @dev: Device to check the PM QoS flags for. | 51 | * @dev: Device to check the PM QoS flags for. |
@@ -135,8 +130,7 @@ s32 dev_pm_qos_read_value(struct device *dev) | |||
135 | * @value: Value to assign to the QoS request. | 130 | * @value: Value to assign to the QoS request. |
136 | * | 131 | * |
137 | * Internal function to update the constraints list using the PM QoS core | 132 | * Internal function to update the constraints list using the PM QoS core |
138 | * code and if needed call the per-device and the global notification | 133 | * code and if needed call the per-device callbacks. |
139 | * callbacks | ||
140 | */ | 134 | */ |
141 | static int apply_constraint(struct dev_pm_qos_request *req, | 135 | static int apply_constraint(struct dev_pm_qos_request *req, |
142 | enum pm_qos_req_action action, s32 value) | 136 | enum pm_qos_req_action action, s32 value) |
@@ -148,12 +142,6 @@ static int apply_constraint(struct dev_pm_qos_request *req, | |||
148 | case DEV_PM_QOS_RESUME_LATENCY: | 142 | case DEV_PM_QOS_RESUME_LATENCY: |
149 | ret = pm_qos_update_target(&qos->resume_latency, | 143 | ret = pm_qos_update_target(&qos->resume_latency, |
150 | &req->data.pnode, action, value); | 144 | &req->data.pnode, action, value); |
151 | if (ret) { | ||
152 | value = pm_qos_read_value(&qos->resume_latency); | ||
153 | blocking_notifier_call_chain(&dev_pm_notifiers, | ||
154 | (unsigned long)value, | ||
155 | req); | ||
156 | } | ||
157 | break; | 145 | break; |
158 | case DEV_PM_QOS_LATENCY_TOLERANCE: | 146 | case DEV_PM_QOS_LATENCY_TOLERANCE: |
159 | ret = pm_qos_update_target(&qos->latency_tolerance, | 147 | ret = pm_qos_update_target(&qos->latency_tolerance, |
@@ -536,36 +524,6 @@ int dev_pm_qos_remove_notifier(struct device *dev, | |||
536 | EXPORT_SYMBOL_GPL(dev_pm_qos_remove_notifier); | 524 | EXPORT_SYMBOL_GPL(dev_pm_qos_remove_notifier); |
537 | 525 | ||
538 | /** | 526 | /** |
539 | * dev_pm_qos_add_global_notifier - sets notification entry for changes to | ||
540 | * target value of the PM QoS constraints for any device | ||
541 | * | ||
542 | * @notifier: notifier block managed by caller. | ||
543 | * | ||
544 | * Will register the notifier into a notification chain that gets called | ||
545 | * upon changes to the target value for any device. | ||
546 | */ | ||
547 | int dev_pm_qos_add_global_notifier(struct notifier_block *notifier) | ||
548 | { | ||
549 | return blocking_notifier_chain_register(&dev_pm_notifiers, notifier); | ||
550 | } | ||
551 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_global_notifier); | ||
552 | |||
553 | /** | ||
554 | * dev_pm_qos_remove_global_notifier - deletes notification for changes to | ||
555 | * target value of PM QoS constraints for any device | ||
556 | * | ||
557 | * @notifier: notifier block to be removed. | ||
558 | * | ||
559 | * Will remove the notifier from the notification chain that gets called | ||
560 | * upon changes to the target value for any device. | ||
561 | */ | ||
562 | int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier) | ||
563 | { | ||
564 | return blocking_notifier_chain_unregister(&dev_pm_notifiers, notifier); | ||
565 | } | ||
566 | EXPORT_SYMBOL_GPL(dev_pm_qos_remove_global_notifier); | ||
567 | |||
568 | /** | ||
569 | * dev_pm_qos_add_ancestor_request - Add PM QoS request for device's ancestor. | 527 | * dev_pm_qos_add_ancestor_request - Add PM QoS request for device's ancestor. |
570 | * @dev: Device whose ancestor to add the request for. | 528 | * @dev: Device whose ancestor to add the request for. |
571 | * @req: Pointer to the preallocated handle. | 529 | * @req: Pointer to the preallocated handle. |
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index d4d34791e463..3e2547d6e207 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h | |||
@@ -146,8 +146,6 @@ int dev_pm_qos_add_notifier(struct device *dev, | |||
146 | struct notifier_block *notifier); | 146 | struct notifier_block *notifier); |
147 | int dev_pm_qos_remove_notifier(struct device *dev, | 147 | int dev_pm_qos_remove_notifier(struct device *dev, |
148 | struct notifier_block *notifier); | 148 | struct notifier_block *notifier); |
149 | int dev_pm_qos_add_global_notifier(struct notifier_block *notifier); | ||
150 | int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier); | ||
151 | void dev_pm_qos_constraints_init(struct device *dev); | 149 | void dev_pm_qos_constraints_init(struct device *dev); |
152 | void dev_pm_qos_constraints_destroy(struct device *dev); | 150 | void dev_pm_qos_constraints_destroy(struct device *dev); |
153 | int dev_pm_qos_add_ancestor_request(struct device *dev, | 151 | int dev_pm_qos_add_ancestor_request(struct device *dev, |
@@ -199,12 +197,6 @@ static inline int dev_pm_qos_add_notifier(struct device *dev, | |||
199 | static inline int dev_pm_qos_remove_notifier(struct device *dev, | 197 | static inline int dev_pm_qos_remove_notifier(struct device *dev, |
200 | struct notifier_block *notifier) | 198 | struct notifier_block *notifier) |
201 | { return 0; } | 199 | { return 0; } |
202 | static inline int dev_pm_qos_add_global_notifier( | ||
203 | struct notifier_block *notifier) | ||
204 | { return 0; } | ||
205 | static inline int dev_pm_qos_remove_global_notifier( | ||
206 | struct notifier_block *notifier) | ||
207 | { return 0; } | ||
208 | static inline void dev_pm_qos_constraints_init(struct device *dev) | 200 | static inline void dev_pm_qos_constraints_init(struct device *dev) |
209 | { | 201 | { |
210 | dev->power.power_state = PMSG_ON; | 202 | dev->power.power_state = PMSG_ON; |