Skip to content

Commit 2457aaf

Browse files
committed
Merge tag 'pm+acpi-3.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel/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()
2 parents d45004f + d831a00 commit 2457aaf

File tree

9 files changed

+46
-22
lines changed

9 files changed

+46
-22
lines changed

arch/arm/mach-imx/clk-imx27.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ int __init mx27_clocks_init(unsigned long fref)
285285
clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
286286
clk_register_clkdev(clk[rtc_ipg_gate], NULL, "imx21-rtc");
287287
clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
288-
clk_register_clkdev(clk[cpu_div], NULL, "cpufreq-cpu0.0");
288+
clk_register_clkdev(clk[cpu_div], NULL, "cpu0");
289289
clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
290290

291291
mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);

arch/arm/mach-imx/clk-imx51-imx53.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
328328
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
329329
clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
330330
clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
331-
clk_register_clkdev(clk[cpu_podf], NULL, "cpufreq-cpu0.0");
331+
clk_register_clkdev(clk[cpu_podf], NULL, "cpu0");
332332
clk_register_clkdev(clk[iim_gate], "iim", NULL);
333333
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
334334
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");

arch/arm/mach-imx/mach-imx6q.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,15 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
233233
of_node_put(np);
234234
}
235235

236-
static void __init imx6q_opp_init(struct device *cpu_dev)
236+
static void __init imx6q_opp_init(void)
237237
{
238238
struct device_node *np;
239+
struct device *cpu_dev = get_cpu_device(0);
239240

241+
if (!cpu_dev) {
242+
pr_warn("failed to get cpu0 device\n");
243+
return;
244+
}
240245
np = of_node_get(cpu_dev->of_node);
241246
if (!np) {
242247
pr_warn("failed to find cpu0 node\n");
@@ -268,7 +273,7 @@ static void __init imx6q_init_late(void)
268273
imx6q_cpuidle_init();
269274

270275
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
271-
imx6q_opp_init(&imx6q_cpufreq_pdev.dev);
276+
imx6q_opp_init();
272277
platform_device_register(&imx6q_cpufreq_pdev);
273278
}
274279
}

arch/arm/mach-shmobile/clock-r8a73a4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ static struct clk_lookup lookups[] = {
555555
CLKDEV_CON_ID("pll2h", &pll2h_clk),
556556

557557
/* CPU clock */
558-
CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk),
558+
CLKDEV_DEV_ID("cpu0", &z_clk),
559559

560560
/* DIV6 */
561561
CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),

arch/arm/mach-shmobile/clock-sh73a0.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ static struct clk_lookup lookups[] = {
616616
CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
617617

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

621621
/* DIV6 clocks */
622622
CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),

drivers/cpufreq/cpufreq-cpu0.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1313

1414
#include <linux/clk.h>
15+
#include <linux/cpu.h>
1516
#include <linux/cpufreq.h>
1617
#include <linux/err.h>
1718
#include <linux/module.h>
@@ -177,7 +178,11 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
177178
struct device_node *np;
178179
int ret;
179180

180-
cpu_dev = &pdev->dev;
181+
cpu_dev = get_cpu_device(0);
182+
if (!cpu_dev) {
183+
pr_err("failed to get cpu0 device\n");
184+
return -ENODEV;
185+
}
181186

182187
np = of_node_get(cpu_dev->of_node);
183188
if (!np) {

drivers/cpufreq/cpufreq.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -952,9 +952,20 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
952952
if (cpu == policy->cpu)
953953
return;
954954

955+
/*
956+
* Take direct locks as lock_policy_rwsem_write wouldn't work here.
957+
* Also lock for last cpu is enough here as contention will happen only
958+
* after policy->cpu is changed and after it is changed, other threads
959+
* will try to acquire lock for new cpu. And policy is already updated
960+
* by then.
961+
*/
962+
down_write(&per_cpu(cpu_policy_rwsem, policy->cpu));
963+
955964
policy->last_cpu = policy->cpu;
956965
policy->cpu = cpu;
957966

967+
up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu));
968+
958969
#ifdef CONFIG_CPU_FREQ_TABLE
959970
cpufreq_frequency_table_update_policy_cpu(policy);
960971
#endif
@@ -1125,7 +1136,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
11251136
int ret;
11261137

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

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

1192-
WARN_ON(lock_policy_rwsem_write(cpu));
1203+
lock_policy_rwsem_read(cpu);
11931204
cpus = cpumask_weight(policy->cpus);
1194-
1195-
if (cpus > 1)
1196-
cpumask_clear_cpu(cpu, policy->cpus);
1197-
unlock_policy_rwsem_write(cpu);
1205+
unlock_policy_rwsem_read(cpu);
11981206

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

12041212
new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
12051213
if (new_cpu >= 0) {
1206-
WARN_ON(lock_policy_rwsem_write(cpu));
12071214
update_policy_cpu(policy, new_cpu);
1208-
unlock_policy_rwsem_write(cpu);
12091215

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

1240-
lock_policy_rwsem_read(cpu);
1246+
WARN_ON(lock_policy_rwsem_write(cpu));
12411247
cpus = cpumask_weight(policy->cpus);
1242-
unlock_policy_rwsem_read(cpu);
1248+
1249+
if (cpus > 1)
1250+
cpumask_clear_cpu(cpu, policy->cpus);
1251+
unlock_policy_rwsem_write(cpu);
12431252

12441253
/* If cpu is last user of policy, free policy */
12451254
if (cpus == 1) {
@@ -2095,7 +2104,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
20952104
write_lock_irqsave(&cpufreq_driver_lock, flags);
20962105
if (cpufreq_driver) {
20972106
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2098-
return -EBUSY;
2107+
return -EEXIST;
20992108
}
21002109
cpufreq_driver = driver_data;
21012110
write_unlock_irqrestore(&cpufreq_driver_lock, flags);

drivers/cpufreq/imx6q-cpufreq.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <linux/clk.h>
10+
#include <linux/cpu.h>
1011
#include <linux/cpufreq.h>
1112
#include <linux/delay.h>
1213
#include <linux/err.h>
@@ -202,7 +203,11 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
202203
unsigned long min_volt, max_volt;
203204
int num, ret;
204205

205-
cpu_dev = &pdev->dev;
206+
cpu_dev = get_cpu_device(0);
207+
if (!cpu_dev) {
208+
pr_err("failed to get cpu0 device\n");
209+
return -ENODEV;
210+
}
206211

207212
np = of_node_get(cpu_dev->of_node);
208213
if (!np) {

drivers/pci/pci-acpi.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
4747
if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev)
4848
return;
4949

50+
if (pci_dev->pme_poll)
51+
pci_dev->pme_poll = false;
52+
5053
if (pci_dev->current_state == PCI_D3cold) {
5154
pci_wakeup_event(pci_dev);
5255
pm_runtime_resume(&pci_dev->dev);
@@ -57,9 +60,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
5760
if (pci_dev->pme_support)
5861
pci_check_pme_status(pci_dev);
5962

60-
if (pci_dev->pme_poll)
61-
pci_dev->pme_poll = false;
62-
6363
pci_wakeup_event(pci_dev);
6464
pm_runtime_resume(&pci_dev->dev);
6565

0 commit comments

Comments
 (0)