diff options
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r-- | drivers/pci/pci-acpi.c | 76 |
1 files changed, 27 insertions, 49 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ca4927ba8433..37263b0ebfe3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -18,31 +18,31 @@ | |||
18 | #include "pci.h" | 18 | #include "pci.h" |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. | 21 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. |
22 | * @handle: ACPI handle of a device the notification is for. | 22 | * @work: Work item to handle. |
23 | * @event: Type of the signaled event. | ||
24 | * @context: PCI root bus to wake up devices on. | ||
25 | */ | 23 | */ |
26 | static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) | 24 | static void pci_acpi_wake_bus(struct work_struct *work) |
27 | { | 25 | { |
28 | struct pci_bus *pci_bus = context; | 26 | struct acpi_device *adev; |
27 | struct acpi_pci_root *root; | ||
29 | 28 | ||
30 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) | 29 | adev = container_of(work, struct acpi_device, wakeup.context.work); |
31 | pci_pme_wakeup_bus(pci_bus); | 30 | root = acpi_driver_data(adev); |
31 | pci_pme_wakeup_bus(root->bus); | ||
32 | } | 32 | } |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. | 35 | * pci_acpi_wake_dev - PCI device wakeup notification work function. |
36 | * @handle: ACPI handle of a device the notification is for. | 36 | * @handle: ACPI handle of a device the notification is for. |
37 | * @event: Type of the signaled event. | 37 | * @work: Work item to handle. |
38 | * @context: PCI device object to wake up. | ||
39 | */ | 38 | */ |
40 | static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | 39 | static void pci_acpi_wake_dev(struct work_struct *work) |
41 | { | 40 | { |
42 | struct pci_dev *pci_dev = context; | 41 | struct acpi_device_wakeup_context *context; |
42 | struct pci_dev *pci_dev; | ||
43 | 43 | ||
44 | if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) | 44 | context = container_of(work, struct acpi_device_wakeup_context, work); |
45 | return; | 45 | pci_dev = to_pci_dev(context->dev); |
46 | 46 | ||
47 | if (pci_dev->pme_poll) | 47 | if (pci_dev->pme_poll) |
48 | pci_dev->pme_poll = false; | 48 | pci_dev->pme_poll = false; |
@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. | 68 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus. |
69 | * @dev: ACPI device to add the notifier for. | 69 | * @dev: PCI root bridge ACPI device. |
70 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. | ||
71 | */ | ||
72 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | ||
73 | struct pci_bus *pci_bus) | ||
74 | { | ||
75 | return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. | ||
80 | * @dev: ACPI device to remove the notifier from. | ||
81 | */ | 70 | */ |
82 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | 71 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev) |
83 | { | 72 | { |
84 | return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); | 73 | return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus); |
85 | } | 74 | } |
86 | 75 | ||
87 | /** | 76 | /** |
@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | |||
92 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | 81 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, |
93 | struct pci_dev *pci_dev) | 82 | struct pci_dev *pci_dev) |
94 | { | 83 | { |
95 | return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); | 84 | return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev); |
96 | } | ||
97 | |||
98 | /** | ||
99 | * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. | ||
100 | * @dev: ACPI device to remove the notifier from. | ||
101 | */ | ||
102 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | ||
103 | { | ||
104 | return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev); | ||
105 | } | 85 | } |
106 | 86 | ||
107 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | 87 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) |
@@ -170,14 +150,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) | |||
170 | 150 | ||
171 | static bool acpi_pci_power_manageable(struct pci_dev *dev) | 151 | static bool acpi_pci_power_manageable(struct pci_dev *dev) |
172 | { | 152 | { |
173 | acpi_handle handle = ACPI_HANDLE(&dev->dev); | 153 | struct acpi_device *adev = ACPI_COMPANION(&dev->dev); |
174 | 154 | return adev ? acpi_device_power_manageable(adev) : false; | |
175 | return handle ? acpi_bus_power_manageable(handle) : false; | ||
176 | } | 155 | } |
177 | 156 | ||
178 | static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | 157 | static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) |
179 | { | 158 | { |
180 | acpi_handle handle = ACPI_HANDLE(&dev->dev); | 159 | struct acpi_device *adev = ACPI_COMPANION(&dev->dev); |
181 | static const u8 state_conv[] = { | 160 | static const u8 state_conv[] = { |
182 | [PCI_D0] = ACPI_STATE_D0, | 161 | [PCI_D0] = ACPI_STATE_D0, |
183 | [PCI_D1] = ACPI_STATE_D1, | 162 | [PCI_D1] = ACPI_STATE_D1, |
@@ -188,7 +167,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
188 | int error = -EINVAL; | 167 | int error = -EINVAL; |
189 | 168 | ||
190 | /* If the ACPI device has _EJ0, ignore the device */ | 169 | /* If the ACPI device has _EJ0, ignore the device */ |
191 | if (!handle || acpi_has_method(handle, "_EJ0")) | 170 | if (!adev || acpi_has_method(adev->handle, "_EJ0")) |
192 | return -ENODEV; | 171 | return -ENODEV; |
193 | 172 | ||
194 | switch (state) { | 173 | switch (state) { |
@@ -202,7 +181,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
202 | case PCI_D1: | 181 | case PCI_D1: |
203 | case PCI_D2: | 182 | case PCI_D2: |
204 | case PCI_D3hot: | 183 | case PCI_D3hot: |
205 | error = acpi_bus_set_power(handle, state_conv[state]); | 184 | error = acpi_device_set_power(adev, state_conv[state]); |
206 | } | 185 | } |
207 | 186 | ||
208 | if (!error) | 187 | if (!error) |
@@ -214,9 +193,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
214 | 193 | ||
215 | static bool acpi_pci_can_wakeup(struct pci_dev *dev) | 194 | static bool acpi_pci_can_wakeup(struct pci_dev *dev) |
216 | { | 195 | { |
217 | acpi_handle handle = ACPI_HANDLE(&dev->dev); | 196 | struct acpi_device *adev = ACPI_COMPANION(&dev->dev); |
218 | 197 | return adev ? acpi_device_can_wakeup(adev) : false; | |
219 | return handle ? acpi_bus_can_wakeup(handle) : false; | ||
220 | } | 198 | } |
221 | 199 | ||
222 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | 200 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) |