Skip to content

Commit

Permalink
Merge branches 'pm-cpufreq', 'pm-cpuidle' and 'pm-domains'
Browse files Browse the repository at this point in the history
* pm-cpufreq:
  arm: imx: Add MODULE_ALIAS for cpufreq
  cpufreq: Add and use cpufreq_for_each_{valid_,}entry_idx()
  cpufreq: intel_pstate: Enable HWP during system resume on CPU0
  cpufreq: scpi: fix error return code in scpi_cpufreq_init()
  cpufreq: scpi: fix static checker warning cdev isn't an ERR_PTR
  cpufreq: remove at32ap-cpufreq
  cpufreq: AMD: Ignore the check for ProcFeedback in ST/CZ
  cpufreq: Skip cpufreq resume if it's not suspended

* pm-cpuidle:
  x86: PM: Make APM idle driver initialize polling state

* pm-domains:
  PM / domains: Fix up domain-idle-states OF parsing
  • Loading branch information
Rafael J. Wysocki committed Feb 8, 2018
4 parents 168b651 + d040473 + f859422 + a3381e3 commit 616f160
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 238 deletions.
4 changes: 4 additions & 0 deletions Documentation/cpu-freq/cpu-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,7 @@ For example:
/* Do something with pos */
pos->frequency = ...
}

If you need to work with the position of pos within driver_freq_table,
do not subtract the pointers, as it is quite costly. Instead, use the
macros cpufreq_for_each_entry_idx() and cpufreq_for_each_valid_entry_idx().
1 change: 1 addition & 0 deletions arch/x86/kernel/apm_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,7 @@ static int __init apm_init(void)
if (HZ != 100)
idle_period = (idle_period * HZ) / 100;
if (idle_threshold < 100) {
cpuidle_poll_state_init(&apm_idle_driver);
if (!cpuidle_register_driver(&apm_idle_driver))
if (cpuidle_register_device(&apm_cpuidle_device))
cpuidle_unregister_driver(&apm_idle_driver);
Expand Down
76 changes: 45 additions & 31 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -2290,6 +2290,38 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
return 0;
}

static int genpd_iterate_idle_states(struct device_node *dn,
struct genpd_power_state *states)
{
int ret;
struct of_phandle_iterator it;
struct device_node *np;
int i = 0;

ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
if (ret <= 0)
return ret;

/* Loop over the phandles until all the requested entry is found */
of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) {
np = it.node;
if (!of_match_node(idle_state_match, np))
continue;
if (states) {
ret = genpd_parse_state(&states[i], np);
if (ret) {
pr_err("Parsing idle state node %pOF failed with err %d\n",
np, ret);
of_node_put(np);
return ret;
}
}
i++;
}

return i;
}

