diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 23:26:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 23:26:16 -0400 |
commit | 11d8ec408d0aa2dae7ca89f95e497b8f22427b20 (patch) | |
tree | 88e7a8c08437f0bcaa747fc40c68604eb26fd431 /drivers/base | |
parent | 39fada55274241d50e27eb961cc9280b5b6121fb (diff) | |
parent | e2b3b80de5cda284c885721e873f9a6e90f68ef8 (diff) |
Merge tag 'pm-extra-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki:
"A few more fixes and cleanups in the x86-64 low-level hibernation
code, PM core, cpufreq (Kconfig and intel_pstate), and the operating
points framework.
Specifics:
- Prevent the low-level assembly hibernate code on x86-64 from
referring to __PAGE_OFFSET directly as a symbol which doesn't work
when the kernel identity mapping base is randomized, in which case
__PAGE_OFFSET is a variable (Rafael Wysocki).
- Avoid selecting CPU_FREQ_STAT by default as the statistics are not
required for proper cpufreq operation (Borislav Petkov).
- Add Skylake-X and Broadwell-X IDs to the intel_pstate's list of
processors where out-of-band (OBB) control of P-states is possible
and if that is in use, intel_pstate should not attempt to manage
P-states (Srinivas Pandruvada).
- Drop some unnecessary checks from the wakeup IRQ handling code in
the PM core (Markus Elfring).
- Reduce the number operating performance point (OPP) lookups in one
of the OPP framework's helper functions (Jisheng Zhang)"
* tag 'pm-extra-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
x86/power/64: Do not refer to __PAGE_OFFSET from assembly code
cpufreq: Do not default-yes CPU_FREQ_STAT
cpufreq: intel_pstate: Add more out-of-band IDs
PM / OPP: optimize dev_pm_opp_set_rate() performance a bit
PM-wakeup: Delete unnecessary checks before three function calls
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/opp/core.c | 31 | ||||
-rw-r--r-- | drivers/base/power/wakeup.c | 18 |
2 files changed, 26 insertions, 23 deletions
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 7c04c87738a6..df0c70963d9e 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c | |||
@@ -402,6 +402,22 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | |||
402 | } | 402 | } |
403 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); | 403 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); |
404 | 404 | ||
405 | static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, | ||
406 | unsigned long *freq) | ||
407 | { | ||
408 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | ||
409 | |||
410 | list_for_each_entry_rcu(temp_opp, &opp_table->opp_list, node) { | ||
411 | if (temp_opp->available && temp_opp->rate >= *freq) { | ||
412 | opp = temp_opp; | ||
413 | *freq = opp->rate; | ||
414 | break; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | return opp; | ||
419 | } | ||
420 | |||
405 | /** | 421 | /** |
406 | * dev_pm_opp_find_freq_ceil() - Search for an rounded ceil freq | 422 | * dev_pm_opp_find_freq_ceil() - Search for an rounded ceil freq |
407 | * @dev: device for which we do this operation | 423 | * @dev: device for which we do this operation |
@@ -427,7 +443,6 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, | |||
427 | unsigned long *freq) | 443 | unsigned long *freq) |
428 | { | 444 | { |
429 | struct opp_table *opp_table; | 445 | struct opp_table *opp_table; |
430 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | ||
431 | 446 | ||
432 | opp_rcu_lockdep_assert(); | 447 | opp_rcu_lockdep_assert(); |
433 | 448 | ||
@@ -440,15 +455,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, | |||
440 | if (IS_ERR(opp_table)) | 455 | if (IS_ERR(opp_table)) |
441 | return ERR_CAST(opp_table); | 456 | return ERR_CAST(opp_table); |
442 | 457 | ||
443 | list_for_each_entry_rcu(temp_opp, &opp_table->opp_list, node) { | 458 | return _find_freq_ceil(opp_table, freq); |
444 | if (temp_opp->available && temp_opp->rate >= *freq) { | ||
445 | opp = temp_opp; | ||
446 | *freq = opp->rate; | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | return opp; | ||
452 | } | 459 | } |
453 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); | 460 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); |
454 | 461 | ||
@@ -612,7 +619,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
612 | return PTR_ERR(opp_table); | 619 | return PTR_ERR(opp_table); |
613 | } | 620 | } |
614 | 621 | ||
615 | old_opp = dev_pm_opp_find_freq_ceil(dev, &old_freq); | 622 | old_opp = _find_freq_ceil(opp_table, &old_freq); |
616 | if (!IS_ERR(old_opp)) { | 623 | if (!IS_ERR(old_opp)) { |
617 | ou_volt = old_opp->u_volt; | 624 | ou_volt = old_opp->u_volt; |
618 | ou_volt_min = old_opp->u_volt_min; | 625 | ou_volt_min = old_opp->u_volt_min; |
@@ -622,7 +629,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
622 | __func__, old_freq, PTR_ERR(old_opp)); | 629 | __func__, old_freq, PTR_ERR(old_opp)); |
623 | } | 630 | } |
624 | 631 | ||
625 | opp = dev_pm_opp_find_freq_ceil(dev, &freq); | 632 | opp = _find_freq_ceil(opp_table, &freq); |
626 | if (IS_ERR(opp)) { | 633 | if (IS_ERR(opp)) { |
627 | ret = PTR_ERR(opp); | 634 | ret = PTR_ERR(opp); |
628 | dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", | 635 | dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5fb7718f256c..62e4de2aa8d1 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -334,10 +334,9 @@ void device_wakeup_arm_wake_irqs(void) | |||
334 | struct wakeup_source *ws; | 334 | struct wakeup_source *ws; |
335 | 335 | ||
336 | rcu_read_lock(); | 336 | rcu_read_lock(); |
337 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { | 337 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) |
338 | if (ws->wakeirq) | 338 | dev_pm_arm_wake_irq(ws->wakeirq); |
339 | dev_pm_arm_wake_irq(ws->wakeirq); | 339 | |
340 | } | ||
341 | rcu_read_unlock(); | 340 | rcu_read_unlock(); |
342 | } | 341 | } |
343 | 342 | ||
@@ -351,10 +350,9 @@ void device_wakeup_disarm_wake_irqs(void) | |||
351 | struct wakeup_source *ws; | 350 | struct wakeup_source *ws; |
352 | 351 | ||
353 | rcu_read_lock(); | 352 | rcu_read_lock(); |
354 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { | 353 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) |
355 | if (ws->wakeirq) | 354 | dev_pm_disarm_wake_irq(ws->wakeirq); |
356 | dev_pm_disarm_wake_irq(ws->wakeirq); | 355 | |
357 | } | ||
358 | rcu_read_unlock(); | 356 | rcu_read_unlock(); |
359 | } | 357 | } |
360 | 358 | ||
@@ -390,9 +388,7 @@ int device_wakeup_disable(struct device *dev) | |||
390 | return -EINVAL; | 388 | return -EINVAL; |
391 | 389 | ||
392 | ws = device_wakeup_detach(dev); | 390 | ws = device_wakeup_detach(dev); |
393 | if (ws) | 391 | wakeup_source_unregister(ws); |
394 | wakeup_source_unregister(ws); | ||
395 | |||
396 | return 0; | 392 | return 0; |
397 | } | 393 | } |
398 | EXPORT_SYMBOL_GPL(device_wakeup_disable); | 394 | EXPORT_SYMBOL_GPL(device_wakeup_disable); |