X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=drivers%2Facpi%2Fdevice_pm.c;h=ca02102137734e3b37ab879d268dc58a934d0e24;hb=33e4f80ee69b;hp=798d5003a039d876f275fc2d933be71cb7ebfbed;hpb=035f1456f9ed256cd1a92ae1b81cc24413359e61;p=mirror_ubuntu-artful-kernel.git diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 798d5003a039..ca0210213773 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -386,6 +386,12 @@ EXPORT_SYMBOL(acpi_bus_power_manageable); #ifdef CONFIG_PM static DEFINE_MUTEX(acpi_pm_notifier_lock); +void acpi_pm_wakeup_event(struct device *dev) +{ + pm_wakeup_dev_event(dev, 0, acpi_s2idle_wakeup()); +} +EXPORT_SYMBOL_GPL(acpi_pm_wakeup_event); + static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) { struct acpi_device *adev; @@ -400,9 +406,9 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) mutex_lock(&acpi_pm_notifier_lock); if (adev->wakeup.flags.notifier_present) { - pm_wakeup_ws_event(adev->wakeup.ws, 0, true); - if (adev->wakeup.context.work.func) - queue_pm_work(&adev->wakeup.context.work); + pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup()); + if (adev->wakeup.context.func) + adev->wakeup.context.func(&adev->wakeup.context); } mutex_unlock(&acpi_pm_notifier_lock); @@ -414,7 +420,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) * acpi_add_pm_notifier - Register PM notify handler for given ACPI device. * @adev: ACPI device to add the notify handler for. * @dev: Device to generate a wakeup event for while handling the notification. - * @work_func: Work function to execute when handling the notification. + * @func: Work function to execute when handling the notification. * * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of * PM wakeup events. For example, wakeup events may be generated for bridges @@ -422,11 +428,11 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) * bridge itself doesn't have a wakeup GPE associated with it. */ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, - void (*work_func)(struct work_struct *work)) + void (*func)(struct acpi_device_wakeup_context *context)) { acpi_status status = AE_ALREADY_EXISTS; - if (!dev && !work_func) + if (!dev && !func) return AE_BAD_PARAMETER; mutex_lock(&acpi_pm_notifier_lock); @@ -436,8 +442,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); adev->wakeup.context.dev = dev; - if (work_func) - INIT_WORK(&adev->wakeup.context.work, work_func); + adev->wakeup.context.func = func; status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, acpi_pm_notify_handler, NULL); @@ -470,10 +475,7 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) if (ACPI_FAILURE(status)) goto out; - if (adev->wakeup.context.work.func) { - cancel_work_sync(&adev->wakeup.context.work); - adev->wakeup.context.work.func = NULL; - } + adev->wakeup.context.func = NULL; adev->wakeup.context.dev = NULL; wakeup_source_unregister(adev->wakeup.ws); @@ -659,16 +661,15 @@ EXPORT_SYMBOL(acpi_pm_device_sleep_state); /** * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. - * @work: Work item to handle. + * @context: Device wakeup context. */ -static void acpi_pm_notify_work_func(struct work_struct *work) +static void acpi_pm_notify_work_func(struct acpi_device_wakeup_context *context) { - struct device *dev; + struct device *dev = context->dev; - dev = container_of(work, struct acpi_device_wakeup_context, work)->dev; if (dev) { pm_wakeup_event(dev, 0); - pm_runtime_resume(dev); + pm_request_resume(dev); } } @@ -694,26 +695,23 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, acpi_status res; int error; + if (adev->wakeup.flags.enabled) + return 0; + error = acpi_enable_wakeup_device_power(adev, target_state); if (error) return error; - if (adev->wakeup.flags.enabled) - return 0; - res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); - if (ACPI_SUCCESS(res)) { - adev->wakeup.flags.enabled = 1; - } else { + if (ACPI_FAILURE(res)) { acpi_disable_wakeup_device_power(adev); return -EIO; } - } else { - if (adev->wakeup.flags.enabled) { - acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); - adev->wakeup.flags.enabled = 0; - } + adev->wakeup.flags.enabled = 1; + } else if (adev->wakeup.flags.enabled) { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); acpi_disable_wakeup_device_power(adev); + adev->wakeup.flags.enabled = 0; } return 0; } @@ -762,8 +760,8 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) error = acpi_device_wakeup(adev, acpi_target_system_state(), enable); if (!error) - dev_info(dev, "System wakeup %s by ACPI\n", - enable ? "enabled" : "disabled"); + dev_dbg(dev, "System wakeup %s by ACPI\n", + enable ? "enabled" : "disabled"); return error; }