Loading drivers/acpi/acpica/evmisc.c +55 −39 Original line number Diff line number Diff line Loading @@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) * RETURN: ACPI_INTERRUPT_HANDLED * * DESCRIPTION: Invoked directly from the SCI handler when a global lock * release interrupt occurs. Attempt to acquire the global lock, * if successful, signal the thread waiting for the lock. * release interrupt occurs. If there's a thread waiting for * the global lock, signal it. * * NOTE: Assumes that the semaphore can be signaled from interrupt level. If * this is not possible for some reason, a separate thread will have to be * scheduled to do this. * ******************************************************************************/ static u8 acpi_ev_global_lock_pending; static spinlock_t _acpi_ev_global_lock_pending_lock; #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock static u32 acpi_ev_global_lock_handler(void *context) { u8 acquired = FALSE; acpi_status status; acpi_cpu_flags flags; /* * Attempt to get the lock. * * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); /* Got the lock, now wake all threads waiting for it */ if (!acpi_ev_global_lock_pending) { goto out; } acpi_gbl_global_lock_acquired = TRUE; /* Send a unit to the semaphore */ if (ACPI_FAILURE (acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore, 1))) { ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); } status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); } acpi_ev_global_lock_pending = FALSE; out: acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); return (ACPI_INTERRUPT_HANDLED); } Loading Loading @@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired; acpi_status acpi_ev_acquire_global_lock(u16 timeout) { acpi_cpu_flags flags; acpi_status status = AE_OK; u8 acquired = FALSE; Loading Loading @@ -467,33 +468,48 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) return_ACPI_STATUS(AE_OK); } flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); do { /* Attempt to acquire the actual hardware lock */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { /* We got the lock */ acpi_gbl_global_lock_acquired = TRUE; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); break; } acpi_ev_global_lock_pending = TRUE; acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); /* * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. * Did not get the lock. The pending bit was set above, and we * must wait until we get the global lock released interrupt. */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); /* * Wait for handshake with the global lock interrupt handler. * This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, status = acpi_ex_system_wait_semaphore( acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); } while (ACPI_SUCCESS(status)); acpi_ev_global_lock_pending = FALSE; acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); return_ACPI_STATUS(status); } Loading drivers/acpi/button.c +7 −2 Original line number Diff line number Diff line Loading @@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device) input_report_switch(button->input, SW_LID, !state); input_sync(button->input); if (state) pm_wakeup_event(&device->dev, 0); ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); if (ret == NOTIFY_DONE) ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, Loading Loading @@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) input_sync(input); input_report_key(input, keycode, 0); input_sync(input); pm_wakeup_event(&device->dev, 0); } acpi_bus_generate_proc_event(device, event, ++button->pushed); Loading Loading @@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device) acpi_enable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; device_set_wakeup_enable(&device->dev, true); } printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); Loading @@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) acpi_disable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; device_set_wakeup_enable(&device->dev, false); } acpi_button_remove_fs(device); Loading drivers/acpi/glue.c +1 −4 Original line number Diff line number Diff line Loading @@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) "firmware_node"); ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, "physical_node"); if (acpi_dev->wakeup.flags.valid) { if (acpi_dev->wakeup.flags.valid) device_set_wakeup_capable(dev, true); device_set_wakeup_enable(dev, acpi_dev->wakeup.state.enabled); } } return 0; Loading drivers/acpi/proc.c +12 −29 Original line number Diff line number Diff line Loading @@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) dev->pnp.bus_id, (u32) dev->wakeup.sleep_state, dev->wakeup.flags.run_wake ? '*' : ' ', dev->wakeup.state.enabled ? "enabled" : "disabled"); (device_may_wakeup(&dev->dev) || (ldev && device_may_wakeup(ldev))) ? "enabled" : "disabled"); if (ldev) seq_printf(seq, "%s:%s", ldev->bus ? ldev->bus->name : "no-bus", Loading @@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev) { struct device *dev = acpi_get_physical_device(adev->handle); if (dev && device_can_wakeup(dev)) device_set_wakeup_enable(dev, adev->wakeup.state.enabled); if (dev && device_can_wakeup(dev)) { bool enable = !device_may_wakeup(dev); device_set_wakeup_enable(dev, enable); } } static ssize_t Loading @@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file, char strbuf[5]; char str[5] = ""; unsigned int len = count; struct acpi_device *found_dev = NULL; if (len > 4) len = 4; Loading @@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file, continue; if (!strncmp(dev->pnp.bus_id, str, 4)) { dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0 : 1; found_dev = dev; break; } } if (found_dev) { physical_device_enable_wakeup(found_dev); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); if ((dev != found_dev) && (dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) && (dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) { printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, " "can't disable/enable one separately\n", dev->pnp.bus_id, found_dev->pnp.bus_id); dev->wakeup.state.enabled = found_dev->wakeup.state.enabled; if (device_can_wakeup(&dev->dev)) { bool enable = !device_may_wakeup(&dev->dev); device_set_wakeup_enable(&dev->dev, enable); } else { physical_device_enable_wakeup(dev); } break; } } mutex_unlock(&acpi_device_lock); Loading drivers/acpi/scan.c +1 −1 Original line number Diff line number Diff line Loading @@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) /* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) { device->wakeup.flags.run_wake = 1; device->wakeup.flags.always_enabled = 1; device_set_wakeup_capable(&device->dev, true); return; } Loading Loading
drivers/acpi/acpica/evmisc.c +55 −39 Original line number Diff line number Diff line Loading @@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) * RETURN: ACPI_INTERRUPT_HANDLED * * DESCRIPTION: Invoked directly from the SCI handler when a global lock * release interrupt occurs. Attempt to acquire the global lock, * if successful, signal the thread waiting for the lock. * release interrupt occurs. If there's a thread waiting for * the global lock, signal it. * * NOTE: Assumes that the semaphore can be signaled from interrupt level. If * this is not possible for some reason, a separate thread will have to be * scheduled to do this. * ******************************************************************************/ static u8 acpi_ev_global_lock_pending; static spinlock_t _acpi_ev_global_lock_pending_lock; #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock static u32 acpi_ev_global_lock_handler(void *context) { u8 acquired = FALSE; acpi_status status; acpi_cpu_flags flags; /* * Attempt to get the lock. * * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); /* Got the lock, now wake all threads waiting for it */ if (!acpi_ev_global_lock_pending) { goto out; } acpi_gbl_global_lock_acquired = TRUE; /* Send a unit to the semaphore */ if (ACPI_FAILURE (acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore, 1))) { ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); } status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); } acpi_ev_global_lock_pending = FALSE; out: acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); return (ACPI_INTERRUPT_HANDLED); } Loading Loading @@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired; acpi_status acpi_ev_acquire_global_lock(u16 timeout) { acpi_cpu_flags flags; acpi_status status = AE_OK; u8 acquired = FALSE; Loading Loading @@ -467,33 +468,48 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) return_ACPI_STATUS(AE_OK); } flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); do { /* Attempt to acquire the actual hardware lock */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { /* We got the lock */ acpi_gbl_global_lock_acquired = TRUE; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); break; } acpi_ev_global_lock_pending = TRUE; acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); /* * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. * Did not get the lock. The pending bit was set above, and we * must wait until we get the global lock released interrupt. */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); /* * Wait for handshake with the global lock interrupt handler. * This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, status = acpi_ex_system_wait_semaphore( acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); } while (ACPI_SUCCESS(status)); acpi_ev_global_lock_pending = FALSE; acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); return_ACPI_STATUS(status); } Loading
drivers/acpi/button.c +7 −2 Original line number Diff line number Diff line Loading @@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device) input_report_switch(button->input, SW_LID, !state); input_sync(button->input); if (state) pm_wakeup_event(&device->dev, 0); ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); if (ret == NOTIFY_DONE) ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, Loading Loading @@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) input_sync(input); input_report_key(input, keycode, 0); input_sync(input); pm_wakeup_event(&device->dev, 0); } acpi_bus_generate_proc_event(device, event, ++button->pushed); Loading Loading @@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device) acpi_enable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; device_set_wakeup_enable(&device->dev, true); } printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); Loading @@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) acpi_disable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; device_set_wakeup_enable(&device->dev, false); } acpi_button_remove_fs(device); Loading
drivers/acpi/glue.c +1 −4 Original line number Diff line number Diff line Loading @@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) "firmware_node"); ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, "physical_node"); if (acpi_dev->wakeup.flags.valid) { if (acpi_dev->wakeup.flags.valid) device_set_wakeup_capable(dev, true); device_set_wakeup_enable(dev, acpi_dev->wakeup.state.enabled); } } return 0; Loading
drivers/acpi/proc.c +12 −29 Original line number Diff line number Diff line Loading @@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) dev->pnp.bus_id, (u32) dev->wakeup.sleep_state, dev->wakeup.flags.run_wake ? '*' : ' ', dev->wakeup.state.enabled ? "enabled" : "disabled"); (device_may_wakeup(&dev->dev) || (ldev && device_may_wakeup(ldev))) ? "enabled" : "disabled"); if (ldev) seq_printf(seq, "%s:%s", ldev->bus ? ldev->bus->name : "no-bus", Loading @@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev) { struct device *dev = acpi_get_physical_device(adev->handle); if (dev && device_can_wakeup(dev)) device_set_wakeup_enable(dev, adev->wakeup.state.enabled); if (dev && device_can_wakeup(dev)) { bool enable = !device_may_wakeup(dev); device_set_wakeup_enable(dev, enable); } } static ssize_t Loading @@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file, char strbuf[5]; char str[5] = ""; unsigned int len = count; struct acpi_device *found_dev = NULL; if (len > 4) len = 4; Loading @@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file, continue; if (!strncmp(dev->pnp.bus_id, str, 4)) { dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0 : 1; found_dev = dev; break; } } if (found_dev) { physical_device_enable_wakeup(found_dev); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); if ((dev != found_dev) && (dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) && (dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) { printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, " "can't disable/enable one separately\n", dev->pnp.bus_id, found_dev->pnp.bus_id); dev->wakeup.state.enabled = found_dev->wakeup.state.enabled; if (device_can_wakeup(&dev->dev)) { bool enable = !device_may_wakeup(&dev->dev); device_set_wakeup_enable(&dev->dev, enable); } else { physical_device_enable_wakeup(dev); } break; } } mutex_unlock(&acpi_device_lock); Loading
drivers/acpi/scan.c +1 −1 Original line number Diff line number Diff line Loading @@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) /* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) { device->wakeup.flags.run_wake = 1; device->wakeup.flags.always_enabled = 1; device_set_wakeup_capable(&device->dev, true); return; } Loading