aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/button.c')
-rw-r--r--drivers/acpi/button.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index db35594d4df7..6d5d1832a588 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
79static void acpi_button_notify(struct acpi_device *device, u32 event); 79static void acpi_button_notify(struct acpi_device *device, u32 event);
80 80
81#ifdef CONFIG_PM_SLEEP 81#ifdef CONFIG_PM_SLEEP
82static int acpi_button_suspend(struct device *dev);
82static int acpi_button_resume(struct device *dev); 83static int acpi_button_resume(struct device *dev);
83#else 84#else
85#define acpi_button_suspend NULL
84#define acpi_button_resume NULL 86#define acpi_button_resume NULL
85#endif 87#endif
86static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); 88static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
87 89
88static struct acpi_driver acpi_button_driver = { 90static struct acpi_driver acpi_button_driver = {
89 .name = "button", 91 .name = "button",
@@ -102,6 +104,7 @@ struct acpi_button {
102 struct input_dev *input; 104 struct input_dev *input;
103 char phys[32]; /* for input device */ 105 char phys[32]; /* for input device */
104 unsigned long pushed; 106 unsigned long pushed;
107 bool suspended;
105}; 108};
106 109
107static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); 110static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
293 if (button->type == ACPI_BUTTON_TYPE_LID) { 296 if (button->type == ACPI_BUTTON_TYPE_LID) {
294 acpi_lid_send_state(device); 297 acpi_lid_send_state(device);
295 } else { 298 } else {
296 int keycode = test_bit(KEY_SLEEP, input->keybit) ? 299 int keycode;
297 KEY_SLEEP : KEY_POWER; 300
301 pm_wakeup_event(&device->dev, 0);
302 if (button->suspended)
303 break;
298 304
305 keycode = test_bit(KEY_SLEEP, input->keybit) ?
306 KEY_SLEEP : KEY_POWER;
299 input_report_key(input, keycode, 1); 307 input_report_key(input, keycode, 1);
300 input_sync(input); 308 input_sync(input);
301 input_report_key(input, keycode, 0); 309 input_report_key(input, keycode, 0);
302 input_sync(input); 310 input_sync(input);
303 311
304 pm_wakeup_event(&device->dev, 0);
305 acpi_bus_generate_netlink_event( 312 acpi_bus_generate_netlink_event(
306 device->pnp.device_class, 313 device->pnp.device_class,
307 dev_name(&device->dev), 314 dev_name(&device->dev),
@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
316} 323}
317 324
318#ifdef CONFIG_PM_SLEEP 325#ifdef CONFIG_PM_SLEEP
326static int acpi_button_suspend(struct device *dev)
327{
328 struct acpi_device *device = to_acpi_device(dev);
329 struct acpi_button *button = acpi_driver_data(device);
330
331 button->suspended = true;
332 return 0;
333}
334
319static int acpi_button_resume(struct device *dev) 335static int acpi_button_resume(struct device *dev)
320{ 336{
321 struct acpi_device *device = to_acpi_device(dev); 337 struct acpi_device *device = to_acpi_device(dev);
322 struct acpi_button *button = acpi_driver_data(device); 338 struct acpi_button *button = acpi_driver_data(device);
323 339
340 button->suspended = false;
324 if (button->type == ACPI_BUTTON_TYPE_LID) 341 if (button->type == ACPI_BUTTON_TYPE_LID)
325 return acpi_lid_send_state(device); 342 return acpi_lid_send_state(device);
326 return 0; 343 return 0;