diff options
| author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2007-10-22 06:18:18 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2007-10-25 16:31:30 -0400 |
| commit | 23de5d9ef2a4bbc4f733f58311bcb7cf6239c813 (patch) | |
| tree | a781cebb71c5ea3b5a6750ac48cb57aaad32aac4 /drivers | |
| parent | 1dbc1fda5d8ca907f320b806005d4a447977d26a (diff) | |
ACPI: button: send initial lid state after add and resume
Input layer should know about initial state of lid switch,
even before first notify.
Reference: https://bugzilla.novell.com/show_bug.cgi?id=326814
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/acpi/button.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 301e832e6961..24a7865a57cb 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
| @@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids); | |||
| 78 | 78 | ||
| 79 | static int acpi_button_add(struct acpi_device *device); | 79 | static int acpi_button_add(struct acpi_device *device); |
| 80 | static int acpi_button_remove(struct acpi_device *device, int type); | 80 | static int acpi_button_remove(struct acpi_device *device, int type); |
| 81 | static int acpi_button_resume(struct acpi_device *device); | ||
| 81 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file); | 82 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file); |
| 82 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file); | 83 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file); |
| 83 | 84 | ||
| @@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = { | |||
| 87 | .ids = button_device_ids, | 88 | .ids = button_device_ids, |
| 88 | .ops = { | 89 | .ops = { |
| 89 | .add = acpi_button_add, | 90 | .add = acpi_button_add, |
| 91 | .resume = acpi_button_resume, | ||
| 90 | .remove = acpi_button_remove, | 92 | .remove = acpi_button_remove, |
| 91 | }, | 93 | }, |
| 92 | }; | 94 | }; |
| @@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device) | |||
| 253 | /* -------------------------------------------------------------------------- | 255 | /* -------------------------------------------------------------------------- |
| 254 | Driver Interface | 256 | Driver Interface |
| 255 | -------------------------------------------------------------------------- */ | 257 | -------------------------------------------------------------------------- */ |
| 258 | static int acpi_lid_send_state(struct acpi_button *button) | ||
| 259 | { | ||
| 260 | unsigned long state; | ||
| 261 | acpi_status status; | ||
| 262 | |||
| 263 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, | ||
| 264 | &state); | ||
| 265 | if (ACPI_FAILURE(status)) | ||
| 266 | return -ENODEV; | ||
| 267 | /* input layer checks if event is redundant */ | ||
| 268 | input_report_switch(button->input, SW_LID, !state); | ||
| 269 | return 0; | ||
| 270 | } | ||
| 256 | 271 | ||
| 257 | static void acpi_button_notify(acpi_handle handle, u32 event, void *data) | 272 | static void acpi_button_notify(acpi_handle handle, u32 event, void *data) |
| 258 | { | 273 | { |
| @@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) | |||
| 265 | switch (event) { | 280 | switch (event) { |
| 266 | case ACPI_BUTTON_NOTIFY_STATUS: | 281 | case ACPI_BUTTON_NOTIFY_STATUS: |
| 267 | input = button->input; | 282 | input = button->input; |
| 268 | |||
| 269 | if (button->type == ACPI_BUTTON_TYPE_LID) { | 283 | if (button->type == ACPI_BUTTON_TYPE_LID) { |
| 270 | struct acpi_handle *handle = button->device->handle; | 284 | acpi_lid_send_state(button); |
| 271 | unsigned long state; | ||
| 272 | |||
| 273 | if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID", | ||
| 274 | NULL, &state))) | ||
| 275 | input_report_switch(input, SW_LID, !state); | ||
| 276 | |||
| 277 | } else { | 285 | } else { |
| 278 | int keycode = test_bit(KEY_SLEEP, input->keybit) ? | 286 | int keycode = test_bit(KEY_SLEEP, input->keybit) ? |
| 279 | KEY_SLEEP : KEY_POWER; | 287 | KEY_SLEEP : KEY_POWER; |
| @@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button) | |||
| 336 | return ACPI_FAILURE(status) ? -ENODEV : 0; | 344 | return ACPI_FAILURE(status) ? -ENODEV : 0; |
| 337 | } | 345 | } |
| 338 | 346 | ||
| 347 | static int acpi_button_resume(struct acpi_device *device) | ||
| 348 | { | ||
| 349 | struct acpi_button *button; | ||
| 350 | if (!device) | ||
| 351 | return -EINVAL; | ||
| 352 | button = acpi_driver_data(device); | ||
| 353 | if (button && button->type == ACPI_BUTTON_TYPE_LID) | ||
| 354 | return acpi_lid_send_state(button); | ||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | |||
| 339 | static void acpi_button_remove_notify_handlers(struct acpi_button *button) | 358 | static void acpi_button_remove_notify_handlers(struct acpi_button *button) |
| 340 | { | 359 | { |
| 341 | switch (button->type) { | 360 | switch (button->type) { |
| @@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device) | |||
| 453 | error = input_register_device(input); | 472 | error = input_register_device(input); |
| 454 | if (error) | 473 | if (error) |
| 455 | goto err_remove_handlers; | 474 | goto err_remove_handlers; |
| 475 | if (button->type == ACPI_BUTTON_TYPE_LID) | ||
| 476 | acpi_lid_send_state(button); | ||
| 456 | 477 | ||
| 457 | if (device->wakeup.flags.valid) { | 478 | if (device->wakeup.flags.valid) { |
| 458 | /* Button's GPE is run-wake GPE */ | 479 | /* Button's GPE is run-wake GPE */ |
