Skip to content

Commit c41b381

Browse files
committed
Merge tag 'pm+acpi-fixes-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: - Fixes for blackfin and microblaze build problems introduced by the removal of global pm_idle. From Lars-Peter Clausen. - OPP core build fix from Shawn Guo. - Error condition check fix for the new imx6q-cpufreq driver from Wei Yongjun. - Fix for an AER driver crash related to the lack of APEI initialization for acpi=off. From Rafael J Wysocki. - Fix for a USB breakage on Thinkpad T430 related to ACPI power resources and PCI wakeup from Rafael J. Wysocki. * tag 'pm+acpi-fixes-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / PM: Take unusual configurations of power resources into account imx6q-cpufreq: fix return value check in imx6q_cpufreq_probe() PM / OPP: fix condition for empty of_init_opp_table() ACPI / APEI: Fix crash in apei_hest_parse() for acpi=off microblaze idle: Fix compile error blackfin idle: Fix compile error
2 parents 556f12f + 4383822 commit c41b381

File tree

8 files changed

+107
-50
lines changed

8 files changed

+107
-50
lines changed

arch/blackfin/kernel/process.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,10 @@ void cpu_idle(void)
8080
if (cpu_is_offline(smp_processor_id()))
8181
cpu_die();
8282
#endif
83-
if (!idle)
84-
idle = default_idle;
8583
tick_nohz_idle_enter();
8684
rcu_idle_enter();
8785
while (!need_resched())
88-
idle();
86+
default_idle();
8987
rcu_idle_exit();
9088
tick_nohz_idle_exit();
9189
preempt_enable_no_resched();

arch/microblaze/kernel/process.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,10 @@ void cpu_idle(void)
9797

9898
/* endless idle loop with no priority at all */
9999
while (1) {
100-
if (!idle)
101-
idle = default_idle;
102-
103100
tick_nohz_idle_enter();
104101
rcu_idle_enter();
105102
while (!need_resched())
106-
idle();
103+
default_idle();
107104
rcu_idle_exit();
108105
tick_nohz_idle_exit();
109106

drivers/acpi/apei/hest.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ int apei_hest_parse(apei_hest_func_t func, void *data)
8989
struct acpi_hest_header *hest_hdr;
9090
int i, rc, len;
9191

92-
if (hest_disable)
92+
if (hest_disable || !hest_tab)
9393
return -EINVAL;
9494

9595
hest_hdr = (struct acpi_hest_header *)(hest_tab + 1);
@@ -216,9 +216,6 @@ void __init acpi_hest_init(void)
216216
return;
217217
}
218218

219-
if (acpi_disabled)
220-
goto err;
221-
222219
status = acpi_get_table(ACPI_SIG_HEST, 0,
223220
(struct acpi_table_header **)&hest_tab);
224221
if (status == AE_NOT_FOUND)

drivers/acpi/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
7171
struct list_head *list);
7272
int acpi_add_power_resource(acpi_handle handle);
7373
void acpi_power_add_remove_device(struct acpi_device *adev, bool add);
74-
int acpi_power_min_system_level(struct list_head *list);
74+
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level);
7575
int acpi_device_sleep_wake(struct acpi_device *dev,
7676
int enable, int sleep_state, int dev_state);
7777
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);

drivers/acpi/power.c

Lines changed: 85 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct acpi_power_resource {
7373
u32 system_level;
7474
u32 order;
7575
unsigned int ref_count;
76+
bool wakeup_enabled;
7677
struct mutex resource_lock;
7778
};
7879

@@ -272,11 +273,9 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
272273
return 0;
273274
}
274275

275-
static int acpi_power_on(struct acpi_power_resource *resource)
276+
static int acpi_power_on_unlocked(struct acpi_power_resource *resource)
276277
{
277-
int result = 0;;
278-
279-
mutex_lock(&resource->resource_lock);
278+
int result = 0;
280279

281280
if (resource->ref_count++) {
282281
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -293,9 +292,16 @@ static int acpi_power_on(struct acpi_power_resource *resource)
293292
schedule_work(&dep->work);
294293
}
295294
}
295+
return result;
296+
}
296297

297-
mutex_unlock(&resource->resource_lock);
298+
static int acpi_power_on(struct acpi_power_resource *resource)
299+
{
300+
int result;
298301

302+
mutex_lock(&resource->resource_lock);
303+
result = acpi_power_on_unlocked(resource);
304+
mutex_unlock(&resource->resource_lock);
299305
return result;
300306
}
301307

@@ -313,17 +319,15 @@ static int __acpi_power_off(struct acpi_power_resource *resource)
313319
return 0;
314320
}
315321

316-
static int acpi_power_off(struct acpi_power_resource *resource)
322+
static int acpi_power_off_unlocked(struct acpi_power_resource *resource)
317323
{
318324
int result = 0;
319325

320-
mutex_lock(&resource->resource_lock);
321-
322326
if (!resource->ref_count) {
323327
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
324328
"Power resource [%s] already off",
325329
resource->name));
326-
goto unlock;
330+
return 0;
327331
}
328332

329333
if (--resource->ref_count) {
@@ -335,10 +339,16 @@ static int acpi_power_off(struct acpi_power_resource *resource)
335339
if (result)
336340
resource->ref_count++;
337341
}
342+
return result;
343+
}
338344

339-
unlock:
340-
mutex_unlock(&resource->resource_lock);
345+
static int acpi_power_off(struct acpi_power_resource *resource)
346+
{
347+
int result;
341348

349+
mutex_lock(&resource->resource_lock);
350+
result = acpi_power_off_unlocked(resource);
351+
mutex_unlock(&resource->resource_lock);
342352
return result;
343353
}
344354

@@ -521,18 +531,35 @@ void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
521531
}
522532
}
523533

524-
int acpi_power_min_system_level(struct list_head *list)
534+
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
525535
{
526536
struct acpi_power_resource_entry *entry;
527537
int system_level = 5;
528538

529539
list_for_each_entry(entry, list, node) {
530540
struct acpi_power_resource *resource = entry->resource;
541+
acpi_handle handle = resource->device.handle;
542+
int result;
543+
int state;
531544

545+
mutex_lock(&resource->resource_lock);
546+
547+
result = acpi_power_get_state(handle, &state);
548+
if (result) {
549+
mutex_unlock(&resource->resource_lock);
550+
return result;
551+
}
552+
if (state == ACPI_POWER_RESOURCE_STATE_ON) {
553+
resource->ref_count++;
554+
resource->wakeup_enabled = true;
555+
}
532556
if (system_level > resource->system_level)
533557
system_level = resource->system_level;
558+
559+
mutex_unlock(&resource->resource_lock);
534560
}
535-
return system_level;
561+
*system_level_p = system_level;
562+
return 0;
536563
}
537564

538565
/* --------------------------------------------------------------------------
@@ -610,6 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
610637
*/
611638
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
612639
{
640+
struct acpi_power_resource_entry *entry;
613641
int err = 0;
614642

615643
if (!dev || !dev->wakeup.flags.valid)
@@ -620,17 +648,31 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
620648
if (dev->wakeup.prepare_count++)
621649
goto out;
622650

623-
err = acpi_power_on_list(&dev->wakeup.resources);
624-
if (err) {
625-
dev_err(&dev->dev, "Cannot turn wakeup power resources on\n");
626-
dev->wakeup.flags.valid = 0;
627-
} else {
628-
/*
629-
* Passing 3 as the third argument below means the device may be
630-
* put into arbitrary power state afterward.
631-
*/
632-
err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
651+
list_for_each_entry(entry, &dev->wakeup.resources, node) {
652+
struct acpi_power_resource *resource = entry->resource;
653+
654+
mutex_lock(&resource->resource_lock);
655+
656+
if (!resource->wakeup_enabled) {
657+
err = acpi_power_on_unlocked(resource);
658+
if (!err)
659+
resource->wakeup_enabled = true;
660+
}
661+
662+
mutex_unlock(&resource->resource_lock);
663+
664+
if (err) {
665+
dev_err(&dev->dev,
666+
"Cannot turn wakeup power resources on\n");
667+
dev->wakeup.flags.valid = 0;
668+
goto out;
669+
}
633670
}
671+
/*
672+
* Passing 3 as the third argument below means the device may be
673+
* put into arbitrary power state afterward.
674+
*/
675+
err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
634676
if (err)
635677
dev->wakeup.prepare_count = 0;
636678

@@ -647,6 +689,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
647689
*/
648690
int acpi_disable_wakeup_device_power(struct acpi_device *dev)
649691
{
692+
struct acpi_power_resource_entry *entry;
650693
int err = 0;
651694

652695
if (!dev || !dev->wakeup.flags.valid)
@@ -668,10 +711,25 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
668711
if (err)
669712
goto out;
670713

671-
err = acpi_power_off_list(&dev->wakeup.resources);
672-
if (err) {
673-
dev_err(&dev->dev, "Cannot turn wakeup power resources off\n");
674-
dev->wakeup.flags.valid = 0;
714+
list_for_each_entry(entry, &dev->wakeup.resources, node) {
715+
struct acpi_power_resource *resource = entry->resource;
716+
717+
mutex_lock(&resource->resource_lock);
718+
719+
if (resource->wakeup_enabled) {
720+
err = acpi_power_off_unlocked(resource);
721+
if (!err)
722+
resource->wakeup_enabled = false;
723+
}
724+
725+
mutex_unlock(&resource->resource_lock);
726+
727+
if (err) {
728+
dev_err(&dev->dev,
729+
"Cannot turn wakeup power resources off\n");
730+
dev->wakeup.flags.valid = 0;
731+
break;
732+
}
675733
}
676734

677735
out:

drivers/acpi/scan.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,14 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
10021002
if (!list_empty(&wakeup->resources)) {
10031003
int sleep_state;
10041004

1005-
sleep_state = acpi_power_min_system_level(&wakeup->resources);
1005+
err = acpi_power_wakeup_list_init(&wakeup->resources,
1006+
&sleep_state);
1007+
if (err) {
1008+
acpi_handle_warn(handle, "Retrieving current states "
1009+
"of wakeup power resources failed\n");
1010+
acpi_power_resources_list_free(&wakeup->resources);
1011+
goto out;
1012+
}
10061013
if (sleep_state < wakeup->sleep_state) {
10071014
acpi_handle_warn(handle, "Overriding _PRW sleep state "
10081015
"(S%d) by S%d from power resources\n",

drivers/cpufreq/imx6q-cpufreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
245245
arm_reg = devm_regulator_get(cpu_dev, "arm");
246246
pu_reg = devm_regulator_get(cpu_dev, "pu");
247247
soc_reg = devm_regulator_get(cpu_dev, "soc");
248-
if (!arm_reg || !pu_reg || !soc_reg) {
248+
if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
249249
dev_err(cpu_dev, "failed to get regulators\n");
250250
ret = -ENOENT;
251251
goto put_node;

include/linux/opp.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ int opp_enable(struct device *dev, unsigned long freq);
4747
int opp_disable(struct device *dev, unsigned long freq);
4848

4949
struct srcu_notifier_head *opp_get_notifier(struct device *dev);
50-
51-
#ifdef CONFIG_OF
52-
int of_init_opp_table(struct device *dev);
53-
#else
54-
static inline int of_init_opp_table(struct device *dev)
55-
{
56-
return -EINVAL;
57-
}
58-
#endif /* CONFIG_OF */
5950
#else
6051
static inline unsigned long opp_get_voltage(struct opp *opp)
6152
{
@@ -112,6 +103,15 @@ static inline struct srcu_notifier_head *opp_get_notifier(struct device *dev)
112103
}
113104
#endif /* CONFIG_PM_OPP */
114105

106+
#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
107+
int of_init_opp_table(struct device *dev);
108+
#else
109+
static inline int of_init_opp_table(struct device *dev)
110+
{
111+
return -EINVAL;
112+
}
113+
#endif
114+
115115
#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
116116
int opp_init_cpufreq_table(struct device *dev,
117117
struct cpufreq_frequency_table **table);

0 commit comments

Comments
 (0)