diff options
author | Len Brown <len.brown@intel.com> | 2011-01-12 04:55:46 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-01-12 04:55:46 -0500 |
commit | fb4af417cce9ff87abf33a6bb9a0cf613e285364 (patch) | |
tree | 328ce710c6e6acf7b58145da939fb3cc91d188c9 /drivers/acpi | |
parent | 07bf280521bb06bc8e64f0b998fc391253fcb959 (diff) | |
parent | 7b330707dddab1ad772898c1c82516342a551173 (diff) |
Merge branch 'wakeup-etc-rafael' into release
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/evmisc.c | 94 | ||||
-rw-r--r-- | drivers/acpi/button.c | 9 | ||||
-rw-r--r-- | drivers/acpi/glue.c | 5 | ||||
-rw-r--r-- | drivers/acpi/proc.c | 41 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 8 | ||||
-rw-r--r-- | drivers/acpi/wakeup.c | 18 |
7 files changed, 94 insertions, 83 deletions
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index fcaed9fb44ff..8e31bb5a973a 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | 284 | * RETURN: ACPI_INTERRUPT_HANDLED |
285 | * | 285 | * |
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | 286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock |
287 | * release interrupt occurs. Attempt to acquire the global lock, | 287 | * release interrupt occurs. If there's a thread waiting for |
288 | * if successful, signal the thread waiting for the lock. | 288 | * the global lock, signal it. |
289 | * | 289 | * |
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | 290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If |
291 | * this is not possible for some reason, a separate thread will have to be | 291 | * this is not possible for some reason, a separate thread will have to be |
292 | * scheduled to do this. | 292 | * scheduled to do this. |
293 | * | 293 | * |
294 | ******************************************************************************/ | 294 | ******************************************************************************/ |
295 | static u8 acpi_ev_global_lock_pending; | ||
296 | static spinlock_t _acpi_ev_global_lock_pending_lock; | ||
297 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
295 | 298 | ||
296 | static u32 acpi_ev_global_lock_handler(void *context) | 299 | static u32 acpi_ev_global_lock_handler(void *context) |
297 | { | 300 | { |
298 | u8 acquired = FALSE; | 301 | acpi_status status; |
302 | acpi_cpu_flags flags; | ||
299 | 303 | ||
300 | /* | 304 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
301 | * Attempt to get the lock. | ||
302 | * | ||
303 | * If we don't get it now, it will be marked pending and we will | ||
304 | * take another interrupt when it becomes free. | ||
305 | */ | ||
306 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
307 | if (acquired) { | ||
308 | 305 | ||
309 | /* Got the lock, now wake all threads waiting for it */ | 306 | if (!acpi_ev_global_lock_pending) { |
307 | goto out; | ||
308 | } | ||
310 | 309 | ||
311 | acpi_gbl_global_lock_acquired = TRUE; | 310 | /* Send a unit to the semaphore */ |
312 | /* Send a unit to the semaphore */ | ||
313 | 311 | ||
314 | if (ACPI_FAILURE | 312 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); |
315 | (acpi_os_signal_semaphore | 313 | if (ACPI_FAILURE(status)) { |
316 | (acpi_gbl_global_lock_semaphore, 1))) { | 314 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); |
317 | ACPI_ERROR((AE_INFO, | ||
318 | "Could not signal Global Lock semaphore")); | ||
319 | } | ||
320 | } | 315 | } |
321 | 316 | ||
317 | acpi_ev_global_lock_pending = FALSE; | ||
318 | |||
319 | out: | ||
320 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
321 | |||
322 | return (ACPI_INTERRUPT_HANDLED); | 322 | return (ACPI_INTERRUPT_HANDLED); |
323 | } | 323 | } |
324 | 324 | ||
@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired; | |||
415 | 415 | ||
416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
417 | { | 417 | { |
418 | acpi_cpu_flags flags; | ||
418 | acpi_status status = AE_OK; | 419 | acpi_status status = AE_OK; |
419 | u8 acquired = FALSE; | 420 | u8 acquired = FALSE; |
420 | 421 | ||
@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
467 | return_ACPI_STATUS(AE_OK); | 468 | return_ACPI_STATUS(AE_OK); |
468 | } | 469 | } |
469 | 470 | ||
470 | /* Attempt to acquire the actual hardware lock */ | 471 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
472 | |||
473 | do { | ||
474 | |||
475 | /* Attempt to acquire the actual hardware lock */ | ||
476 | |||
477 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
478 | if (acquired) { | ||
479 | acpi_gbl_global_lock_acquired = TRUE; | ||
480 | |||
481 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
482 | "Acquired hardware Global Lock\n")); | ||
483 | break; | ||
484 | } | ||
471 | 485 | ||
472 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | 486 | acpi_ev_global_lock_pending = TRUE; |
473 | if (acquired) { | ||
474 | 487 | ||
475 | /* We got the lock */ | 488 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
476 | 489 | ||
490 | /* | ||
491 | * Did not get the lock. The pending bit was set above, and we | ||
492 | * must wait until we get the global lock released interrupt. | ||
493 | */ | ||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 494 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
478 | "Acquired hardware Global Lock\n")); | 495 | "Waiting for hardware Global Lock\n")); |
479 | 496 | ||
480 | acpi_gbl_global_lock_acquired = TRUE; | 497 | /* |
481 | return_ACPI_STATUS(AE_OK); | 498 | * Wait for handshake with the global lock interrupt handler. |
482 | } | 499 | * This interface releases the interpreter if we must wait. |
500 | */ | ||
501 | status = acpi_ex_system_wait_semaphore( | ||
502 | acpi_gbl_global_lock_semaphore, | ||
503 | ACPI_WAIT_FOREVER); | ||
483 | 504 | ||
484 | /* | 505 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
485 | * Did not get the lock. The pending bit was set above, and we must now | ||
486 | * wait until we get the global lock released interrupt. | ||
487 | */ | ||
488 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); | ||
489 | 506 | ||
490 | /* | 507 | } while (ACPI_SUCCESS(status)); |
491 | * Wait for handshake with the global lock interrupt handler. | 508 | |
492 | * This interface releases the interpreter if we must wait. | 509 | acpi_ev_global_lock_pending = FALSE; |
493 | */ | 510 | |
494 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 511 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
495 | ACPI_WAIT_FOREVER); | ||
496 | 512 | ||
497 | return_ACPI_STATUS(status); | 513 | return_ACPI_STATUS(status); |
498 | } | 514 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 71ef9cd0735f..76bbb78a5ad9 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device) | |||
279 | input_report_switch(button->input, SW_LID, !state); | 279 | input_report_switch(button->input, SW_LID, !state); |
280 | input_sync(button->input); | 280 | input_sync(button->input); |
281 | 281 | ||
282 | if (state) | ||
283 | pm_wakeup_event(&device->dev, 0); | ||
284 | |||
282 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); | 285 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); |
283 | if (ret == NOTIFY_DONE) | 286 | if (ret == NOTIFY_DONE) |
284 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, | 287 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, |
@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
314 | input_sync(input); | 317 | input_sync(input); |
315 | input_report_key(input, keycode, 0); | 318 | input_report_key(input, keycode, 0); |
316 | input_sync(input); | 319 | input_sync(input); |
320 | |||
321 | pm_wakeup_event(&device->dev, 0); | ||
317 | } | 322 | } |
318 | 323 | ||
319 | acpi_bus_generate_proc_event(device, event, ++button->pushed); | 324 | acpi_bus_generate_proc_event(device, event, ++button->pushed); |
@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
426 | acpi_enable_gpe(device->wakeup.gpe_device, | 431 | acpi_enable_gpe(device->wakeup.gpe_device, |
427 | device->wakeup.gpe_number); | 432 | device->wakeup.gpe_number); |
428 | device->wakeup.run_wake_count++; | 433 | device->wakeup.run_wake_count++; |
429 | device->wakeup.state.enabled = 1; | 434 | device_set_wakeup_enable(&device->dev, true); |
430 | } | 435 | } |
431 | 436 | ||
432 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 437 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
449 | acpi_disable_gpe(device->wakeup.gpe_device, | 454 | acpi_disable_gpe(device->wakeup.gpe_device, |
450 | device->wakeup.gpe_number); | 455 | device->wakeup.gpe_number); |
451 | device->wakeup.run_wake_count--; | 456 | device->wakeup.run_wake_count--; |
452 | device->wakeup.state.enabled = 0; | 457 | device_set_wakeup_enable(&device->dev, false); |
453 | } | 458 | } |
454 | 459 | ||
455 | acpi_button_remove_fs(device); | 460 | acpi_button_remove_fs(device); |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 78b0164c35b2..7c47ed55e528 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
167 | "firmware_node"); | 167 | "firmware_node"); |
168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
169 | "physical_node"); | 169 | "physical_node"); |
170 | if (acpi_dev->wakeup.flags.valid) { | 170 | if (acpi_dev->wakeup.flags.valid) |
171 | device_set_wakeup_capable(dev, true); | 171 | device_set_wakeup_capable(dev, true); |
172 | device_set_wakeup_enable(dev, | ||
173 | acpi_dev->wakeup.state.enabled); | ||
174 | } | ||
175 | } | 172 | } |
176 | 173 | ||
177 | return 0; | 174 | return 0; |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index afad67769db6..f5f986991b52 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
311 | dev->pnp.bus_id, | 311 | dev->pnp.bus_id, |
312 | (u32) dev->wakeup.sleep_state, | 312 | (u32) dev->wakeup.sleep_state, |
313 | dev->wakeup.flags.run_wake ? '*' : ' ', | 313 | dev->wakeup.flags.run_wake ? '*' : ' ', |
314 | dev->wakeup.state.enabled ? "enabled" : "disabled"); | 314 | (device_may_wakeup(&dev->dev) |
315 | || (ldev && device_may_wakeup(ldev))) ? | ||
316 | "enabled" : "disabled"); | ||
315 | if (ldev) | 317 | if (ldev) |
316 | seq_printf(seq, "%s:%s", | 318 | seq_printf(seq, "%s:%s", |
317 | ldev->bus ? ldev->bus->name : "no-bus", | 319 | ldev->bus ? ldev->bus->name : "no-bus", |
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev) | |||
328 | { | 330 | { |
329 | struct device *dev = acpi_get_physical_device(adev->handle); | 331 | struct device *dev = acpi_get_physical_device(adev->handle); |
330 | 332 | ||
331 | if (dev && device_can_wakeup(dev)) | 333 | if (dev && device_can_wakeup(dev)) { |
332 | device_set_wakeup_enable(dev, adev->wakeup.state.enabled); | 334 | bool enable = !device_may_wakeup(dev); |
335 | device_set_wakeup_enable(dev, enable); | ||
336 | } | ||
333 | } | 337 | } |
334 | 338 | ||
335 | static ssize_t | 339 | static ssize_t |
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file, | |||
341 | char strbuf[5]; | 345 | char strbuf[5]; |
342 | char str[5] = ""; | 346 | char str[5] = ""; |
343 | unsigned int len = count; | 347 | unsigned int len = count; |
344 | struct acpi_device *found_dev = NULL; | ||
345 | 348 | ||
346 | if (len > 4) | 349 | if (len > 4) |
347 | len = 4; | 350 | len = 4; |
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file, | |||
361 | continue; | 364 | continue; |
362 | 365 | ||
363 | if (!strncmp(dev->pnp.bus_id, str, 4)) { | 366 | if (!strncmp(dev->pnp.bus_id, str, 4)) { |
364 | dev->wakeup.state.enabled = | 367 | if (device_can_wakeup(&dev->dev)) { |
365 | dev->wakeup.state.enabled ? 0 : 1; | 368 | bool enable = !device_may_wakeup(&dev->dev); |
366 | found_dev = dev; | 369 | device_set_wakeup_enable(&dev->dev, enable); |
367 | break; | 370 | } else { |
368 | } | ||
369 | } | ||
370 | if (found_dev) { | ||
371 | physical_device_enable_wakeup(found_dev); | ||
372 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||
373 | struct acpi_device *dev = container_of(node, | ||
374 | struct | ||
375 | acpi_device, | ||
376 | wakeup_list); | ||
377 | |||
378 | if ((dev != found_dev) && | ||
379 | (dev->wakeup.gpe_number == | ||
380 | found_dev->wakeup.gpe_number) | ||
381 | && (dev->wakeup.gpe_device == | ||
382 | found_dev->wakeup.gpe_device)) { | ||
383 | printk(KERN_WARNING | ||
384 | "ACPI: '%s' and '%s' have the same GPE, " | ||
385 | "can't disable/enable one separately\n", | ||
386 | dev->pnp.bus_id, found_dev->pnp.bus_id); | ||
387 | dev->wakeup.state.enabled = | ||
388 | found_dev->wakeup.state.enabled; | ||
389 | physical_device_enable_wakeup(dev); | 371 | physical_device_enable_wakeup(dev); |
390 | } | 372 | } |
373 | break; | ||
391 | } | 374 | } |
392 | } | 375 | } |
393 | mutex_unlock(&acpi_device_lock); | 376 | mutex_unlock(&acpi_device_lock); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 148e7492d736..64d4da0d6d52 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
803 | /* Power button, Lid switch always enable wakeup */ | 803 | /* Power button, Lid switch always enable wakeup */ |
804 | if (!acpi_match_device_ids(device, button_device_ids)) { | 804 | if (!acpi_match_device_ids(device, button_device_ids)) { |
805 | device->wakeup.flags.run_wake = 1; | 805 | device->wakeup.flags.run_wake = 1; |
806 | device->wakeup.flags.always_enabled = 1; | 806 | device_set_wakeup_capable(&device->dev, true); |
807 | return; | 807 | return; |
808 | } | 808 | } |
809 | 809 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index febb153b5a68..ddc5cce508a1 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -435,6 +435,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
435 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | 435 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), |
436 | }, | 436 | }, |
437 | }, | 437 | }, |
438 | { | ||
439 | .callback = init_nvs_nosave, | ||
440 | .ident = "Averatec AV1020-ED2", | ||
441 | .matches = { | ||
442 | DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), | ||
443 | DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), | ||
444 | }, | ||
445 | }, | ||
438 | {}, | 446 | {}, |
439 | }; | 447 | }; |
440 | #endif /* CONFIG_SUSPEND */ | 448 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index c6cb68e0a80c..ed6501452507 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -37,11 +37,12 @@ void acpi_enable_wakeup_devices(u8 sleep_state) | |||
37 | container_of(node, struct acpi_device, wakeup_list); | 37 | container_of(node, struct acpi_device, wakeup_list); |
38 | 38 | ||
39 | if (!dev->wakeup.flags.valid | 39 | if (!dev->wakeup.flags.valid |
40 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 40 | || sleep_state > (u32) dev->wakeup.sleep_state |
41 | || sleep_state > (u32) dev->wakeup.sleep_state) | 41 | || !(device_may_wakeup(&dev->dev) |
42 | || dev->wakeup.prepare_count)) | ||
42 | continue; | 43 | continue; |
43 | 44 | ||
44 | if (dev->wakeup.state.enabled) | 45 | if (device_may_wakeup(&dev->dev)) |
45 | acpi_enable_wakeup_device_power(dev, sleep_state); | 46 | acpi_enable_wakeup_device_power(dev, sleep_state); |
46 | 47 | ||
47 | /* The wake-up power should have been enabled already. */ | 48 | /* The wake-up power should have been enabled already. */ |
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state) | |||
63 | container_of(node, struct acpi_device, wakeup_list); | 64 | container_of(node, struct acpi_device, wakeup_list); |
64 | 65 | ||
65 | if (!dev->wakeup.flags.valid | 66 | if (!dev->wakeup.flags.valid |
66 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 67 | || sleep_state > (u32) dev->wakeup.sleep_state |
67 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | 68 | || !(device_may_wakeup(&dev->dev) |
69 | || dev->wakeup.prepare_count)) | ||
68 | continue; | 70 | continue; |
69 | 71 | ||
70 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 72 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
71 | ACPI_GPE_DISABLE); | 73 | ACPI_GPE_DISABLE); |
72 | 74 | ||
73 | if (dev->wakeup.state.enabled) | 75 | if (device_may_wakeup(&dev->dev)) |
74 | acpi_disable_wakeup_device_power(dev); | 76 | acpi_disable_wakeup_device_power(dev); |
75 | } | 77 | } |
76 | } | 78 | } |
@@ -84,8 +86,8 @@ int __init acpi_wakeup_device_init(void) | |||
84 | struct acpi_device *dev = container_of(node, | 86 | struct acpi_device *dev = container_of(node, |
85 | struct acpi_device, | 87 | struct acpi_device, |
86 | wakeup_list); | 88 | wakeup_list); |
87 | if (dev->wakeup.flags.always_enabled) | 89 | if (device_can_wakeup(&dev->dev)) |
88 | dev->wakeup.state.enabled = 1; | 90 | device_set_wakeup_enable(&dev->dev, true); |
89 | } | 91 | } |
90 | mutex_unlock(&acpi_device_lock); | 92 | mutex_unlock(&acpi_device_lock); |
91 | return 0; | 93 | return 0; |