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/acpi | |
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/acpi')
-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 */ |