summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-05 23:26:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-05 23:26:16 -0400
commit11d8ec408d0aa2dae7ca89f95e497b8f22427b20 (patch)
tree88e7a8c08437f0bcaa747fc40c68604eb26fd431 /drivers/base
parent39fada55274241d50e27eb961cc9280b5b6121fb (diff)
parente2b3b80de5cda284c885721e873f9a6e90f68ef8 (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.c31
-rw-r--r--drivers/base/power/wakeup.c18
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}
403EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); 403EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact);
404 404
405static 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}
453EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); 460EXPORT_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}
398EXPORT_SYMBOL_GPL(device_wakeup_disable); 394EXPORT_SYMBOL_GPL(device_wakeup_disable);