Commit 805c5281 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'acpi-pm', 'acpi-sleep' and 'acpi-button'

* acpi-pm:
  ACPI / PM: Use ACPI_COMPANION() instead of ACPI_HANDLE()
  ACPI / PM: Always enable wakeup GPEs when enabling device wakeup
  ACPI / PM: Revork the handling of ACPI device wakeup notifications
  PM: Create PM workqueue if runtime PM is not configured too

* acpi-sleep:
  ACPI / sleep: Do not save NVS for new machines to accelerate S3

* acpi-button:
  ACPI / button: Do not propagate wakeup-from-suspend events
...@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device); ...@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event); static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev);
static int acpi_button_resume(struct device *dev); static int acpi_button_resume(struct device *dev);
#else #else
#define acpi_button_suspend NULL
#define acpi_button_resume NULL #define acpi_button_resume NULL
#endif #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 = { static struct acpi_driver acpi_button_driver = {
.name = "button", .name = "button",
...@@ -102,6 +104,7 @@ struct acpi_button { ...@@ -102,6 +104,7 @@ struct acpi_button {
struct input_dev *input; struct input_dev *input;
char phys[32]; /* for input device */ char phys[32]; /* for input device */
unsigned long pushed; unsigned long pushed;
bool suspended;
}; };
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
...@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) ...@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
if (button->type == ACPI_BUTTON_TYPE_LID) { if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device); acpi_lid_send_state(device);
} else { } else {
int keycode = test_bit(KEY_SLEEP, input->keybit) ? int keycode;
KEY_SLEEP : KEY_POWER;
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_report_key(input, keycode, 1);
input_sync(input); input_sync(input);
input_report_key(input, keycode, 0); input_report_key(input, keycode, 0);
input_sync(input); input_sync(input);
pm_wakeup_event(&device->dev, 0);
acpi_bus_generate_netlink_event( acpi_bus_generate_netlink_event(
device->pnp.device_class, device->pnp.device_class,
dev_name(&device->dev), dev_name(&device->dev),
...@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) ...@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
} }
#ifdef CONFIG_PM_SLEEP #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) static int acpi_button_resume(struct device *dev)
{ {
struct acpi_device *device = to_acpi_device(dev); struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device); struct acpi_button *button = acpi_driver_data(device);
button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID) if (button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(device); return acpi_lid_send_state(device);
return 0; return 0;
......
This diff is collapsed.
...@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (no_aspm) if (no_aspm)
pcie_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) if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true); device_set_run_wake(root->bus->bridge, true);
......
...@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { ...@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
static void acpi_sleep_dmi_check(void) 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); dmi_check_system(acpisleep_dmi_table);
} }
......
...@@ -18,31 +18,31 @@ ...@@ -18,31 +18,31 @@
#include "pci.h" #include "pci.h"
/** /**
* pci_acpi_wake_bus - Wake-up notification handler for root buses. * pci_acpi_wake_bus - Root bus wakeup notification fork function.
* @handle: ACPI handle of a device the notification is for. * @work: Work item to handle.
* @event: Type of the signaled event.
* @context: PCI root bus to wake up devices on.
*/ */
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) adev = container_of(work, struct acpi_device, wakeup.context.work);
pci_pme_wakeup_bus(pci_bus); 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. * @handle: ACPI handle of a device the notification is for.
* @event: Type of the signaled event. * @work: Work item to handle.
* @context: PCI device object to wake up.
*/ */
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) context = container_of(work, struct acpi_device_wakeup_context, work);
return; pci_dev = to_pci_dev(context->dev);
if (pci_dev->pme_poll) if (pci_dev->pme_poll)
pci_dev->pme_poll = false; pci_dev->pme_poll = false;
...@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) ...@@ -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. * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus.
* @dev: ACPI device to add the notifier for. * @dev: PCI root bridge ACPI device.
* @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
*/ */
acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev)
struct pci_bus *pci_bus)
{ {
return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_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);
} }
/** /**
...@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) ...@@ -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, acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
struct pci_dev *pci_dev) struct pci_dev *pci_dev)
{ {
return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_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);
} }
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
......
...@@ -315,12 +315,19 @@ struct acpi_device_wakeup_flags { ...@@ -315,12 +315,19 @@ struct acpi_device_wakeup_flags {
u8 notifier_present:1; /* Wake-up notify handler has been installed */ 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 { struct acpi_device_wakeup {
acpi_handle gpe_device; acpi_handle gpe_device;
u64 gpe_number; u64 gpe_number;
u64 sleep_state; u64 sleep_state;
struct list_head resources; struct list_head resources;
struct acpi_device_wakeup_flags flags; struct acpi_device_wakeup_flags flags;
struct acpi_device_wakeup_context context;
struct wakeup_source *ws;
int prepare_count; int prepare_count;
}; };
...@@ -510,20 +517,18 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); ...@@ -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); int acpi_disable_wakeup_device_power(struct acpi_device *dev);
#ifdef CONFIG_PM #ifdef CONFIG_PM
acpi_status acpi_add_pm_notifier(struct acpi_device *adev, acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
acpi_notify_handler handler, void *context); void (*work_func)(struct work_struct *work));
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
acpi_notify_handler handler);
int acpi_pm_device_sleep_state(struct device *, int *, int); int acpi_pm_device_sleep_state(struct device *, int *, int);
#else #else
static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev, static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
acpi_notify_handler handler, struct device *dev,
void *context) void (*work_func)(struct work_struct *work))
{ {
return AE_SUPPORT; return AE_SUPPORT;
} }
static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
acpi_notify_handler handler)
{ {
return AE_SUPPORT; return AE_SUPPORT;
} }
...@@ -538,13 +543,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) ...@@ -538,13 +543,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
#endif #endif
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
int __acpi_device_run_wake(struct acpi_device *, bool);
int acpi_pm_device_run_wake(struct device *, bool); int acpi_pm_device_run_wake(struct device *, bool);
#else #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) static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
{ {
return -ENODEV; return -ENODEV;
...@@ -552,14 +552,8 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) ...@@ -552,14 +552,8 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
#endif #endif
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
int acpi_pm_device_sleep_wake(struct device *, bool); int acpi_pm_device_sleep_wake(struct device *, bool);
#else #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) static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
{ {
return -ENODEV; return -ENODEV;
......
...@@ -11,12 +11,17 @@ ...@@ -11,12 +11,17 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev);
struct pci_bus *pci_bus); static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
extern 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, extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
struct pci_dev *pci_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); 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) static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
......
...@@ -24,11 +24,20 @@ ...@@ -24,11 +24,20 @@
#define RPM_AUTO 0x08 /* Use autosuspend_delay */ #define RPM_AUTO 0x08 /* Use autosuspend_delay */
#ifdef CONFIG_PM #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_suspend(struct device *dev);
extern int pm_generic_runtime_resume(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_suspend(struct device *dev);
extern int pm_runtime_force_resume(struct device *dev); extern int pm_runtime_force_resume(struct device *dev);
#else #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_suspend(struct device *dev) { return 0; }
static inline int pm_generic_runtime_resume(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; } 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; } ...@@ -37,8 +46,6 @@ static inline int pm_runtime_force_resume(struct device *dev) { return 0; }
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
extern struct workqueue_struct *pm_wq;
extern int __pm_runtime_idle(struct device *dev, int rpmflags); extern int __pm_runtime_idle(struct device *dev, int rpmflags);
extern int __pm_runtime_suspend(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); extern int __pm_runtime_resume(struct device *dev, int rpmflags);
......
...@@ -615,7 +615,6 @@ static struct attribute_group attr_group = { ...@@ -615,7 +615,6 @@ static struct attribute_group attr_group = {
.attrs = g, .attrs = g,
}; };
#ifdef CONFIG_PM_RUNTIME
struct workqueue_struct *pm_wq; struct workqueue_struct *pm_wq;
EXPORT_SYMBOL_GPL(pm_wq); EXPORT_SYMBOL_GPL(pm_wq);
...@@ -625,9 +624,6 @@ static int __init pm_start_workqueue(void) ...@@ -625,9 +624,6 @@ static int __init pm_start_workqueue(void)
return pm_wq ? 0 : -ENOMEM; return pm_wq ? 0 : -ENOMEM;
} }
#else
static inline int pm_start_workqueue(void) { return 0; }
#endif
static int __init pm_init(void) static int __init pm_init(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment