Skip to content

Commit

Permalink
Merge tag 'pm+acpi-3.12-rc2' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/rafael/linux-pm

Pull ACPI and power management fixes from Rafael Wysocki:

 1) Four fixes for cpufreq regressions introduced by the changes that
    removed Device Tree parsing for CPU device nodes from cpufreq
    drivers from Sudeep KarkadaNagesha.

 2) Two fixes for recent cpufreq regressions introduced by changes
    related to the preservation of sysfs attributes over system
    suspend/resume cycles from Viresh Kumar.

 3) Fix for ACPI-based wakeup signaling in the PCI subsystem that
    fails to stop PME polling for devices put into the D3cold power
    state from Rafael J Wysocki.

 4) Fix for bad interactions between cpufreq and udev on systems
    supporting intel_pstate where acpi-cpufreq is available as well
    from Yinghai Lu.

* tag 'pm+acpi-3.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: return EEXIST instead of EBUSY for second registering
  PCI / ACPI / PM: Clear pme_poll for devices in D3cold on wakeup
  ARM: shmobile: change dev_id to cpu0 while registering cpu clock
  ARM: i.MX: change dev_id to cpu0 while registering cpu clock
  cpufreq: imx6q-cpufreq: assign cpu_dev correctly to cpu0 device
  cpufreq: cpufreq-cpu0: assign cpu_dev correctly to cpu0 device
  cpufreq: unlock correct rwsem while updating policy->cpu
  cpufreq: Clear policy->cpus bits in __cpufreq_remove_dev_finish()
  • Loading branch information
Linus Torvalds committed Sep 20, 2013
2 parents d45004f + d831a00 commit 2457aaf
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 22 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-imx/clk-imx27.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
clk_register_clkdev(clk[rtc_ipg_gate], NULL, "imx21-rtc");
clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
clk_register_clkdev(clk[cpu_div], NULL, "cpufreq-cpu0.0");
clk_register_clkdev(clk[cpu_div], NULL, "cpu0");
clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);

mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-imx/clk-imx51-imx53.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
clk_register_clkdev(clk[cpu_podf], NULL, "cpufreq-cpu0.0");
clk_register_clkdev(clk[cpu_podf], NULL, "cpu0");
clk_register_clkdev(clk[iim_gate], "iim", NULL);
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
Expand Down
9 changes: 7 additions & 2 deletions arch/arm/mach-imx/mach-imx6q.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,15 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
of_node_put(np);
}

static void __init imx6q_opp_init(struct device *cpu_dev)
static void __init imx6q_opp_init(void)
{
struct device_node *np;
struct device *cpu_dev = get_cpu_device(0);

if (!cpu_dev) {
pr_warn("failed to get cpu0 device\n");
return;
}
np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_warn("failed to find cpu0 node\n");
Expand Down Expand Up @@ -268,7 +273,7 @@ static void __init imx6q_init_late(void)
imx6q_cpuidle_init();

if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
imx6q_opp_init(&imx6q_cpufreq_pdev.dev);
imx6q_opp_init();
platform_device_register(&imx6q_cpufreq_pdev);
}
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-shmobile/clock-r8a73a4.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("pll2h", &pll2h_clk),

/* CPU clock */
CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk),
CLKDEV_DEV_ID("cpu0", &z_clk),

/* DIV6 */
CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-shmobile/clock-sh73a0.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */

/* DIV4 clocks */
CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),

/* DIV6 clocks */
CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
Expand Down
7 changes: 6 additions & 1 deletion drivers/cpufreq/cpufreq-cpu0.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/module.h>
Expand Down Expand Up @@ -177,7 +178,11 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
struct device_node *np;
int ret;

cpu_dev = &pdev->dev;
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
pr_err("failed to get cpu0 device\n");
return -ENODEV;
}

np = of_node_get(cpu_dev->of_node);
if (!np) {
Expand Down
31 changes: 20 additions & 11 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,9 +952,20 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
if (cpu == policy->cpu)
return;

/*
* Take direct locks as lock_policy_rwsem_write wouldn't work here.
* Also lock for last cpu is enough here as contention will happen only
* after policy->cpu is changed and after it is changed, other threads
* will try to acquire lock for new cpu. And policy is already updated
* by then.
*/
down_write(&per_cpu(cpu_policy_rwsem, policy->cpu));

policy->last_cpu = policy->cpu;
policy->cpu = cpu;

up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu));

#ifdef CONFIG_CPU_FREQ_TABLE
cpufreq_frequency_table_update_policy_cpu(policy);
#endif
Expand Down Expand Up @@ -1125,7 +1136,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
int ret;

/* first sibling now owns the new sysfs dir */
cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));

/* Don't touch sysfs files during light-weight tear-down */
if (frozen)
Expand Down Expand Up @@ -1189,12 +1200,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
policy->governor->name, CPUFREQ_NAME_LEN);
#endif

WARN_ON(lock_policy_rwsem_write(cpu));
lock_policy_rwsem_read(cpu);
cpus = cpumask_weight(policy->cpus);

if (cpus > 1)
cpumask_clear_cpu(cpu, policy->cpus);
unlock_policy_rwsem_write(cpu);
unlock_policy_rwsem_read(cpu);

if (cpu != policy->cpu) {
if (!frozen)
Expand All @@ -1203,9 +1211,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,

new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
if (new_cpu >= 0) {
WARN_ON(lock_policy_rwsem_write(cpu));
update_policy_cpu(policy, new_cpu);
unlock_policy_rwsem_write(cpu);

if (!frozen) {
pr_debug("%s: policy Kobject moved to cpu: %d "
Expand Down Expand Up @@ -1237,9 +1243,12 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
return -EINVAL;
}

lock_policy_rwsem_read(cpu);
WARN_ON(lock_policy_rwsem_write(cpu));
cpus = cpumask_weight(policy->cpus);
unlock_policy_rwsem_read(cpu);

if (cpus > 1)
cpumask_clear_cpu(cpu, policy->cpus);
unlock_policy_rwsem_write(cpu);

/* If cpu is last user of policy, free policy */
if (cpus == 1) {
Expand Down Expand Up @@ -2095,7 +2104,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
write_lock_irqsave(&cpufreq_driver_lock, flags);
if (cpufreq_driver) {
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
return -EBUSY;
return -EEXIST;
}
cpufreq_driver = driver_data;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Expand Down
7 changes: 6 additions & 1 deletion drivers/cpufreq/imx6q-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/err.h>
Expand Down Expand Up @@ -202,7 +203,11 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
unsigned long min_volt, max_volt;
int num, ret;

cpu_dev = &pdev->dev;
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
pr_err("failed to get cpu0 device\n");
return -ENODEV;
}

np = of_node_get(cpu_dev->of_node);
if (!np) {
Expand Down
6 changes: 3 additions & 3 deletions drivers/pci/pci-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev)
return;

if (pci_dev->pme_poll)
pci_dev->pme_poll = false;

if (pci_dev->current_state == PCI_D3cold) {
pci_wakeup_event(pci_dev);
pm_runtime_resume(&pci_dev->dev);
Expand All @@ -57,9 +60,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
if (pci_dev->pme_support)
pci_check_pme_status(pci_dev);

if (pci_dev->pme_poll)
pci_dev->pme_poll = false;

pci_wakeup_event(pci_dev);
pm_runtime_resume(&pci_dev->dev);

Expand Down

0 comments on commit 2457aaf

Please sign in to comment.