aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/button.c45
-rw-r--r--include/acpi/button.h10
2 files changed, 53 insertions, 2 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 9195deba9d94..ebb593e9c380 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -113,6 +113,9 @@ static const struct file_operations acpi_button_state_fops = {
113 .release = single_release, 113 .release = single_release,
114}; 114};
115 115
116static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
117static struct acpi_device *lid_device;
118
116/* -------------------------------------------------------------------------- 119/* --------------------------------------------------------------------------
117 FS Interface (/proc) 120 FS Interface (/proc)
118 -------------------------------------------------------------------------- */ 121 -------------------------------------------------------------------------- */
@@ -229,11 +232,38 @@ static int acpi_button_remove_fs(struct acpi_device *device)
229/* -------------------------------------------------------------------------- 232/* --------------------------------------------------------------------------
230 Driver Interface 233 Driver Interface
231 -------------------------------------------------------------------------- */ 234 -------------------------------------------------------------------------- */
235int acpi_lid_notifier_register(struct notifier_block *nb)
236{
237 return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
238}
239EXPORT_SYMBOL(acpi_lid_notifier_register);
240
241int acpi_lid_notifier_unregister(struct notifier_block *nb)
242{
243 return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
244}
245EXPORT_SYMBOL(acpi_lid_notifier_unregister);
246
247int acpi_lid_open(void)
248{
249 acpi_status status;
250 unsigned long long state;
251
252 status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
253 &state);
254 if (ACPI_FAILURE(status))
255 return -ENODEV;
256
257 return !!state;
258}
259EXPORT_SYMBOL(acpi_lid_open);
260
232static int acpi_lid_send_state(struct acpi_device *device) 261static int acpi_lid_send_state(struct acpi_device *device)
233{ 262{
234 struct acpi_button *button = acpi_driver_data(device); 263 struct acpi_button *button = acpi_driver_data(device);
235 unsigned long long state; 264 unsigned long long state;
236 acpi_status status; 265 acpi_status status;
266 int ret;
237 267
238 status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state); 268 status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
239 if (ACPI_FAILURE(status)) 269 if (ACPI_FAILURE(status))
@@ -242,7 +272,12 @@ static int acpi_lid_send_state(struct acpi_device *device)
242 /* input layer checks if event is redundant */ 272 /* input layer checks if event is redundant */
243 input_report_switch(button->input, SW_LID, !state); 273 input_report_switch(button->input, SW_LID, !state);
244 input_sync(button->input); 274 input_sync(button->input);
245 return 0; 275
276 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
277 if (ret == NOTIFY_DONE)
278 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
279 device);
280 return ret;
246} 281}
247 282
248static void acpi_button_notify(struct acpi_device *device, u32 event) 283static void acpi_button_notify(struct acpi_device *device, u32 event)
@@ -364,8 +399,14 @@ static int acpi_button_add(struct acpi_device *device)
364 error = input_register_device(input); 399 error = input_register_device(input);
365 if (error) 400 if (error)
366 goto err_remove_fs; 401 goto err_remove_fs;
367 if (button->type == ACPI_BUTTON_TYPE_LID) 402 if (button->type == ACPI_BUTTON_TYPE_LID) {
368 acpi_lid_send_state(device); 403 acpi_lid_send_state(device);
404 /*
405 * This assumes there's only one lid device, or if there are
406 * more we only care about the last one...
407 */
408 lid_device = device;
409 }
369 410
370 if (device->wakeup.flags.valid) { 411 if (device->wakeup.flags.valid) {
371 /* Button's GPE is run-wake GPE */ 412 /* Button's GPE is run-wake GPE */
diff --git a/include/acpi/button.h b/include/acpi/button.h
new file mode 100644
index 000000000000..bb643a79d651
--- /dev/null
+++ b/include/acpi/button.h
@@ -0,0 +1,10 @@
1#ifndef ACPI_BUTTON_H
2#define ACPI_BUTTON_H
3
4#include <linux/notifier.h>
5
6extern int acpi_lid_notifier_register(struct notifier_block *nb);
7extern int acpi_lid_notifier_unregister(struct notifier_block *nb);
8extern int acpi_lid_open(void);
9
10#endif /* ACPI_BUTTON_H */