/**
* of_genpd_parse_idle_states: Return array of idle states for the genpd.
*
Expand All @@ -2299,49 +2331,31 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
*
* Returns the device states parsed from the OF node. The memory for the states
* is allocated by this function and is the responsibility of the caller to
* free the memory after use.
* free the memory after use. If no domain idle states is found it returns
* -EINVAL and in case of errors, a negative error code.
*/
int of_genpd_parse_idle_states(struct device_node *dn,
struct genpd_power_state **states, int *n)
{
struct genpd_power_state *st;
struct device_node *np;
int i = 0;
int err, ret;
int count;
struct of_phandle_iterator it;
const struct of_device_id *match_id;
int ret;

count = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
if (count <= 0)
return -EINVAL;
ret = genpd_iterate_idle_states(dn, NULL);
if (ret <= 0)
return ret < 0 ? ret : -EINVAL;

st = kcalloc(count, sizeof(*st), GFP_KERNEL);
st = kcalloc(ret, sizeof(*st), GFP_KERNEL);
if (!st)
return -ENOMEM;

/* Loop over the phandles until all the requested entry is found */
of_for_each_phandle(&it, err, dn, "domain-idle-states", NULL, 0) {
np = it.node;
match_id = of_match_node(idle_state_match, np);
if (!match_id)
continue;
ret = genpd_parse_state(&st[i++], np);
if (ret) {
pr_err
("Parsing idle state node %pOF failed with err %d\n",
np, ret);
of_node_put(np);
kfree(st);
return ret;
}
ret = genpd_iterate_idle_states(dn, st);
if (ret <= 0) {
kfree(st);
return ret < 0 ? ret : -EINVAL;
}

*n = i;
if (!i)
kfree(st);
else
*states = st;
*states = st;
*n = ret;

return 0;
}
Expand Down
10 changes: 0 additions & 10 deletions drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -239,16 +239,6 @@ if PPC32 || PPC64
source "drivers/cpufreq/Kconfig.powerpc"
endif

if AVR32
config AVR32_AT32AP_CPUFREQ
bool "CPU frequency driver for AT32AP"
depends on PLATFORM_AT32AP
default n
help
This enables the CPU frequency driver for AT32AP processors.
If in doubt, say N.
endif

if IA64
config IA64_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
Expand Down
1 change: 0 additions & 1 deletion drivers/cpufreq/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ obj-$(CONFIG_POWERNV_CPUFREQ) += powernv-cpufreq.o

##################################################################################
# Other platform drivers
obj-$(CONFIG_AVR32_AT32AP_CPUFREQ) += at32ap-cpufreq.o
obj-$(CONFIG_BFIN_CPU_FREQ) += blackfin-cpufreq.o
obj-$(CONFIG_BMIPS_CPUFREQ) += bmips-cpufreq.o
obj-$(CONFIG_CRIS_MACH_ARTPEC3) += cris-artpec3-cpufreq.o
Expand Down
11 changes: 9 additions & 2 deletions drivers/cpufreq/amd_freq_sensitivity.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/percpu-defs.h>
#include <linux/init.h>
#include <linux/mod_devicetable.h>
Expand Down Expand Up @@ -109,12 +110,18 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
static int __init amd_freq_sensitivity_init(void)
{
u64 val;
struct pci_dev *pcidev;

if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return -ENODEV;

if (!static_cpu_has(X86_FEATURE_PROC_FEEDBACK))
return -ENODEV;
pcidev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, NULL);

if (!pcidev) {
if (!static_cpu_has(X86_FEATURE_PROC_FEEDBACK))
return -ENODEV;
}

if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
return -ENODEV;
Expand Down
127 changes: 0 additions & 127 deletions drivers/cpufreq/at32ap-cpufreq.c

This file was deleted.

3 changes: 3 additions & 0 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,9 @@ void cpufreq_resume(void)
if (!cpufreq_driver)
return;

if (unlikely(!cpufreq_suspended))
return;

cpufreq_suspended = false;

if (!has_target() && !cpufreq_driver->resume)
Expand Down
7 changes: 3 additions & 4 deletions drivers/cpufreq/exynos5440-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ static struct cpufreq_freqs freqs;
static int init_div_table(void)
{
struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table;
unsigned int tmp, clk_div, ema_div, freq, volt_id;
unsigned int tmp, clk_div, ema_div, freq, volt_id, idx;
struct dev_pm_opp *opp;

cpufreq_for_each_entry(pos, freq_tbl) {
cpufreq_for_each_entry_idx(pos, freq_tbl, idx) {
opp = dev_pm_opp_find_freq_exact(dvfs_info->dev,
pos->frequency * 1000, true);
if (IS_ERR(opp)) {
Expand Down Expand Up @@ -154,8 +154,7 @@ static int init_div_table(void)
tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT)
| ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT));

__raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 *
(pos - freq_tbl));
__raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx);
dev_pm_opp_put(opp);
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/cpufreq/freq_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,9 @@ int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
break;
}

cpufreq_for_each_valid_entry(pos, table) {
cpufreq_for_each_valid_entry_idx(pos, table, i) {
freq = pos->frequency;

i = pos - table;
if ((freq < policy->min) || (freq > policy->max))
continue;
if (freq == target_freq) {
Expand Down Expand Up @@ -211,15 +210,16 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
unsigned int freq)
{
struct cpufreq_frequency_table *pos, *table = policy->freq_table;
int idx;

if (unlikely(!table)) {
pr_debug("%s: Unable to find frequency table\n", __func__);
return -ENOENT;
}

cpufreq_for_each_valid_entry(pos, table)
cpufreq_for_each_valid_entry_idx(pos, table, idx)
if (pos->frequency == freq)
return pos - table;
return idx;

return -EINVAL;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/cpufreq/imx6q-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ static struct platform_driver imx6q_cpufreq_platdrv = {
};
module_platform_driver(imx6q_cpufreq_platdrv);

MODULE_ALIAS("platform:imx6q-cpufreq");
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
MODULE_LICENSE("GPL");
5 changes: 5 additions & 0 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,13 +779,18 @@ static int intel_pstate_hwp_save_state(struct cpufreq_policy *policy)
return 0;
}

static void intel_pstate_hwp_enable(struct cpudata *cpudata);

static int intel_pstate_resume(struct cpufreq_policy *policy)
{
if (!hwp_active)
return 0;

mutex_lock(&intel_pstate_limits_lock);

if (policy->cpu == 0)
intel_pstate_hwp_enable(all_cpu_data[policy->cpu]);

all_cpu_data[policy->cpu]->epp_policy = 0;
intel_pstate_hwp_set(policy->cpu);

Expand Down
Loading

0 comments on commit 616f160

Please sign in to comment.