Commit 9cd238ab authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm-4.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
 "These fix a regression in the ondemand and conservative cpufreq
  governors that was introduced during the 4.13 cycle, a recent
  regression in the imx6q cpufreq driver and a regression in the PCI
  handling of hibernation from the 4.14 cycle.

  Specifics:

   - Fix an issue in the PCI handling of the "thaw" transition during
     hibernation (after creating an image), introduced by a bug fix from
     the 4.13 cycle and exposed by recent changes in the IRQ subsystem,
     that caused pci_restore_state() to be called for devices in
     low-power states in some cases which is incorrect and breaks MSI
     management on some systems (Rafael Wysocki).

   - Fix a recent regression in the imx6q cpufreq driver that broke
     speed grading on i.MX6 QuadPlus by omitting checks causing invalid
     operating performance points (OPPs) to be disabled on that SoC as
     appropriate (Lucas Stach).

   - Fix a regression introduced during the 4.14 cycle in the ondemand
     and conservative cpufreq governors that causes the sampling
     interval used by them to be shorter than the tick period in some
     cases which leads to incorrect decisions (Rafael Wysocki)"

* tag 'pm-4.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: governor: Ensure sufficiently large sampling intervals
  cpufreq: imx6q: fix speed grading regression on i.MX6 QuadPlus
  PCI / PM: Force devices to D0 in pci_pm_thaw_noirq()
parents 7887f470 63d15e8c
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "cpufreq_governor.h" #include "cpufreq_governor.h"
#define CPUFREQ_DBS_MIN_SAMPLING_INTERVAL (2 * TICK_NSEC / NSEC_PER_USEC)
static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs); static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs);
static DEFINE_MUTEX(gov_dbs_data_mutex); static DEFINE_MUTEX(gov_dbs_data_mutex);
...@@ -47,11 +49,15 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf, ...@@ -47,11 +49,15 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
{ {
struct dbs_data *dbs_data = to_dbs_data(attr_set); struct dbs_data *dbs_data = to_dbs_data(attr_set);
struct policy_dbs_info *policy_dbs; struct policy_dbs_info *policy_dbs;
unsigned int sampling_interval;
int ret; int ret;
ret = sscanf(buf, "%u", &dbs_data->sampling_rate);
if (ret != 1) ret = sscanf(buf, "%u", &sampling_interval);
if (ret != 1 || sampling_interval < CPUFREQ_DBS_MIN_SAMPLING_INTERVAL)
return -EINVAL; return -EINVAL;
dbs_data->sampling_rate = sampling_interval;
/* /*
* We are operating under dbs_data->mutex and so the list and its * We are operating under dbs_data->mutex and so the list and its
* entries can't be freed concurrently. * entries can't be freed concurrently.
...@@ -430,7 +436,14 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) ...@@ -430,7 +436,14 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
if (ret) if (ret)
goto free_policy_dbs_info; goto free_policy_dbs_info;
dbs_data->sampling_rate = cpufreq_policy_transition_delay_us(policy); /*
* The sampling interval should not be less than the transition latency
* of the CPU and it also cannot be too small for dbs_update() to work
* correctly.
*/
dbs_data->sampling_rate = max_t(unsigned int,
CPUFREQ_DBS_MIN_SAMPLING_INTERVAL,
cpufreq_policy_transition_delay_us(policy));
if (!have_governor_per_policy()) if (!have_governor_per_policy())
gov->gdbs_data = dbs_data; gov->gdbs_data = dbs_data;
......
...@@ -226,17 +226,18 @@ static void imx6q_opp_check_speed_grading(struct device *dev) ...@@ -226,17 +226,18 @@ static void imx6q_opp_check_speed_grading(struct device *dev)
val >>= OCOTP_CFG3_SPEED_SHIFT; val >>= OCOTP_CFG3_SPEED_SHIFT;
val &= 0x3; val &= 0x3;
if ((val != OCOTP_CFG3_SPEED_1P2GHZ) &&
of_machine_is_compatible("fsl,imx6q"))
if (dev_pm_opp_disable(dev, 1200000000))
dev_warn(dev, "failed to disable 1.2GHz OPP\n");
if (val < OCOTP_CFG3_SPEED_996MHZ) if (val < OCOTP_CFG3_SPEED_996MHZ)
if (dev_pm_opp_disable(dev, 996000000)) if (dev_pm_opp_disable(dev, 996000000))
dev_warn(dev, "failed to disable 996MHz OPP\n"); dev_warn(dev, "failed to disable 996MHz OPP\n");
if (of_machine_is_compatible("fsl,imx6q")) {
if (of_machine_is_compatible("fsl,imx6q") ||
of_machine_is_compatible("fsl,imx6qp")) {
if (val != OCOTP_CFG3_SPEED_852MHZ) if (val != OCOTP_CFG3_SPEED_852MHZ)
if (dev_pm_opp_disable(dev, 852000000)) if (dev_pm_opp_disable(dev, 852000000))
dev_warn(dev, "failed to disable 852MHz OPP\n"); dev_warn(dev, "failed to disable 852MHz OPP\n");
if (val != OCOTP_CFG3_SPEED_1P2GHZ)
if (dev_pm_opp_disable(dev, 1200000000))
dev_warn(dev, "failed to disable 1.2GHz OPP\n");
} }
iounmap(base); iounmap(base);
put_node: put_node:
......
...@@ -1012,7 +1012,12 @@ static int pci_pm_thaw_noirq(struct device *dev) ...@@ -1012,7 +1012,12 @@ static int pci_pm_thaw_noirq(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev); return pci_legacy_resume_early(dev);
pci_update_current_state(pci_dev, PCI_D0); /*
* pci_restore_state() requires the device to be in D0 (because of MSI
* restoration among other things), so force it into D0 in case the
* driver's "freeze" callbacks put it into a low-power state directly.
*/
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev); pci_restore_state(pci_dev);
if (drv && drv->pm && drv->pm->thaw_noirq) if (drv && drv->pm && drv->pm->thaw_noirq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment