aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-01-06 17:34:22 -0500
committerLen Brown <len.brown@intel.com>2011-01-07 01:17:41 -0500
commitf2b56bc808addb908a5bf435d9b942c02af9a7c4 (patch)
tree562c7c96e60505f2b7278add12d19e5a545e7e1b
parentb014f4f1aad3f25d5c7d877a394869645ea0c96b (diff)
ACPI / PM: Use device wakeup flags for handling ACPI wakeup devices
There are ACPI devices (buttons and the laptop lid) that can wake up the system from sleep states and have no "physical" companion devices. The ACPI subsystem uses two flags, wakeup.state.enabled and wakeup.flags.always_enabled, for handling those devices, but they are not accessible through the standard device wakeup infrastructure. User space can only control them via the /proc/acpi/wakeup interface that is not really convenient (e.g. the way in which devices are enabled to wake up the system is not portable between different systems, because it requires one to know the devices' "names" used in the system's ACPI tables). To address this problem, use standard device wakeup flags instead of the special ACPI flags for handling those devices. In particular, use device_set_wakeup_capable() to mark the ACPI wakeup devices during initialization and use device_set_wakeup_enable() to allow or disallow them to wake up the system from sleep states. Rework the /proc/acpi/wakeup interface to take these changes into account. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/button.c4
-rw-r--r--drivers/acpi/proc.c19
-rw-r--r--drivers/acpi/scan.c2
-rw-r--r--drivers/acpi/wakeup.c18
4 files changed, 26 insertions, 17 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 71ef9cd0735f..234c104fcdd8 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -426,7 +426,7 @@ static int acpi_button_add(struct acpi_device *device)
426 acpi_enable_gpe(device->wakeup.gpe_device, 426 acpi_enable_gpe(device->wakeup.gpe_device,
427 device->wakeup.gpe_number); 427 device->wakeup.gpe_number);
428 device->wakeup.run_wake_count++; 428 device->wakeup.run_wake_count++;
429 device->wakeup.state.enabled = 1; 429 device_set_wakeup_enable(&device->dev, true);
430 } 430 }
431 431
432 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); 432 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
@@ -449,7 +449,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
449 acpi_disable_gpe(device->wakeup.gpe_device, 449 acpi_disable_gpe(device->wakeup.gpe_device,
450 device->wakeup.gpe_number); 450 device->wakeup.gpe_number);
451 device->wakeup.run_wake_count--; 451 device->wakeup.run_wake_count--;
452 device->wakeup.state.enabled = 0; 452 device_set_wakeup_enable(&device->dev, false);
453 } 453 }
454 454
455 acpi_button_remove_fs(device); 455 acpi_button_remove_fs(device);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 129effbb7bd4..f5f986991b52 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
311 dev->pnp.bus_id, 311 dev->pnp.bus_id,
312 (u32) dev->wakeup.sleep_state, 312 (u32) dev->wakeup.sleep_state,
313 dev->wakeup.flags.run_wake ? '*' : ' ', 313 dev->wakeup.flags.run_wake ? '*' : ' ',
314 dev->wakeup.state.enabled ? "enabled" : "disabled"); 314 (device_may_wakeup(&dev->dev)
315 || (ldev && device_may_wakeup(ldev))) ?
316 "enabled" : "disabled");
315 if (ldev) 317 if (ldev)
316 seq_printf(seq, "%s:%s", 318 seq_printf(seq, "%s:%s",
317 ldev->bus ? ldev->bus->name : "no-bus", 319 ldev->bus ? ldev->bus->name : "no-bus",
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
328{ 330{
329 struct device *dev = acpi_get_physical_device(adev->handle); 331 struct device *dev = acpi_get_physical_device(adev->handle);
330 332
331 if (dev && device_can_wakeup(dev)) 333 if (dev && device_can_wakeup(dev)) {
332 device_set_wakeup_enable(dev, adev->wakeup.state.enabled); 334 bool enable = !device_may_wakeup(dev);
335 device_set_wakeup_enable(dev, enable);
336 }
333} 337}
334 338
335static ssize_t 339static ssize_t
@@ -360,9 +364,12 @@ acpi_system_write_wakeup_device(struct file *file,
360 continue; 364 continue;
361 365
362 if (!strncmp(dev->pnp.bus_id, str, 4)) { 366 if (!strncmp(dev->pnp.bus_id, str, 4)) {
363 dev->wakeup.state.enabled = 367 if (device_can_wakeup(&dev->dev)) {
364 dev->wakeup.state.enabled ? 0 : 1; 368 bool enable = !device_may_wakeup(&dev->dev);
365 physical_device_enable_wakeup(dev); 369 device_set_wakeup_enable(&dev->dev, enable);
370 } else {
371 physical_device_enable_wakeup(dev);
372 }
366 break; 373 break;
367 } 374 }
368 } 375 }
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 29ef505c487b..bf7acbff1f5f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
803 /* Power button, Lid switch always enable wakeup */ 803 /* Power button, Lid switch always enable wakeup */
804 if (!acpi_match_device_ids(device, button_device_ids)) { 804 if (!acpi_match_device_ids(device, button_device_ids)) {
805 device->wakeup.flags.run_wake = 1; 805 device->wakeup.flags.run_wake = 1;
806 device->wakeup.flags.always_enabled = 1; 806 device_set_wakeup_capable(&device->dev, true);
807 return; 807 return;
808 } 808 }
809 809
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index f62a50c3ed34..f252d0de9922 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -37,11 +37,12 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
37 container_of(node, struct acpi_device, wakeup_list); 37 container_of(node, struct acpi_device, wakeup_list);
38 38
39 if (!dev->wakeup.flags.valid 39 if (!dev->wakeup.flags.valid
40 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) 40 || sleep_state > (u32) dev->wakeup.sleep_state
41 || sleep_state > (u32) dev->wakeup.sleep_state) 41 || !(device_may_wakeup(&dev->dev)
42 || dev->wakeup.prepare_count))
42 continue; 43 continue;
43 44
44 if (dev->wakeup.state.enabled) 45 if (device_may_wakeup(&dev->dev))
45 acpi_enable_wakeup_device_power(dev, sleep_state); 46 acpi_enable_wakeup_device_power(dev, sleep_state);
46 47
47 /* The wake-up power should have been enabled already. */ 48 /* The wake-up power should have been enabled already. */
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
63 container_of(node, struct acpi_device, wakeup_list); 64 container_of(node, struct acpi_device, wakeup_list);
64 65
65 if (!dev->wakeup.flags.valid 66 if (!dev->wakeup.flags.valid
66 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) 67 || sleep_state > (u32) dev->wakeup.sleep_state
67 || (sleep_state > (u32) dev->wakeup.sleep_state)) 68 || !(device_may_wakeup(&dev->dev)
69 || dev->wakeup.prepare_count))
68 continue; 70 continue;
69 71
70 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, 72 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
71 ACPI_GPE_DISABLE); 73 ACPI_GPE_DISABLE);
72 74
73 if (dev->wakeup.state.enabled) 75 if (device_may_wakeup(&dev->dev))
74 acpi_disable_wakeup_device_power(dev); 76 acpi_disable_wakeup_device_power(dev);
75 } 77 }
76} 78}
@@ -84,8 +86,8 @@ int __init acpi_wakeup_device_init(void)
84 struct acpi_device *dev = container_of(node, 86 struct acpi_device *dev = container_of(node,
85 struct acpi_device, 87 struct acpi_device,
86 wakeup_list); 88 wakeup_list);
87 if (dev->wakeup.flags.always_enabled) 89 if (device_can_wakeup(&dev->dev))
88 dev->wakeup.state.enabled = 1; 90 device_set_wakeup_enable(&dev->dev, true);
89 } 91 }
90 mutex_unlock(&acpi_device_lock); 92 mutex_unlock(&acpi_device_lock);
91 return 0; 93 return 0;