diff options
Diffstat (limited to 'drivers/pnp/pnpacpi')
-rw-r--r-- | drivers/pnp/pnpacpi/Makefile | 3 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 93 |
2 files changed, 69 insertions, 27 deletions
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile index 905326fcca85..40c93da18252 100644 --- a/drivers/pnp/pnpacpi/Makefile +++ b/drivers/pnp/pnpacpi/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the kernel PNPACPI driver. | 2 | # Makefile for the kernel PNPACPI driver. |
3 | # | 3 | # |
4 | obj-y += pnp.o | ||
4 | 5 | ||
5 | obj-y := core.o rsparser.o | 6 | pnp-y := core.o rsparser.o |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 57313f4658bc..ca84d5099ce7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -81,12 +81,19 @@ static int pnpacpi_get_resources(struct pnp_dev *dev) | |||
81 | 81 | ||
82 | static int pnpacpi_set_resources(struct pnp_dev *dev) | 82 | static int pnpacpi_set_resources(struct pnp_dev *dev) |
83 | { | 83 | { |
84 | struct acpi_device *acpi_dev = dev->data; | 84 | struct acpi_device *acpi_dev; |
85 | acpi_handle handle = acpi_dev->handle; | 85 | acpi_handle handle; |
86 | struct acpi_buffer buffer; | 86 | struct acpi_buffer buffer; |
87 | int ret; | 87 | int ret; |
88 | 88 | ||
89 | pnp_dbg(&dev->dev, "set resources\n"); | 89 | pnp_dbg(&dev->dev, "set resources\n"); |
90 | |||
91 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
92 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
93 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | |||
90 | ret = pnpacpi_build_resource_template(dev, &buffer); | 97 | ret = pnpacpi_build_resource_template(dev, &buffer); |
91 | if (ret) | 98 | if (ret) |
92 | return ret; | 99 | return ret; |
@@ -105,12 +112,18 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) | |||
105 | 112 | ||
106 | static int pnpacpi_disable_resources(struct pnp_dev *dev) | 113 | static int pnpacpi_disable_resources(struct pnp_dev *dev) |
107 | { | 114 | { |
108 | struct acpi_device *acpi_dev = dev->data; | 115 | struct acpi_device *acpi_dev; |
109 | acpi_handle handle = acpi_dev->handle; | 116 | acpi_handle handle; |
110 | int ret; | 117 | int ret; |
111 | 118 | ||
112 | dev_dbg(&dev->dev, "disable resources\n"); | 119 | dev_dbg(&dev->dev, "disable resources\n"); |
113 | 120 | ||
121 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
122 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
123 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
114 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 127 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
115 | ret = 0; | 128 | ret = 0; |
116 | if (acpi_bus_power_manageable(handle)) | 129 | if (acpi_bus_power_manageable(handle)) |
@@ -124,46 +137,74 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) | |||
124 | #ifdef CONFIG_ACPI_SLEEP | 137 | #ifdef CONFIG_ACPI_SLEEP |
125 | static bool pnpacpi_can_wakeup(struct pnp_dev *dev) | 138 | static bool pnpacpi_can_wakeup(struct pnp_dev *dev) |
126 | { | 139 | { |
127 | struct acpi_device *acpi_dev = dev->data; | 140 | struct acpi_device *acpi_dev; |
128 | acpi_handle handle = acpi_dev->handle; | 141 | acpi_handle handle; |
142 | |||
143 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
144 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
145 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
146 | return false; | ||
147 | } | ||
129 | 148 | ||
130 | return acpi_bus_can_wakeup(handle); | 149 | return acpi_bus_can_wakeup(handle); |
131 | } | 150 | } |
132 | 151 | ||
133 | static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) | 152 | static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) |
134 | { | 153 | { |
135 | struct acpi_device *acpi_dev = dev->data; | 154 | struct acpi_device *acpi_dev; |
136 | acpi_handle handle = acpi_dev->handle; | 155 | acpi_handle handle; |
137 | int power_state; | 156 | int error = 0; |
157 | |||
158 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
159 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
160 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
161 | return 0; | ||
162 | } | ||
138 | 163 | ||
139 | if (device_can_wakeup(&dev->dev)) { | 164 | if (device_can_wakeup(&dev->dev)) { |
140 | int rc = acpi_pm_device_sleep_wake(&dev->dev, | 165 | error = acpi_pm_device_sleep_wake(&dev->dev, |
141 | device_may_wakeup(&dev->dev)); | 166 | device_may_wakeup(&dev->dev)); |
167 | if (error) | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | if (acpi_bus_power_manageable(handle)) { | ||
172 | int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); | ||
173 | |||
174 | if (power_state < 0) | ||
175 | power_state = (state.event == PM_EVENT_ON) ? | ||
176 | ACPI_STATE_D0 : ACPI_STATE_D3; | ||
142 | 177 | ||
143 | if (rc) | 178 | /* |
144 | return rc; | 179 | * acpi_bus_set_power() often fails (keyboard port can't be |
180 | * powered-down?), and in any case, our return value is ignored | ||
181 | * by pnp_bus_suspend(). Hence we don't revert the wakeup | ||
182 | * setting if the set_power fails. | ||
183 | */ | ||
184 | error = acpi_bus_set_power(handle, power_state); | ||
145 | } | 185 | } |
146 | power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); | 186 | |
147 | if (power_state < 0) | 187 | return error; |
148 | power_state = (state.event == PM_EVENT_ON) ? | ||
149 | ACPI_STATE_D0 : ACPI_STATE_D3; | ||
150 | |||
151 | /* acpi_bus_set_power() often fails (keyboard port can't be | ||
152 | * powered-down?), and in any case, our return value is ignored | ||
153 | * by pnp_bus_suspend(). Hence we don't revert the wakeup | ||
154 | * setting if the set_power fails. | ||
155 | */ | ||
156 | return acpi_bus_set_power(handle, power_state); | ||
157 | } | 188 | } |
158 | 189 | ||
159 | static int pnpacpi_resume(struct pnp_dev *dev) | 190 | static int pnpacpi_resume(struct pnp_dev *dev) |
160 | { | 191 | { |
161 | struct acpi_device *acpi_dev = dev->data; | 192 | struct acpi_device *acpi_dev; |
162 | acpi_handle handle = acpi_dev->handle; | 193 | acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); |
194 | int error = 0; | ||
195 | |||
196 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
197 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
198 | return -ENODEV; | ||
199 | } | ||
163 | 200 | ||
164 | if (device_may_wakeup(&dev->dev)) | 201 | if (device_may_wakeup(&dev->dev)) |
165 | acpi_pm_device_sleep_wake(&dev->dev, false); | 202 | acpi_pm_device_sleep_wake(&dev->dev, false); |
166 | return acpi_bus_set_power(handle, ACPI_STATE_D0); | 203 | |
204 | if (acpi_bus_power_manageable(handle)) | ||
205 | error = acpi_bus_set_power(handle, ACPI_STATE_D0); | ||
206 | |||
207 | return error; | ||
167 | } | 208 | } |
168 | #endif | 209 | #endif |
169 | 210 | ||