mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 22:52:19 +02:00
Power management fixes for v4.13-rc4
- Fix the handling of the scaling_cur_freq cpufreq policy attribute
on x86 systems with the MPERF/APERF registers present to make it
behave more as expected after recent changes (Rafael Wysocki).
- Drop a leftover callback from the intel_pstate driver which also
prevents the cpuinfo_cur_freq cpufreq policy attribute from being
incorrectly exposed when intel_pstate works in the active mode
(Rafael Wysocki).
- Add a missing piece describing the cpuinfo_cur_freq policy
attribute to cpufreq documentation (Rafael Wysocki).
- Fix up a recently added part of the Thunderbolt driver to avoid
aborting system suspends if its mailbox commands time out (Rafael
Wysocki).
- Update device runtime PM framework documentation to reflect the
current behavior of the code (Johan Hovold).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAABCAAGBQJZg3DiAAoJEILEb/54YlRxvgkP/RV5djXAUeUpoMnzJCnP7jpB
bYvzqIXN2olcZPNP3hNLM7W1yRAWiwL9F1aFF2apJPyMQ8DW7iBqltAxQY+h2Ggc
lLvQcT5NRCFbIlsRadBL3TMZMFmtYqBD9Q8C+LLgQDWmm3mgG8o0kFJdGWkOMHg7
4FaqTuF1np8ARd1jX3E4QGCVaSqIEKN9xMo7jzsWIHXruag3tJb92ryROVcq3uO7
5WspJSbVMKS0E6jbK3RQkJ9T/3U453p8JMDJNQfOUFr1KQNfAikyV3U0ZoQA6Hjk
1tmJE9v7jq75BDj0Dtfskl8EBFA4Sk+Pegyb3/hB8MR/oRzCWRAe9rVW5LweckcC
Q1Q+SDKcVKVIEQa3GZOH1nBfHP/pIMQb0+WGMIq614rr1Ug9IuF4cCn2AnzkIFLE
lpkVch3mCfrCwAKmsvYug5isHdazlS93MY9dOZr4D1lewgFp1piShsBSK3RFBT8F
Cu3lYTzBi/MJ+8T0vZysHVEkCNu3emrXwccjzubW1rSNINGgRF5AV9F2HwGYzDHe
KD3Kw1KH2LZEWZAlR6W711pBJny4INENPH0XE85hZ4Ryi+2SN7zvsA/PM0rGjqBq
TcuFc3jN+DMwWoOJryY8701gE8SMz+8Vam/B191XFUkdZSHFk1WWILAu/OfTZCRo
bLYhORgyemWPluAzzcsx
=j2UJ
-----END PGP SIGNATURE-----
Merge tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki:
"These fix two cpufreq issues, one introduced recently and one related
to recent changes, fix cpufreq documentation, fix up recently added
code in the Thunderbolt driver and update runtime PM framework
documentation.
Specifics:
- Fix the handling of the scaling_cur_freq cpufreq policy attribute
on x86 systems with the MPERF/APERF registers present to make it
behave more as expected after recent changes (Rafael Wysocki).
- Drop a leftover callback from the intel_pstate driver which also
prevents the cpuinfo_cur_freq cpufreq policy attribute from being
incorrectly exposed when intel_pstate works in the active mode
(Rafael Wysocki).
- Add a missing piece describing the cpuinfo_cur_freq policy
attribute to cpufreq documentation (Rafael Wysocki).
- Fix up a recently added part of the Thunderbolt driver to avoid
aborting system suspends if its mailbox commands time out (Rafael
Wysocki).
- Update device runtime PM framework documentation to reflect the
current behavior of the code (Johan Hovold)"
* tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
thunderbolt: icm: Ignore mailbox errors in icm_suspend()
cpufreq: x86: Make scaling_cur_freq behave more as expected
PM / runtime: Document new pm_runtime_set_suspended() constraint
cpufreq: docs: Add missing cpuinfo_cur_freq description
cpufreq: intel_pstate: Drop ->get from intel_pstate structure
This commit is contained in:
commit
73784fb73b
|
|
@ -237,6 +237,14 @@ are the following:
|
|||
This attribute is not present if the scaling driver in use does not
|
||||
support it.
|
||||
|
||||
``cpuinfo_cur_freq``
|
||||
Current frequency of the CPUs belonging to this policy as obtained from
|
||||
the hardware (in KHz).
|
||||
|
||||
This is expected to be the frequency the hardware actually runs at.
|
||||
If that frequency cannot be determined, this attribute should not
|
||||
be present.
|
||||
|
||||
``cpuinfo_max_freq``
|
||||
Maximum possible operating frequency the CPUs belonging to this policy
|
||||
can run at (in kHz).
|
||||
|
|
|
|||
|
|
@ -435,7 +435,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
|||
PM status to 'suspended' and update its parent's counter of 'active'
|
||||
children as appropriate (it is only valid to use this function if
|
||||
'power.runtime_error' is set or 'power.disable_depth' is greater than
|
||||
zero)
|
||||
zero); it will fail and return an error code if the device has a child
|
||||
which is active and the 'power.ignore_children' flag is unset
|
||||
|
||||
bool pm_runtime_active(struct device *dev);
|
||||
- return true if the device's runtime PM status is 'active' or its
|
||||
|
|
|
|||
|
|
@ -8,20 +8,25 @@
|
|||
* This file is licensed under GPLv2.
|
||||
*/
|
||||
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
struct aperfmperf_sample {
|
||||
unsigned int khz;
|
||||
unsigned long jiffies;
|
||||
ktime_t time;
|
||||
u64 aperf;
|
||||
u64 mperf;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
|
||||
|
||||
#define APERFMPERF_CACHE_THRESHOLD_MS 10
|
||||
#define APERFMPERF_REFRESH_DELAY_MS 20
|
||||
#define APERFMPERF_STALE_THRESHOLD_MS 1000
|
||||
|
||||
/*
|
||||
* aperfmperf_snapshot_khz()
|
||||
* On the current CPU, snapshot APERF, MPERF, and jiffies
|
||||
|
|
@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
|
|||
u64 aperf, aperf_delta;
|
||||
u64 mperf, mperf_delta;
|
||||
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
|
||||
ktime_t now = ktime_get();
|
||||
s64 time_delta = ktime_ms_delta(now, s->time);
|
||||
|
||||
/* Don't bother re-computing within 10 ms */
|
||||
if (time_before(jiffies, s->jiffies + HZ/100))
|
||||
/* Don't bother re-computing within the cache threshold time. */
|
||||
if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
|
||||
return;
|
||||
|
||||
rdmsrl(MSR_IA32_APERF, aperf);
|
||||
|
|
@ -51,22 +58,21 @@ static void aperfmperf_snapshot_khz(void *dummy)
|
|||
if (mperf_delta == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
|
||||
* khz = (cpu_khz * aperf_delta) / mperf_delta
|
||||
*/
|
||||
if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
|
||||
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
|
||||
else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
|
||||
s->khz = div64_u64(aperf_delta,
|
||||
div64_u64(mperf_delta, cpu_khz));
|
||||
s->jiffies = jiffies;
|
||||
s->time = now;
|
||||
s->aperf = aperf;
|
||||
s->mperf = mperf;
|
||||
|
||||
/* If the previous iteration was too long ago, discard it. */
|
||||
if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
|
||||
s->khz = 0;
|
||||
else
|
||||
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
|
||||
}
|
||||
|
||||
unsigned int arch_freq_get_on_cpu(int cpu)
|
||||
{
|
||||
unsigned int khz;
|
||||
|
||||
if (!cpu_khz)
|
||||
return 0;
|
||||
|
||||
|
|
@ -74,6 +80,12 @@ unsigned int arch_freq_get_on_cpu(int cpu)
|
|||
return 0;
|
||||
|
||||
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
|
||||
khz = per_cpu(samples.khz, cpu);
|
||||
if (khz)
|
||||
return khz;
|
||||
|
||||
msleep(APERFMPERF_REFRESH_DELAY_MS);
|
||||
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
|
||||
|
||||
return per_cpu(samples.khz, cpu);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1922,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int intel_pstate_get(unsigned int cpu_num)
|
||||
{
|
||||
struct cpudata *cpu = all_cpu_data[cpu_num];
|
||||
|
||||
return cpu ? get_avg_frequency(cpu) : 0;
|
||||
}
|
||||
|
||||
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
|
||||
{
|
||||
struct cpudata *cpu = all_cpu_data[cpu_num];
|
||||
|
|
@ -2169,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
|
|||
.setpolicy = intel_pstate_set_policy,
|
||||
.suspend = intel_pstate_hwp_save_state,
|
||||
.resume = intel_pstate_resume,
|
||||
.get = intel_pstate_get,
|
||||
.init = intel_pstate_cpu_init,
|
||||
.exit = intel_pstate_cpu_exit,
|
||||
.stop_cpu = intel_pstate_stop_cpu,
|
||||
|
|
|
|||
|
|
@ -904,7 +904,14 @@ static int icm_driver_ready(struct tb *tb)
|
|||
|
||||
static int icm_suspend(struct tb *tb)
|
||||
{
|
||||
return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
|
||||
int ret;
|
||||
|
||||
ret = nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
|
||||
if (ret)
|
||||
tb_info(tb, "Ignoring mailbox command error (%d) in %s\n",
|
||||
ret, __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user