diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-12-22 18:02:44 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-03 07:09:41 -0500 |
commit | d2e5f0c16ad60a7208fd371233e63b73c990ece2 (patch) | |
tree | c8d7913c537e4fbb076e1491f6f3e72d648a8391 /drivers/pci | |
parent | 11909ca1cf614f9396b17d366f9e3cfcba7b4a99 (diff) |
ACPI / PCI: Rework the setup and cleanup of device wakeup
Currently, the ACPI wakeup capability of PCI devices is set up
in two different places, partially in acpi_pci_bind() where
runtime wakeup is initialized and partially in
platform_pci_wakeup_init(), where system wakeup is initialized.
The cleanup is only done in acpi_pci_unbind() and it only covers
runtime wakeup.
Use the new .setup() and .cleanup() callbacks in struct acpi_bus_type
to consolidate that code and do the setup and the cleanup each in one
place.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-acpi.c | 30 | ||||
-rw-r--r-- | drivers/pci/pci.c | 26 | ||||
-rw-r--r-- | drivers/pci/pci.h | 5 | ||||
-rw-r--r-- | drivers/pci/probe.c | 1 |
4 files changed, 30 insertions, 32 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 1af4008182fd..b98106c110e7 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -283,7 +283,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
283 | .is_manageable = acpi_pci_power_manageable, | 283 | .is_manageable = acpi_pci_power_manageable, |
284 | .set_state = acpi_pci_set_power_state, | 284 | .set_state = acpi_pci_set_power_state, |
285 | .choose_state = acpi_pci_choose_state, | 285 | .choose_state = acpi_pci_choose_state, |
286 | .can_wakeup = acpi_pci_can_wakeup, | ||
287 | .sleep_wake = acpi_pci_sleep_wake, | 286 | .sleep_wake = acpi_pci_sleep_wake, |
288 | .run_wake = acpi_pci_run_wake, | 287 | .run_wake = acpi_pci_run_wake, |
289 | }; | 288 | }; |
@@ -321,10 +320,39 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) | |||
321 | return 0; | 320 | return 0; |
322 | } | 321 | } |
323 | 322 | ||
323 | static void acpi_pci_wakeup_setup(struct device *dev) | ||
324 | { | ||
325 | struct acpi_device *adev = acpi_dev_pm_get_node(dev); | ||
326 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
327 | |||
328 | if (!adev || !adev->wakeup.flags.valid) | ||
329 | return; | ||
330 | |||
331 | device_set_wakeup_capable(dev, true); | ||
332 | acpi_pci_sleep_wake(pci_dev, false); | ||
333 | |||
334 | pci_acpi_add_pm_notifier(adev, pci_dev); | ||
335 | if (adev->wakeup.flags.run_wake) | ||
336 | device_set_run_wake(dev, true); | ||
337 | } | ||
338 | |||
339 | static void acpi_pci_wakeup_cleanup(struct device *dev) | ||
340 | { | ||
341 | struct acpi_device *adev = acpi_dev_pm_get_node(dev); | ||
342 | |||
343 | if (adev && adev->wakeup.flags.valid) { | ||
344 | device_set_wakeup_capable(dev, false); | ||
345 | device_set_run_wake(dev, false); | ||
346 | pci_acpi_remove_pm_notifier(adev); | ||
347 | } | ||
348 | } | ||
349 | |||
324 | static struct acpi_bus_type acpi_pci_bus = { | 350 | static struct acpi_bus_type acpi_pci_bus = { |
325 | .bus = &pci_bus_type, | 351 | .bus = &pci_bus_type, |
326 | .find_device = acpi_pci_find_device, | 352 | .find_device = acpi_pci_find_device, |
327 | .find_bridge = acpi_pci_find_root_bridge, | 353 | .find_bridge = acpi_pci_find_root_bridge, |
354 | .setup = acpi_pci_wakeup_setup, | ||
355 | .cleanup = acpi_pci_wakeup_cleanup, | ||
328 | }; | 356 | }; |
329 | 357 | ||
330 | static int __init acpi_pci_init(void) | 358 | static int __init acpi_pci_init(void) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5cb5820fae40..0c4f641b7be1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -450,7 +450,7 @@ static struct pci_platform_pm_ops *pci_platform_pm; | |||
450 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops) | 450 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops) |
451 | { | 451 | { |
452 | if (!ops->is_manageable || !ops->set_state || !ops->choose_state | 452 | if (!ops->is_manageable || !ops->set_state || !ops->choose_state |
453 | || !ops->sleep_wake || !ops->can_wakeup) | 453 | || !ops->sleep_wake) |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | pci_platform_pm = ops; | 455 | pci_platform_pm = ops; |
456 | return 0; | 456 | return 0; |
@@ -473,11 +473,6 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) | |||
473 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; | 473 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; |
474 | } | 474 | } |
475 | 475 | ||
476 | static inline bool platform_pci_can_wakeup(struct pci_dev *dev) | ||
477 | { | ||
478 | return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false; | ||
479 | } | ||
480 | |||
481 | static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | 476 | static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) |
482 | { | 477 | { |
483 | return pci_platform_pm ? | 478 | return pci_platform_pm ? |
@@ -1985,25 +1980,6 @@ void pci_pm_init(struct pci_dev *dev) | |||
1985 | } | 1980 | } |
1986 | } | 1981 | } |
1987 | 1982 | ||
1988 | /** | ||
1989 | * platform_pci_wakeup_init - init platform wakeup if present | ||
1990 | * @dev: PCI device | ||
1991 | * | ||
1992 | * Some devices don't have PCI PM caps but can still generate wakeup | ||
1993 | * events through platform methods (like ACPI events). If @dev supports | ||
1994 | * platform wakeup events, set the device flag to indicate as much. This | ||
1995 | * may be redundant if the device also supports PCI PM caps, but double | ||
1996 | * initialization should be safe in that case. | ||
1997 | */ | ||
1998 | void platform_pci_wakeup_init(struct pci_dev *dev) | ||
1999 | { | ||
2000 | if (!platform_pci_can_wakeup(dev)) | ||
2001 | return; | ||
2002 | |||
2003 | device_set_wakeup_capable(&dev->dev, true); | ||
2004 | platform_pci_sleep_wake(dev, false); | ||
2005 | } | ||
2006 | |||
2007 | static void pci_add_saved_cap(struct pci_dev *pci_dev, | 1983 | static void pci_add_saved_cap(struct pci_dev *pci_dev, |
2008 | struct pci_cap_saved_state *new_cap) | 1984 | struct pci_cap_saved_state *new_cap) |
2009 | { | 1985 | { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e8518292826f..adfd172c5b9b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -43,9 +43,6 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
43 | * platform; to be used during system-wide transitions from a | 43 | * platform; to be used during system-wide transitions from a |
44 | * sleeping state to the working state and vice versa | 44 | * sleeping state to the working state and vice versa |
45 | * | 45 | * |
46 | * @can_wakeup: returns 'true' if given device is capable of waking up the | ||
47 | * system from a sleeping state | ||
48 | * | ||
49 | * @sleep_wake: enables/disables the system wake up capability of given device | 46 | * @sleep_wake: enables/disables the system wake up capability of given device |
50 | * | 47 | * |
51 | * @run_wake: enables/disables the platform to generate run-time wake-up events | 48 | * @run_wake: enables/disables the platform to generate run-time wake-up events |
@@ -59,7 +56,6 @@ struct pci_platform_pm_ops { | |||
59 | bool (*is_manageable)(struct pci_dev *dev); | 56 | bool (*is_manageable)(struct pci_dev *dev); |
60 | int (*set_state)(struct pci_dev *dev, pci_power_t state); | 57 | int (*set_state)(struct pci_dev *dev, pci_power_t state); |
61 | pci_power_t (*choose_state)(struct pci_dev *dev); | 58 | pci_power_t (*choose_state)(struct pci_dev *dev); |
62 | bool (*can_wakeup)(struct pci_dev *dev); | ||
63 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 59 | int (*sleep_wake)(struct pci_dev *dev, bool enable); |
64 | int (*run_wake)(struct pci_dev *dev, bool enable); | 60 | int (*run_wake)(struct pci_dev *dev, bool enable); |
65 | }; | 61 | }; |
@@ -74,7 +70,6 @@ extern void pci_wakeup_bus(struct pci_bus *bus); | |||
74 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); | 70 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); |
75 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); | 71 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); |
76 | extern void pci_pm_init(struct pci_dev *dev); | 72 | extern void pci_pm_init(struct pci_dev *dev); |
77 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | ||
78 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 73 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
79 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 74 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
80 | 75 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6186f03d84f3..2dcd22d9c816 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1280,7 +1280,6 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1280 | 1280 | ||
1281 | /* Power Management */ | 1281 | /* Power Management */ |
1282 | pci_pm_init(dev); | 1282 | pci_pm_init(dev); |
1283 | platform_pci_wakeup_init(dev); | ||
1284 | 1283 | ||
1285 | /* Vital Product Data */ | 1284 | /* Vital Product Data */ |
1286 | pci_vpd_pci22_init(dev); | 1285 | pci_vpd_pci22_init(dev); |