diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index db35594d4df7..6d5d1832a588 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); #ifdef CONFIG_PM_SLEEP +static int acpi_button_suspend(struct device *dev); static int acpi_button_resume(struct device *dev); #else +#define acpi_button_suspend NULL #define acpi_button_resume NULL #endif -static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); +static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); static struct acpi_driver acpi_button_driver = { .name = "button", @@ -102,6 +104,7 @@ struct acpi_button { struct input_dev *input; char phys[32]; /* for input device */ unsigned long pushed; + bool suspended; }; static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); @@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) if (button->type == ACPI_BUTTON_TYPE_LID) { acpi_lid_send_state(device); } else { - int keycode = test_bit(KEY_SLEEP, input->keybit) ? - KEY_SLEEP : KEY_POWER; + int keycode; + pm_wakeup_event(&device->dev, 0); + if (button->suspended) + break; + + keycode = test_bit(KEY_SLEEP, input->keybit) ? + KEY_SLEEP : KEY_POWER; input_report_key(input, keycode, 1); input_sync(input); input_report_key(input, keycode, 0); input_sync(input); - pm_wakeup_event(&device->dev, 0); acpi_bus_generate_netlink_event( device->pnp.device_class, dev_name(&device->dev), @@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } #ifdef CONFIG_PM_SLEEP +static int acpi_button_suspend(struct device *dev) +{ + struct acpi_device *device = to_acpi_device(dev); + struct acpi_button *button = acpi_driver_data(device); + + button->suspended = true; + return 0; +} + static int acpi_button_resume(struct device *dev) { struct acpi_device *device = to_acpi_device(dev); struct acpi_button *button = acpi_driver_data(device); + button->suspended = false; if (button->type == ACPI_BUTTON_TYPE_LID) return acpi_lid_send_state(device); return 0; diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 49a51277f81d..67075f800e34 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -367,29 +367,61 @@ EXPORT_SYMBOL(acpi_bus_power_manageable); #ifdef CONFIG_PM static DEFINE_MUTEX(acpi_pm_notifier_lock); +static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) +{ + struct acpi_device *adev; + + if (val != ACPI_NOTIFY_DEVICE_WAKE) + return; + + adev = acpi_bus_get_acpi_device(handle); + if (!adev) + return; + + mutex_lock(&acpi_pm_notifier_lock); + + if (adev->wakeup.flags.notifier_present) { + __pm_wakeup_event(adev->wakeup.ws, 0); + if (adev->wakeup.context.work.func) + queue_pm_work(&adev->wakeup.context.work); + } + + mutex_unlock(&acpi_pm_notifier_lock); + + acpi_bus_put_acpi_device(adev); +} + /** - * acpi_add_pm_notifier - Register PM notifier for given ACPI device. - * @adev: ACPI device to add the notifier for. - * @context: Context information to pass to the notifier routine. + * 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. * * 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 * if one of the devices below the bridge is signaling wakeup, even if the * bridge itself doesn't have a wakeup GPE associated with it. */ -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, void *context) +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, + void (*work_func)(struct work_struct *work)) { acpi_status status = AE_ALREADY_EXISTS; + if (!dev && !work_func) + return AE_BAD_PARAMETER; + mutex_lock(&acpi_pm_notifier_lock); if (adev->wakeup.flags.notifier_present) goto out; - status = acpi_install_notify_handler(adev->handle, - ACPI_SYSTEM_NOTIFY, - handler, context); + 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); + + status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, + acpi_pm_notify_handler, NULL); if (ACPI_FAILURE(status)) goto out; @@ -404,8 +436,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. * @adev: ACPI device to remove the notifier from. */ -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler) +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) { acpi_status status = AE_BAD_PARAMETER; @@ -416,10 +447,17 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, status = acpi_remove_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, - handler); + acpi_pm_notify_handler); 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.dev = NULL; + wakeup_source_unregister(adev->wakeup.ws); + adev->wakeup.flags.notifier_present = false; out: @@ -558,7 +596,6 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, */ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) { - acpi_handle handle = ACPI_HANDLE(dev); struct acpi_device *adev; int ret, d_min, d_max; @@ -573,8 +610,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) d_max_in = ACPI_STATE_D3_HOT; } - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + adev = ACPI_COMPANION(dev); + if (!adev) { + dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } @@ -600,26 +638,25 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) } EXPORT_SYMBOL(acpi_pm_device_sleep_state); -#ifdef CONFIG_PM_RUNTIME /** - * acpi_wakeup_device - Wakeup notification handler for ACPI devices. - * @handle: ACPI handle of the device the notification is for. - * @event: Type of the signaled event. - * @context: Device corresponding to @handle. + * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. + * @work: Work item to handle. */ -static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context) +static void acpi_pm_notify_work_func(struct work_struct *work) { - struct device *dev = context; + struct device *dev; - if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) { + dev = container_of(work, struct acpi_device_wakeup_context, work)->dev; + if (dev) { pm_wakeup_event(dev, 0); pm_runtime_resume(dev); } } /** - * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. - * @adev: ACPI device to enable/disable the remote wakeup for. + * acpi_device_wakeup - Enable/disable wakeup functionality for device. + * @adev: ACPI device to enable/disable wakeup functionality for. + * @target_state: State the system is transitioning into. * @enable: Whether to enable or disable the wakeup functionality. * * Enable/disable the GPE associated with @adev so that it can generate @@ -629,7 +666,8 @@ static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context) * Callers must ensure that @adev is a valid ACPI device node before executing * this function. */ -int __acpi_device_run_wake(struct acpi_device *adev, bool enable) +static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, + bool enable) { struct acpi_device_wakeup *wakeup = &adev->wakeup; @@ -637,7 +675,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable) acpi_status res; int error; - error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0); + error = acpi_enable_wakeup_device_power(adev, target_state); if (error) return error; @@ -653,6 +691,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable) return 0; } +#ifdef CONFIG_PM_RUNTIME /** * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. * @dev: Device to enable/disable the platform to wake up. @@ -661,41 +700,22 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable) int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) { struct acpi_device *adev; - acpi_handle handle; if (!device_run_wake(phys_dev)) return -EINVAL; - handle = ACPI_HANDLE(phys_dev); - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(phys_dev, "ACPI handle without context in %s!\n", - __func__); + adev = ACPI_COMPANION(phys_dev); + if (!adev) { + dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } - return __acpi_device_run_wake(adev, enable); + return acpi_device_wakeup(adev, enable, ACPI_STATE_S0); } EXPORT_SYMBOL(acpi_pm_device_run_wake); -#else -static inline void acpi_wakeup_device(acpi_handle handle, u32 event, - void *context) {} #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP -/** - * __acpi_device_sleep_wake - Enable or disable device to wake up the system. - * @dev: Device to enable/desible to wake up the system. - * @target_state: System state the device is supposed to wake up from. - * @enable: Whether to enable or disable @dev to wake up the system. - */ -int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, - bool enable) -{ - return enable ? - acpi_enable_wakeup_device_power(adev, target_state) : - acpi_disable_wakeup_device_power(adev); -} - /** * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. * @dev: Device to enable/desible to wake up the system from sleep states. @@ -703,21 +723,19 @@ int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, */ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { - acpi_handle handle; struct acpi_device *adev; int error; if (!device_can_wakeup(dev)) return -EINVAL; - handle = ACPI_HANDLE(dev); - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + adev = ACPI_COMPANION(dev); + if (!adev) { + dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } - error = __acpi_device_sleep_wake(adev, acpi_target_system_state(), - 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"); @@ -775,13 +793,13 @@ int acpi_dev_runtime_suspend(struct device *dev) remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) > PM_QOS_FLAGS_NONE; - error = __acpi_device_run_wake(adev, remote_wakeup); + error = acpi_device_wakeup(adev, ACPI_STATE_S0, remote_wakeup); if (remote_wakeup && error) return -EAGAIN; error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); if (error) - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); return error; } @@ -804,7 +822,7 @@ int acpi_dev_runtime_resume(struct device *dev) return 0; error = acpi_dev_pm_full_power(adev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); return error; } EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume); @@ -860,13 +878,13 @@ int acpi_dev_suspend_late(struct device *dev) target_state = acpi_target_system_state(); wakeup = device_may_wakeup(dev); - error = __acpi_device_sleep_wake(adev, target_state, wakeup); + error = acpi_device_wakeup(adev, target_state, wakeup); if (wakeup && error) return error; error = acpi_dev_pm_low_power(dev, adev, target_state); if (error) - __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false); return error; } @@ -889,7 +907,7 @@ int acpi_dev_resume_early(struct device *dev) return 0; error = acpi_dev_pm_full_power(adev); - __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false); return error; } EXPORT_SYMBOL_GPL(acpi_dev_resume_early); @@ -1048,11 +1066,11 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) if (dev->pm_domain) return -EEXIST; - acpi_add_pm_notifier(adev, acpi_wakeup_device, dev); + acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func); dev->pm_domain = &acpi_general_pm_domain; if (power_on) { acpi_dev_pm_full_power(adev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); } return 0; } @@ -1076,7 +1094,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off) if (adev && dev->pm_domain == &acpi_general_pm_domain) { dev->pm_domain = NULL; - acpi_remove_pm_notifier(adev, acpi_wakeup_device); + acpi_remove_pm_notifier(adev); if (power_off) { /* * If the device's PM QoS resume latency limit or flags @@ -1086,7 +1104,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off) */ dev_pm_qos_hide_latency_limit(dev); dev_pm_qos_hide_flags(dev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); } } diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d388f13d48b4..e6ae603ed1a1 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device, if (no_aspm) pcie_no_aspm(); - pci_acpi_add_bus_pm_notifier(device, root->bus); + pci_acpi_add_bus_pm_notifier(device); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index b3e3cc73ba79..54da4a3fe65e 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { static void acpi_sleep_dmi_check(void) { + int year; + + if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) + acpi_nvs_nosave_s3(); + dmi_check_system(acpisleep_dmi_table); } diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ca4927ba8433..7b8b2298840a 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -18,31 +18,31 @@ #include "pci.h" /** - * pci_acpi_wake_bus - Wake-up notification handler for root buses. - * @handle: ACPI handle of a device the notification is for. - * @event: Type of the signaled event. - * @context: PCI root bus to wake up devices on. + * pci_acpi_wake_bus - Root bus wakeup notification fork function. + * @work: Work item to handle. */ -static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) +static void pci_acpi_wake_bus(struct work_struct *work) { - struct pci_bus *pci_bus = context; + struct acpi_device *adev; + struct acpi_pci_root *root; - if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) - pci_pme_wakeup_bus(pci_bus); + adev = container_of(work, struct acpi_device, wakeup.context.work); + root = acpi_driver_data(adev); + pci_pme_wakeup_bus(root->bus); } /** - * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. + * pci_acpi_wake_dev - PCI device wakeup notification work function. * @handle: ACPI handle of a device the notification is for. - * @event: Type of the signaled event. - * @context: PCI device object to wake up. + * @work: Work item to handle. */ -static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) +static void pci_acpi_wake_dev(struct work_struct *work) { - struct pci_dev *pci_dev = context; + struct acpi_device_wakeup_context *context; + struct pci_dev *pci_dev; - if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) - return; + context = container_of(work, struct acpi_device_wakeup_context, work); + pci_dev = to_pci_dev(context->dev); if (pci_dev->pme_poll) pci_dev->pme_poll = false; @@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) } /** - * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. - * @dev: ACPI device to add the notifier for. - * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. + * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus. + * @dev: PCI root bridge ACPI device. */ -acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, - struct pci_bus *pci_bus) +acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev) { - return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); -} - -/** - * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. - * @dev: ACPI device to remove the notifier from. - */ -acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) -{ - return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); + return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus); } /** @@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev) { - return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); -} - -/** - * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. - * @dev: ACPI device to remove the notifier from. - */ -acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) -{ - return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev); + return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev); } phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b5714580801a..a0b08457452d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -315,12 +315,19 @@ struct acpi_device_wakeup_flags { u8 notifier_present:1; /* Wake-up notify handler has been installed */ }; +struct acpi_device_wakeup_context { + struct work_struct work; + struct device *dev; +}; + struct acpi_device_wakeup { acpi_handle gpe_device; u64 gpe_number; u64 sleep_state; struct list_head resources; struct acpi_device_wakeup_flags flags; + struct acpi_device_wakeup_context context; + struct wakeup_source *ws; int prepare_count; }; @@ -510,20 +517,18 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_PM -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, void *context); -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler); +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, + void (*work_func)(struct work_struct *work)); +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev); int acpi_pm_device_sleep_state(struct device *, int *, int); #else static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, - void *context) + struct device *dev, + void (*work_func)(struct work_struct *work)) { return AE_SUPPORT; } -static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler) +static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) { return AE_SUPPORT; } @@ -538,13 +543,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) #endif #ifdef CONFIG_PM_RUNTIME -int __acpi_device_run_wake(struct acpi_device *, bool); int acpi_pm_device_run_wake(struct device *, bool); #else -static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en) -{ - return -ENODEV; -} static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) { return -ENODEV; @@ -552,14 +552,8 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP -int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else -static inline int __acpi_device_sleep_wake(struct acpi_device *adev, - u32 target_state, bool enable) -{ - return -ENODEV; -} static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 637a608ded0b..64dacb7288a6 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -11,12 +11,17 @@ #include #ifdef CONFIG_ACPI -extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, - struct pci_bus *pci_bus); -extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev); +extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev); +static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) +{ + return acpi_remove_pm_notifier(dev); +} extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev); -extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev); +static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) +{ + return acpi_remove_pm_notifier(dev); +} extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 43fd6716f662..367f49b9a1c9 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -24,11 +24,20 @@ #define RPM_AUTO 0x08 /* Use autosuspend_delay */ #ifdef CONFIG_PM +extern struct workqueue_struct *pm_wq; + +static inline bool queue_pm_work(struct work_struct *work) +{ + return queue_work(pm_wq, work); +} + extern int pm_generic_runtime_suspend(struct device *dev); extern int pm_generic_runtime_resume(struct device *dev); extern int pm_runtime_force_suspend(struct device *dev); extern int pm_runtime_force_resume(struct device *dev); #else +static inline bool queue_pm_work(struct work_struct *work) { return false; } + static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } static inline int pm_runtime_force_suspend(struct device *dev) { return 0; } @@ -37,8 +46,6 @@ static inline int pm_runtime_force_resume(struct device *dev) { return 0; } #ifdef CONFIG_PM_RUNTIME -extern struct workqueue_struct *pm_wq; - extern int __pm_runtime_idle(struct device *dev, int rpmflags); extern int __pm_runtime_suspend(struct device *dev, int rpmflags); extern int __pm_runtime_resume(struct device *dev, int rpmflags); diff --git a/kernel/power/main.c b/kernel/power/main.c index 8e90f330f139..a18efed75fa7 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -615,7 +615,6 @@ static struct attribute_group attr_group = { .attrs = g, }; -#ifdef CONFIG_PM_RUNTIME struct workqueue_struct *pm_wq; EXPORT_SYMBOL_GPL(pm_wq); @@ -625,9 +624,6 @@ static int __init pm_start_workqueue(void) return pm_wq ? 0 : -ENOMEM; } -#else -static inline int pm_start_workqueue(void) { return 0; } -#endif static int __init pm_init(void) {