aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-11-24 18:07:56 -0500
committerLen Brown <len.brown@intel.com>2011-01-12 04:48:44 -0500
commit5e6d4fe4296782f1f095575b8213a97c3e925a16 (patch)
tree3d2376b9b18536acfa20777172ab132a475bb0ae /drivers/acpi
parent30d3df41b32b1ea63d3ebc52ef5644cbe41520f4 (diff)
ACPI / PM: Introduce __acpi_bus_get_power()
It sometimes is necessary to get the power state of an ACPI device without updating its device->power.state field, for example to avoid inconsistencies between device->power.state and the reference counters of the device's power resources. For this purpose introduce __acpi_bus_get_power() that will return the given device's power state via a pointer (instead of modifying device->power.state) and make acpi_bus_get_power() use it. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/bus.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a9fe8e6bc40e..9657abc4a7fb 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -196,34 +196,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
196 Power Management 196 Power Management
197 -------------------------------------------------------------------------- */ 197 -------------------------------------------------------------------------- */
198 198
199int acpi_bus_get_power(acpi_handle handle, int *state) 199static int __acpi_bus_get_power(struct acpi_device *device, int *state)
200{ 200{
201 int result = 0; 201 int result = 0;
202 acpi_status status = 0; 202 acpi_status status = 0;
203 struct acpi_device *device = NULL;
204 unsigned long long psc = 0; 203 unsigned long long psc = 0;
205 204
206 205 if (!device || !state)
207 result = acpi_bus_get_device(handle, &device); 206 return -EINVAL;
208 if (result)
209 return result;
210 207
211 *state = ACPI_STATE_UNKNOWN; 208 *state = ACPI_STATE_UNKNOWN;
212 209
213 if (!device->flags.power_manageable) { 210 if (device->flags.power_manageable) {
214 /* TBD: Non-recursive algorithm for walking up hierarchy */
215 if (device->parent)
216 *state = device->parent->power.state;
217 else
218 *state = ACPI_STATE_D0;
219 } else {
220 /* 211 /*
221 * Get the device's power state either directly (via _PSC) or 212 * Get the device's power state either directly (via _PSC) or
222 * indirectly (via power resources). 213 * indirectly (via power resources).
223 */ 214 */
224 if (device->power.flags.power_resources) { 215 if (device->power.flags.power_resources) {
225 result = acpi_power_get_inferred_state(device, 216 result = acpi_power_get_inferred_state(device, state);
226 &device->power.state);
227 if (result) 217 if (result)
228 return result; 218 return result;
229 } else if (device->power.flags.explicit_get) { 219 } else if (device->power.flags.explicit_get) {
@@ -231,20 +221,40 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
231 NULL, &psc); 221 NULL, &psc);
232 if (ACPI_FAILURE(status)) 222 if (ACPI_FAILURE(status))
233 return -ENODEV; 223 return -ENODEV;
234 device->power.state = (int)psc; 224 *state = (int)psc;
235 } 225 }
236 226 } else {
237 *state = device->power.state; 227 /* TBD: Non-recursive algorithm for walking up hierarchy. */
228 *state = device->parent ?
229 device->parent->power.state : ACPI_STATE_D0;
238 } 230 }
239 231
240 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", 232 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
241 device->pnp.bus_id, device->power.state)); 233 device->pnp.bus_id, *state));
242 234
243 return 0; 235 return 0;
244} 236}
245 237
238
239int acpi_bus_get_power(acpi_handle handle, int *state)
240{
241 struct acpi_device *device;
242 int result;
243
244 result = acpi_bus_get_device(handle, &device);
245 if (result)
246 return result;
247
248 result = __acpi_bus_get_power(device, state);
249 if (result)
250 return result;
251
252 device->power.state = *state;
253 return 0;
254}
246EXPORT_SYMBOL(acpi_bus_get_power); 255EXPORT_SYMBOL(acpi_bus_get_power);
247 256
257
248int acpi_bus_set_power(acpi_handle handle, int state) 258int acpi_bus_set_power(acpi_handle handle, int state)
249{ 259{
250 int result = 0; 260 int result = 0;