diff options
Diffstat (limited to 'drivers/acpi/button.c')
-rw-r--r-- | drivers/acpi/button.c | 25 |
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); | |||
79 | static void acpi_button_notify(struct acpi_device *device, u32 event); | 79 | static void acpi_button_notify(struct acpi_device *device, u32 event); |
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | 81 | #ifdef CONFIG_PM_SLEEP |
82 | static int acpi_button_suspend(struct device *dev); | ||
82 | static int acpi_button_resume(struct device *dev); | 83 | static 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 |
86 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); | 88 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); |
87 | 89 | ||
88 | static struct acpi_driver acpi_button_driver = { | 90 | static 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 | ||
107 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); | 110 | static 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 |
326 | static 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 | |||
319 | static int acpi_button_resume(struct device *dev) | 335 | static 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; |