diff options
-rw-r--r-- | drivers/acpi/internal.h | 2 | ||||
-rw-r--r-- | drivers/acpi/pci_bind.c | 14 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 8 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 1 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 211 | ||||
-rw-r--r-- | drivers/pci/pci.c | 67 | ||||
-rw-r--r-- | drivers/pci/pci.h | 7 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 4 | ||||
-rw-r--r-- | include/linux/pci-acpi.h | 7 | ||||
-rw-r--r-- | include/linux/pci.h | 1 |
10 files changed, 319 insertions, 3 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index cb28e0502acc..9c4c962e46e3 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -36,8 +36,6 @@ static inline int acpi_debug_init(void) { return 0; } | |||
36 | int acpi_power_init(void); | 36 | int acpi_power_init(void); |
37 | int acpi_device_sleep_wake(struct acpi_device *dev, | 37 | int acpi_device_sleep_wake(struct acpi_device *dev, |
38 | int enable, int sleep_state, int dev_state); | 38 | int enable, int sleep_state, int dev_state); |
39 | int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state); | ||
40 | int acpi_disable_wakeup_device_power(struct acpi_device *dev); | ||
41 | int acpi_power_get_inferred_state(struct acpi_device *device); | 39 | int acpi_power_get_inferred_state(struct acpi_device *device); |
42 | int acpi_power_transition(struct acpi_device *device, int state); | 40 | int acpi_power_transition(struct acpi_device *device, int state); |
43 | extern int acpi_power_nocheck; | 41 | extern int acpi_power_nocheck; |
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index a5a77b78a723..2ef04098cc1d 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -26,7 +26,9 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci-acpi.h> | ||
29 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <linux/pm_runtime.h> | ||
30 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
31 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
32 | 34 | ||
@@ -38,7 +40,13 @@ static int acpi_pci_unbind(struct acpi_device *device) | |||
38 | struct pci_dev *dev; | 40 | struct pci_dev *dev; |
39 | 41 | ||
40 | dev = acpi_get_pci_dev(device->handle); | 42 | dev = acpi_get_pci_dev(device->handle); |
41 | if (!dev || !dev->subordinate) | 43 | if (!dev) |
44 | goto out; | ||
45 | |||
46 | device_set_run_wake(&dev->dev, false); | ||
47 | pci_acpi_remove_pm_notifier(device); | ||
48 | |||
49 | if (!dev->subordinate) | ||
42 | goto out; | 50 | goto out; |
43 | 51 | ||
44 | acpi_pci_irq_del_prt(dev->subordinate); | 52 | acpi_pci_irq_del_prt(dev->subordinate); |
@@ -62,6 +70,10 @@ static int acpi_pci_bind(struct acpi_device *device) | |||
62 | if (!dev) | 70 | if (!dev) |
63 | return 0; | 71 | return 0; |
64 | 72 | ||
73 | pci_acpi_add_pm_notifier(device, dev); | ||
74 | if (device->wakeup.flags.run_wake) | ||
75 | device_set_run_wake(&dev->dev, true); | ||
76 | |||
65 | /* | 77 | /* |
66 | * Install the 'bind' function to facilitate callbacks for | 78 | * Install the 'bind' function to facilitate callbacks for |
67 | * children of the P2P bridge. | 79 | * children of the P2P bridge. |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 64f55b6db73c..9cd8bedb1e5a 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/pm.h> | 32 | #include <linux/pm.h> |
33 | #include <linux/pm_runtime.h> | ||
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | #include <linux/pci-acpi.h> | 35 | #include <linux/pci-acpi.h> |
35 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
@@ -528,6 +529,10 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
528 | if (flags != base_flags) | 529 | if (flags != base_flags) |
529 | acpi_pci_osc_support(root, flags); | 530 | acpi_pci_osc_support(root, flags); |
530 | 531 | ||
532 | pci_acpi_add_bus_pm_notifier(device, root->bus); | ||
533 | if (device->wakeup.flags.run_wake) | ||
534 | device_set_run_wake(root->bus->bridge, true); | ||
535 | |||
531 | return 0; | 536 | return 0; |
532 | 537 | ||
533 | end: | 538 | end: |
@@ -549,6 +554,9 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
549 | { | 554 | { |
550 | struct acpi_pci_root *root = acpi_driver_data(device); | 555 | struct acpi_pci_root *root = acpi_driver_data(device); |
551 | 556 | ||
557 | device_set_run_wake(root->bus->bridge, false); | ||
558 | pci_acpi_remove_bus_pm_notifier(device); | ||
559 | |||
552 | kfree(root); | 560 | kfree(root); |
553 | return 0; | 561 | return 0; |
554 | } | 562 | } |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7491a52ad97a..fb7fc24fe727 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -753,6 +753,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
753 | acpi_event_status event_status; | 753 | acpi_event_status event_status; |
754 | 754 | ||
755 | device->wakeup.run_wake_count = 0; | 755 | device->wakeup.run_wake_count = 0; |
756 | device->wakeup.flags.notifier_present = 0; | ||
756 | 757 | ||
757 | /* Power button, Lid switch always enable wakeup */ | 758 | /* Power button, Lid switch always enable wakeup */ |
758 | if (!acpi_match_device_ids(device, button_device_ids)) { | 759 | if (!acpi_match_device_ids(device, button_device_ids)) { |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7e2829538a4c..c0c73913833d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -16,8 +16,144 @@ | |||
16 | #include <acpi/acpi_bus.h> | 16 | #include <acpi/acpi_bus.h> |
17 | 17 | ||
18 | #include <linux/pci-acpi.h> | 18 | #include <linux/pci-acpi.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
22 | static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); | ||
23 | |||
24 | /** | ||
25 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. | ||
26 | * @handle: ACPI handle of a device the notification is for. | ||
27 | * @event: Type of the signaled event. | ||
28 | * @context: PCI root bus to wake up devices on. | ||
29 | */ | ||
30 | static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) | ||
31 | { | ||
32 | struct pci_bus *pci_bus = context; | ||
33 | |||
34 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) | ||
35 | pci_pme_wakeup_bus(pci_bus); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. | ||
40 | * @handle: ACPI handle of a device the notification is for. | ||
41 | * @event: Type of the signaled event. | ||
42 | * @context: PCI device object to wake up. | ||
43 | */ | ||
44 | static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | ||
45 | { | ||
46 | struct pci_dev *pci_dev = context; | ||
47 | |||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | ||
49 | pci_check_pme_status(pci_dev); | ||
50 | pm_runtime_resume(&pci_dev->dev); | ||
51 | if (pci_dev->subordinate) | ||
52 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * add_pm_notifier - Register PM notifier for given ACPI device. | ||
58 | * @dev: ACPI device to add the notifier for. | ||
59 | * @context: PCI device or bus to check for PME status if an event is signaled. | ||
60 | * | ||
61 | * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of | ||
62 | * PM wake-up events. For example, wake-up events may be generated for bridges | ||
63 | * if one of the devices below the bridge is signaling PME, even if the bridge | ||
64 | * itself doesn't have a wake-up GPE associated with it. | ||
65 | */ | ||
66 | static acpi_status add_pm_notifier(struct acpi_device *dev, | ||
67 | acpi_notify_handler handler, | ||
68 | void *context) | ||
69 | { | ||
70 | acpi_status status = AE_ALREADY_EXISTS; | ||
71 | |||
72 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
73 | |||
74 | if (dev->wakeup.flags.notifier_present) | ||
75 | goto out; | ||
76 | |||
77 | status = acpi_install_notify_handler(dev->handle, | ||
78 | ACPI_SYSTEM_NOTIFY, | ||
79 | handler, context); | ||
80 | if (ACPI_FAILURE(status)) | ||
81 | goto out; | ||
82 | |||
83 | dev->wakeup.flags.notifier_present = true; | ||
84 | |||
85 | out: | ||
86 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
92 | * @dev: ACPI device to remove the notifier from. | ||
93 | */ | ||
94 | static acpi_status remove_pm_notifier(struct acpi_device *dev, | ||
95 | acpi_notify_handler handler) | ||
96 | { | ||
97 | acpi_status status = AE_BAD_PARAMETER; | ||
98 | |||
99 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
100 | |||
101 | if (!dev->wakeup.flags.notifier_present) | ||
102 | goto out; | ||
103 | |||
104 | status = acpi_remove_notify_handler(dev->handle, | ||
105 | ACPI_SYSTEM_NOTIFY, | ||
106 | handler); | ||
107 | if (ACPI_FAILURE(status)) | ||
108 | goto out; | ||
109 | |||
110 | dev->wakeup.flags.notifier_present = false; | ||
111 | |||
112 | out: | ||
113 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
114 | return status; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. | ||
119 | * @dev: ACPI device to add the notifier for. | ||
120 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. | ||
121 | */ | ||
122 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | ||
123 | struct pci_bus *pci_bus) | ||
124 | { | ||
125 | return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. | ||
130 | * @dev: ACPI device to remove the notifier from. | ||
131 | */ | ||
132 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | ||
133 | { | ||
134 | return remove_pm_notifier(dev, pci_acpi_wake_bus); | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * pci_acpi_add_pm_notifier - Register PM notifier for given PCI device. | ||
139 | * @dev: ACPI device to add the notifier for. | ||
140 | * @pci_dev: PCI device to check for the PME status if an event is signaled. | ||
141 | */ | ||
142 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | ||
143 | struct pci_dev *pci_dev) | ||
144 | { | ||
145 | return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. | ||
150 | * @dev: ACPI device to remove the notifier from. | ||
151 | */ | ||
152 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | ||
153 | { | ||
154 | return remove_pm_notifier(dev, pci_acpi_wake_dev); | ||
155 | } | ||
156 | |||
21 | /* | 157 | /* |
22 | * _SxD returns the D-state with the highest power | 158 | * _SxD returns the D-state with the highest power |
23 | * (lowest D-state number) supported in the S-state "x". | 159 | * (lowest D-state number) supported in the S-state "x". |
@@ -131,12 +267,87 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | return 0; | 267 | return 0; |
132 | } | 268 | } |
133 | 269 | ||
270 | /** | ||
271 | * acpi_dev_run_wake - Enable/disable wake-up for given device. | ||
272 | * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||
273 | * @enable: Whether enable or disable the wake-up functionality. | ||
274 | * | ||
275 | * Find the ACPI device object corresponding to @pci_dev and try to | ||
276 | * enable/disable the GPE associated with it. | ||
277 | */ | ||
278 | static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | ||
279 | { | ||
280 | struct acpi_device *dev; | ||
281 | acpi_handle handle; | ||
282 | int error = -ENODEV; | ||
283 | |||
284 | if (!device_run_wake(phys_dev)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | handle = DEVICE_ACPI_HANDLE(phys_dev); | ||
288 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||
289 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||
290 | __func__); | ||
291 | return -ENODEV; | ||
292 | } | ||
293 | |||
294 | if (enable) { | ||
295 | if (!dev->wakeup.run_wake_count++) { | ||
296 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
297 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
298 | dev->wakeup.gpe_number, | ||
299 | ACPI_GPE_TYPE_RUNTIME); | ||
300 | } | ||
301 | } else if (dev->wakeup.run_wake_count > 0) { | ||
302 | if (!--dev->wakeup.run_wake_count) { | ||
303 | acpi_disable_gpe(dev->wakeup.gpe_device, | ||
304 | dev->wakeup.gpe_number, | ||
305 | ACPI_GPE_TYPE_RUNTIME); | ||
306 | acpi_disable_wakeup_device_power(dev); | ||
307 | } | ||
308 | } else { | ||
309 | error = -EALREADY; | ||
310 | } | ||
311 | |||
312 | return error; | ||
313 | } | ||
314 | |||
315 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||
316 | { | ||
317 | while (bus->parent) { | ||
318 | struct pci_dev *bridge = bus->self; | ||
319 | |||
320 | if (bridge->pme_interrupt) | ||
321 | return; | ||
322 | if (!acpi_dev_run_wake(&bridge->dev, enable)) | ||
323 | return; | ||
324 | bus = bus->parent; | ||
325 | } | ||
326 | |||
327 | /* We have reached the root bus. */ | ||
328 | if (bus->bridge) | ||
329 | acpi_dev_run_wake(bus->bridge, enable); | ||
330 | } | ||
331 | |||
332 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | ||
333 | { | ||
334 | if (dev->pme_interrupt) | ||
335 | return 0; | ||
336 | |||
337 | if (!acpi_dev_run_wake(&dev->dev, enable)) | ||
338 | return 0; | ||
339 | |||
340 | acpi_pci_propagate_run_wake(dev->bus, enable); | ||
341 | return 0; | ||
342 | } | ||
343 | |||
134 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { | 344 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { |
135 | .is_manageable = acpi_pci_power_manageable, | 345 | .is_manageable = acpi_pci_power_manageable, |
136 | .set_state = acpi_pci_set_power_state, | 346 | .set_state = acpi_pci_set_power_state, |
137 | .choose_state = acpi_pci_choose_state, | 347 | .choose_state = acpi_pci_choose_state, |
138 | .can_wakeup = acpi_pci_can_wakeup, | 348 | .can_wakeup = acpi_pci_can_wakeup, |
139 | .sleep_wake = acpi_pci_sleep_wake, | 349 | .sleep_wake = acpi_pci_sleep_wake, |
350 | .run_wake = acpi_pci_run_wake, | ||
140 | }; | 351 | }; |
141 | 352 | ||
142 | /* ACPI bus type */ | 353 | /* ACPI bus type */ |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5723446544fd..df55a2f351b3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/pm_wakeup.h> | 20 | #include <linux/pm_wakeup.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/pm_runtime.h> | ||
23 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
24 | #include "pci.h" | 25 | #include "pci.h" |
25 | 26 | ||
@@ -462,6 +463,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
462 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 463 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; |
463 | } | 464 | } |
464 | 465 | ||
466 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
467 | { | ||
468 | return pci_platform_pm ? | ||
469 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
470 | } | ||
471 | |||
465 | /** | 472 | /** |
466 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of | 473 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of |
467 | * given PCI device | 474 | * given PCI device |
@@ -1230,6 +1237,31 @@ bool pci_check_pme_status(struct pci_dev *dev) | |||
1230 | } | 1237 | } |
1231 | 1238 | ||
1232 | /** | 1239 | /** |
1240 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | ||
1241 | * @dev: Device to handle. | ||
1242 | * @ign: Ignored. | ||
1243 | * | ||
1244 | * Check if @dev has generated PME and queue a resume request for it in that | ||
1245 | * case. | ||
1246 | */ | ||
1247 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | ||
1248 | { | ||
1249 | if (pci_check_pme_status(dev)) | ||
1250 | pm_request_resume(&dev->dev); | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | /** | ||
1255 | * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary. | ||
1256 | * @bus: Top bus of the subtree to walk. | ||
1257 | */ | ||
1258 | void pci_pme_wakeup_bus(struct pci_bus *bus) | ||
1259 | { | ||
1260 | if (bus) | ||
1261 | pci_walk_bus(bus, pci_pme_wakeup, NULL); | ||
1262 | } | ||
1263 | |||
1264 | /** | ||
1233 | * pci_pme_capable - check the capability of PCI device to generate PME# | 1265 | * pci_pme_capable - check the capability of PCI device to generate PME# |
1234 | * @dev: PCI device to handle. | 1266 | * @dev: PCI device to handle. |
1235 | * @state: PCI state from which device will issue PME#. | 1267 | * @state: PCI state from which device will issue PME#. |
@@ -1434,6 +1466,41 @@ int pci_back_from_sleep(struct pci_dev *dev) | |||
1434 | } | 1466 | } |
1435 | 1467 | ||
1436 | /** | 1468 | /** |
1469 | * pci_dev_run_wake - Check if device can generate run-time wake-up events. | ||
1470 | * @dev: Device to check. | ||
1471 | * | ||
1472 | * Return true if the device itself is cabable of generating wake-up events | ||
1473 | * (through the platform or using the native PCIe PME) or if the device supports | ||
1474 | * PME and one of its upstream bridges can generate wake-up events. | ||
1475 | */ | ||
1476 | bool pci_dev_run_wake(struct pci_dev *dev) | ||
1477 | { | ||
1478 | struct pci_bus *bus = dev->bus; | ||
1479 | |||
1480 | if (device_run_wake(&dev->dev)) | ||
1481 | return true; | ||
1482 | |||
1483 | if (!dev->pme_support) | ||
1484 | return false; | ||
1485 | |||
1486 | while (bus->parent) { | ||
1487 | struct pci_dev *bridge = bus->self; | ||
1488 | |||
1489 | if (device_run_wake(&bridge->dev)) | ||
1490 | return true; | ||
1491 | |||
1492 | bus = bus->parent; | ||
1493 | } | ||
1494 | |||
1495 | /* We have reached the root bus. */ | ||
1496 | if (bus->bridge) | ||
1497 | return device_run_wake(bus->bridge); | ||
1498 | |||
1499 | return false; | ||
1500 | } | ||
1501 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | ||
1502 | |||
1503 | /** | ||
1437 | * pci_pm_init - Initialize PM functions of given PCI device | 1504 | * pci_pm_init - Initialize PM functions of given PCI device |
1438 | * @dev: PCI device to handle. | 1505 | * @dev: PCI device to handle. |
1439 | */ | 1506 | */ |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index b95b0a077d31..286c50821949 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -35,6 +35,10 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
35 | * | 35 | * |
36 | * @sleep_wake: enables/disables the system wake up capability of given device | 36 | * @sleep_wake: enables/disables the system wake up capability of given device |
37 | * | 37 | * |
38 | * @run_wake: enables/disables the platform to generate run-time wake-up events | ||
39 | * for given device (the device's wake-up capability has to be | ||
40 | * enabled by @sleep_wake for this feature to work) | ||
41 | * | ||
38 | * If given platform is generally capable of power managing PCI devices, all of | 42 | * If given platform is generally capable of power managing PCI devices, all of |
39 | * these callbacks are mandatory. | 43 | * these callbacks are mandatory. |
40 | */ | 44 | */ |
@@ -44,12 +48,15 @@ struct pci_platform_pm_ops { | |||
44 | pci_power_t (*choose_state)(struct pci_dev *dev); | 48 | pci_power_t (*choose_state)(struct pci_dev *dev); |
45 | bool (*can_wakeup)(struct pci_dev *dev); | 49 | bool (*can_wakeup)(struct pci_dev *dev); |
46 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 50 | int (*sleep_wake)(struct pci_dev *dev, bool enable); |
51 | int (*run_wake)(struct pci_dev *dev, bool enable); | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 54 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
50 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | 55 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); |
51 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 56 | extern void pci_disable_enabled_device(struct pci_dev *dev); |
52 | extern bool pci_check_pme_status(struct pci_dev *dev); | 57 | extern bool pci_check_pme_status(struct pci_dev *dev); |
58 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | ||
59 | extern void pci_pme_wakeup_bus(struct pci_bus *bus); | ||
53 | extern void pci_pm_init(struct pci_dev *dev); | 60 | extern void pci_pm_init(struct pci_dev *dev); |
54 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 61 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
55 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 62 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 60fcff419352..54508ccea023 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -243,6 +243,7 @@ struct acpi_device_wakeup_flags { | |||
243 | u8 valid:1; /* Can successfully enable wakeup? */ | 243 | u8 valid:1; /* Can successfully enable wakeup? */ |
244 | u8 run_wake:1; /* Run-Wake GPE devices */ | 244 | u8 run_wake:1; /* Run-Wake GPE devices */ |
245 | u8 always_enabled:1; /* Run-wake devices that are always enabled */ | 245 | u8 always_enabled:1; /* Run-wake devices that are always enabled */ |
246 | u8 notifier_present:1; /* Wake-up notify handler has been installed */ | ||
246 | }; | 247 | }; |
247 | 248 | ||
248 | struct acpi_device_wakeup_state { | 249 | struct acpi_device_wakeup_state { |
@@ -388,6 +389,9 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); | |||
388 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); | 389 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); |
389 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) | 390 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) |
390 | 391 | ||
392 | int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); | ||
393 | int acpi_disable_wakeup_device_power(struct acpi_device *dev); | ||
394 | |||
391 | #ifdef CONFIG_PM_SLEEP | 395 | #ifdef CONFIG_PM_SLEEP |
392 | int acpi_pm_device_sleep_state(struct device *, int *); | 396 | int acpi_pm_device_sleep_state(struct device *, int *); |
393 | int acpi_pm_device_sleep_wake(struct device *, bool); | 397 | int acpi_pm_device_sleep_wake(struct device *, bool); |
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 93a7c08f869d..c8b6473c5f42 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
@@ -11,6 +11,13 @@ | |||
11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
12 | 12 | ||
13 | #ifdef CONFIG_ACPI | 13 | #ifdef CONFIG_ACPI |
14 | extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | ||
15 | struct pci_bus *pci_bus); | ||
16 | extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev); | ||
17 | extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | ||
18 | struct pci_dev *pci_dev); | ||
19 | extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev); | ||
20 | |||
14 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) | 21 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) |
15 | { | 22 | { |
16 | struct pci_bus *pbus = pdev->bus; | 23 | struct pci_bus *pbus = pdev->bus; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 9fe4b2089b78..3f787ce78bd1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -782,6 +782,7 @@ int pci_wake_from_d3(struct pci_dev *dev, bool enable); | |||
782 | pci_power_t pci_target_state(struct pci_dev *dev); | 782 | pci_power_t pci_target_state(struct pci_dev *dev); |
783 | int pci_prepare_to_sleep(struct pci_dev *dev); | 783 | int pci_prepare_to_sleep(struct pci_dev *dev); |
784 | int pci_back_from_sleep(struct pci_dev *dev); | 784 | int pci_back_from_sleep(struct pci_dev *dev); |
785 | bool pci_dev_run_wake(struct pci_dev *dev); | ||
785 | 786 | ||
786 | /* For use by arch with custom probe code */ | 787 | /* For use by arch with custom probe code */ |
787 | void set_pcie_port_type(struct pci_dev *pdev); | 788 | void set_pcie_port_type(struct pci_dev *pdev); |