aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/button.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-24 13:30:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-24 13:30:41 -0400
commit94e0fb086fc5663c38bbc0fe86d698be8314f82f (patch)
tree1c3be6c71ec3511aa2a4eb6dfa25f35677464ebb /drivers/acpi/button.c
parentb7f21bb2e23b4fec16b448a34889f467465be659 (diff)
parentc715089f49844260f1eeae8e3b55af9468ba1325 (diff)
Merge branch 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: (57 commits) drm/i915: Handle ERESTARTSYS during page fault drm/i915: Warn before mmaping a purgeable buffer. drm/i915: Track purged state. drm/i915: Remove eviction debug spam drm/i915: Immediately discard any backing storage for uneeded objects drm/i915: Do not mis-classify clean objects as purgeable drm/i915: Whitespace correction for madv drm/i915: BUG_ON page refleak during unbind drm/i915: Search harder for a reusable object drm/i915: Clean up evict from list. drm/i915: Add tracepoints drm/i915: framebuffer compression for GM45+ drm/i915: split display functions by chip type drm/i915: Skip the sanity checks if the current relocation is valid drm/i915: Check that the relocation points to within the target drm/i915: correct FBC update when pipe base update occurs drm/i915: blacklist Acer AspireOne lid status ACPI: make ACPI button funcs no-ops if not built in drm/i915: prevent FIFO calculation overflows on 32 bits with high dotclocks drm/i915: intel_display.c handle latency variable efficiently ... Fix up trivial conflicts in drivers/gpu/drm/i915/{i915_dma.c|i915_drv.h}
Diffstat (limited to 'drivers/acpi/button.c')
-rw-r--r--drivers/acpi/button.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index d295bdccc09c..9335b87c5174 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -115,6 +115,9 @@ static const struct file_operations acpi_button_state_fops = {
115 .release = single_release, 115 .release = single_release,
116}; 116};
117 117
118static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
119static struct acpi_device *lid_device;
120
118/* -------------------------------------------------------------------------- 121/* --------------------------------------------------------------------------
119 FS Interface (/proc) 122 FS Interface (/proc)
120 -------------------------------------------------------------------------- */ 123 -------------------------------------------------------------------------- */
@@ -231,11 +234,38 @@ static int acpi_button_remove_fs(struct acpi_device *device)
231/* -------------------------------------------------------------------------- 234/* --------------------------------------------------------------------------
232 Driver Interface 235 Driver Interface
233 -------------------------------------------------------------------------- */ 236 -------------------------------------------------------------------------- */
237int acpi_lid_notifier_register(struct notifier_block *nb)
238{
239 return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
240}
241EXPORT_SYMBOL(acpi_lid_notifier_register);
242
243int acpi_lid_notifier_unregister(struct notifier_block *nb)
244{
245 return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
246}
247EXPORT_SYMBOL(acpi_lid_notifier_unregister);
248
249int acpi_lid_open(void)
250{
251 acpi_status status;
252 unsigned long long state;
253
254 status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
255 &state);
256 if (ACPI_FAILURE(status))
257 return -ENODEV;
258
259 return !!state;
260}
261EXPORT_SYMBOL(acpi_lid_open);
262
234static int acpi_lid_send_state(struct acpi_device *device) 263static int acpi_lid_send_state(struct acpi_device *device)
235{ 264{
236 struct acpi_button *button = acpi_driver_data(device); 265 struct acpi_button *button = acpi_driver_data(device);
237 unsigned long long state; 266 unsigned long long state;
238 acpi_status status; 267 acpi_status status;
268 int ret;
239 269
240 status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state); 270 status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
241 if (ACPI_FAILURE(status)) 271 if (ACPI_FAILURE(status))
@@ -244,7 +274,12 @@ static int acpi_lid_send_state(struct acpi_device *device)
244 /* input layer checks if event is redundant */ 274 /* input layer checks if event is redundant */
245 input_report_switch(button->input, SW_LID, !state); 275 input_report_switch(button->input, SW_LID, !state);
246 input_sync(button->input); 276 input_sync(button->input);
247 return 0; 277
278 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
279 if (ret == NOTIFY_DONE)
280 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
281 device);
282 return ret;
248} 283}
249 284
250static void acpi_button_notify(struct acpi_device *device, u32 event) 285static void acpi_button_notify(struct acpi_device *device, u32 event)
@@ -366,8 +401,14 @@ static int acpi_button_add(struct acpi_device *device)
366 error = input_register_device(input); 401 error = input_register_device(input);
367 if (error) 402 if (error)
368 goto err_remove_fs; 403 goto err_remove_fs;
369 if (button->type == ACPI_BUTTON_TYPE_LID) 404 if (button->type == ACPI_BUTTON_TYPE_LID) {
370 acpi_lid_send_state(device); 405 acpi_lid_send_state(device);
406 /*
407 * This assumes there's only one lid device, or if there are
408 * more we only care about the last one...
409 */
410 lid_device = device;
411 }
371 412
372 if (device->wakeup.flags.valid) { 413 if (device->wakeup.flags.valid) {
373 /* Button's GPE is run-wake GPE */ 414 /* Button's GPE is run-wake GPE */