Blame view
drivers/acpi/scan.c
38.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 |
/* * scan.c - support for transforming the ACPI namespace into individual objects */ #include <linux/module.h> #include <linux/init.h> |
5a0e3ad6a include cleanup: ... |
7 |
#include <linux/slab.h> |
9b6d97b64 ACPI: scan: handl... |
8 |
#include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <linux/acpi.h> |
74523c901 ACPI: fix checkpa... |
10 11 |
#include <linux/signal.h> #include <linux/kthread.h> |
222e82ac9 acpi: Support IBM... |
12 |
#include <linux/dmi.h> |
1da177e4c Linux-2.6.12-rc2 |
13 14 |
#include <acpi/acpi_drivers.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
|
e60cc7a6f ACPI: move privat... |
16 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
17 |
#define _COMPONENT ACPI_BUS_COMPONENT |
f52fd66d2 ACPI: clean up AC... |
18 |
ACPI_MODULE_NAME("scan"); |
1da177e4c Linux-2.6.12-rc2 |
19 |
#define STRUCT_TO_INT(s) (*((int*)&s)) |
4be44fcd3 [ACPI] Lindent al... |
20 |
extern struct acpi_device *acpi_root; |
1da177e4c Linux-2.6.12-rc2 |
21 22 |
#define ACPI_BUS_CLASS "system_bus" |
29b71a1ca ACPI: autoload mo... |
23 |
#define ACPI_BUS_HID "LNXSYBUS" |
1da177e4c Linux-2.6.12-rc2 |
24 |
#define ACPI_BUS_DEVICE_NAME "System Bus" |
859ac9a4b ACPI: identify de... |
25 |
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
1da177e4c Linux-2.6.12-rc2 |
26 |
static LIST_HEAD(acpi_device_list); |
e49bd2dd5 ACPI: use PNPID:i... |
27 |
static LIST_HEAD(acpi_bus_id_list); |
9090589d8 ACPI: convert acp... |
28 |
DEFINE_MUTEX(acpi_device_lock); |
1da177e4c Linux-2.6.12-rc2 |
29 |
LIST_HEAD(acpi_wakeup_device_list); |
e49bd2dd5 ACPI: use PNPID:i... |
30 |
struct acpi_device_bus_id{ |
bb0958544 ACPI: use more un... |
31 |
char bus_id[15]; |
e49bd2dd5 ACPI: use PNPID:i... |
32 33 |
unsigned int instance_no; struct list_head node; |
1da177e4c Linux-2.6.12-rc2 |
34 |
}; |
29b71a1ca ACPI: autoload mo... |
35 36 37 38 39 40 |
/* * Creates hid/cid(s) string needed for modalias and uevent * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: * char *modalias: "acpi:IBM0001:ACPI0001" */ |
b3e572d2e make drivers/acpi... |
41 42 43 |
static int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size) { |
29b71a1ca ACPI: autoload mo... |
44 |
int len; |
5c9fcb5de ACPI: fix a regre... |
45 |
int count; |
7f47fa6c2 ACPI: maintain a ... |
46 |
struct acpi_hardware_id *id; |
29b71a1ca ACPI: autoload mo... |
47 |
|
5c9fcb5de ACPI: fix a regre... |
48 |
len = snprintf(modalias, size, "acpi:"); |
29b71a1ca ACPI: autoload mo... |
49 |
size -= len; |
7f47fa6c2 ACPI: maintain a ... |
50 51 |
list_for_each_entry(id, &acpi_dev->pnp.ids, list) { count = snprintf(&modalias[len], size, "%s:", id->id); |
5c9fcb5de ACPI: fix a regre... |
52 53 54 55 56 |
if (count < 0 || count >= size) return -EINVAL; len += count; size -= count; } |
29b71a1ca ACPI: autoload mo... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
modalias[len] = '\0'; return len; } static ssize_t acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); int len; /* Device has no HID and no CID or string is >1024 */ len = create_modalias(acpi_dev, buf, 1024); if (len <= 0) return 0; buf[len++] = ' '; return len; } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
c8d72a5e7 ACPI: run ACPI de... |
75 |
static void acpi_bus_hot_remove_device(void *context) |
1da177e4c Linux-2.6.12-rc2 |
76 |
{ |
26d46867b fix a deadlock is... |
77 78 |
struct acpi_device *device; acpi_handle handle = context; |
1da177e4c Linux-2.6.12-rc2 |
79 80 81 |
struct acpi_object_list arg_list; union acpi_object arg; acpi_status status = AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
82 |
|
26d46867b fix a deadlock is... |
83 |
if (acpi_bus_get_device(handle, &device)) |
c8d72a5e7 ACPI: run ACPI de... |
84 |
return; |
26d46867b fix a deadlock is... |
85 86 |
if (!device) |
c8d72a5e7 ACPI: run ACPI de... |
87 |
return; |
26d46867b fix a deadlock is... |
88 89 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
0794469da ACPI: struct devi... |
90 91 |
"Hot-removing device %s... ", dev_name(&device->dev))); |
26d46867b fix a deadlock is... |
92 93 |
if (acpi_bus_trim(device, 1)) { |
55ac9a018 ACPI: replace ACP... |
94 95 96 |
printk(KERN_ERR PREFIX "Removing device failed "); |
c8d72a5e7 ACPI: run ACPI de... |
97 |
return; |
26d46867b fix a deadlock is... |
98 |
} |
1da177e4c Linux-2.6.12-rc2 |
99 |
|
26d46867b fix a deadlock is... |
100 101 102 |
/* power off device */ status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
55ac9a018 ACPI: replace ACP... |
103 104 105 |
printk(KERN_WARNING PREFIX "Power-off device failed "); |
26d46867b fix a deadlock is... |
106 107 |
if (device->flags.lockable) { |
1da177e4c Linux-2.6.12-rc2 |
108 109 110 111 112 113 |
arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; arg.integer.value = 0; acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); } |
1da177e4c Linux-2.6.12-rc2 |
114 |
|
1da177e4c Linux-2.6.12-rc2 |
115 116 117 118 |
arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; arg.integer.value = 1; |
1da177e4c Linux-2.6.12-rc2 |
119 |
|
1da177e4c Linux-2.6.12-rc2 |
120 121 122 |
/* * TBD: _EJD support. */ |
1da177e4c Linux-2.6.12-rc2 |
123 |
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); |
26d46867b fix a deadlock is... |
124 |
if (ACPI_FAILURE(status)) |
c8d72a5e7 ACPI: run ACPI de... |
125 126 127 |
printk(KERN_WARNING PREFIX "Eject device failed "); |
1da177e4c Linux-2.6.12-rc2 |
128 |
|
c8d72a5e7 ACPI: run ACPI de... |
129 |
return; |
1da177e4c Linux-2.6.12-rc2 |
130 |
} |
1da177e4c Linux-2.6.12-rc2 |
131 |
static ssize_t |
f883d9db0 ACPI: convert to ... |
132 133 |
acpi_eject_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
4be44fcd3 [ACPI] Lindent al... |
135 |
int ret = count; |
4be44fcd3 [ACPI] Lindent al... |
136 |
acpi_status status; |
4be44fcd3 [ACPI] Lindent al... |
137 |
acpi_object_type type = 0; |
f883d9db0 ACPI: convert to ... |
138 |
struct acpi_device *acpi_device = to_acpi_device(d); |
1da177e4c Linux-2.6.12-rc2 |
139 |
|
1da177e4c Linux-2.6.12-rc2 |
140 141 142 |
if ((!count) || (buf[0] != '1')) { return -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
143 |
#ifndef FORCE_EJECT |
f883d9db0 ACPI: convert to ... |
144 |
if (acpi_device->driver == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 148 |
ret = -ENODEV; goto err; } #endif |
f883d9db0 ACPI: convert to ... |
149 150 |
status = acpi_get_type(acpi_device->handle, &type); if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { |
1da177e4c Linux-2.6.12-rc2 |
151 152 153 |
ret = -ENODEV; goto err; } |
1da177e4c Linux-2.6.12-rc2 |
154 |
|
c8d72a5e7 ACPI: run ACPI de... |
155 |
acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle); |
74523c901 ACPI: fix checkpa... |
156 |
err: |
1da177e4c Linux-2.6.12-rc2 |
157 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
158 |
} |
f883d9db0 ACPI: convert to ... |
159 |
static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); |
1da177e4c Linux-2.6.12-rc2 |
160 |
|
e49bd2dd5 ACPI: use PNPID:i... |
161 162 163 |
static ssize_t acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); |
1da177e4c Linux-2.6.12-rc2 |
164 |
|
ea8d82fd3 ACPI: use acpi_de... |
165 166 |
return sprintf(buf, "%s ", acpi_device_hid(acpi_dev)); |
1da177e4c Linux-2.6.12-rc2 |
167 |
} |
e49bd2dd5 ACPI: use PNPID:i... |
168 |
static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); |
1da177e4c Linux-2.6.12-rc2 |
169 |
|
e49bd2dd5 ACPI: use PNPID:i... |
170 171 172 173 174 |
static ssize_t acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; int result; |
1da177e4c Linux-2.6.12-rc2 |
175 |
|
e49bd2dd5 ACPI: use PNPID:i... |
176 |
result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); |
0c526d96a ACPI: clean up wh... |
177 |
if (result) |
e49bd2dd5 ACPI: use PNPID:i... |
178 |
goto end; |
1da177e4c Linux-2.6.12-rc2 |
179 |
|
e49bd2dd5 ACPI: use PNPID:i... |
180 181 182 |
result = sprintf(buf, "%s ", (char*)path.pointer); kfree(path.pointer); |
0c526d96a ACPI: clean up wh... |
183 |
end: |
e49bd2dd5 ACPI: use PNPID:i... |
184 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
185 |
} |
e49bd2dd5 ACPI: use PNPID:i... |
186 |
static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
1da177e4c Linux-2.6.12-rc2 |
187 |
|
e49bd2dd5 ACPI: use PNPID:i... |
188 |
static int acpi_device_setup_files(struct acpi_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
189 |
{ |
f883d9db0 ACPI: convert to ... |
190 191 |
acpi_status status; acpi_handle temp; |
e49bd2dd5 ACPI: use PNPID:i... |
192 |
int result = 0; |
1da177e4c Linux-2.6.12-rc2 |
193 194 |
/* |
e49bd2dd5 ACPI: use PNPID:i... |
195 |
* Devices gotten from FADT don't have a "path" attribute |
1da177e4c Linux-2.6.12-rc2 |
196 |
*/ |
0c526d96a ACPI: clean up wh... |
197 |
if (dev->handle) { |
e49bd2dd5 ACPI: use PNPID:i... |
198 |
result = device_create_file(&dev->dev, &dev_attr_path); |
0c526d96a ACPI: clean up wh... |
199 |
if (result) |
e49bd2dd5 ACPI: use PNPID:i... |
200 |
goto end; |
1da177e4c Linux-2.6.12-rc2 |
201 |
} |
1131b938f ACPI: remove acpi... |
202 203 204 |
result = device_create_file(&dev->dev, &dev_attr_hid); if (result) goto end; |
1da177e4c Linux-2.6.12-rc2 |
205 |
|
1131b938f ACPI: remove acpi... |
206 207 208 |
result = device_create_file(&dev->dev, &dev_attr_modalias); if (result) goto end; |
29b71a1ca ACPI: autoload mo... |
209 |
|
e49bd2dd5 ACPI: use PNPID:i... |
210 211 212 213 |
/* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland. */ |
f883d9db0 ACPI: convert to ... |
214 215 |
status = acpi_get_handle(dev->handle, "_EJ0", &temp); if (ACPI_SUCCESS(status)) |
e49bd2dd5 ACPI: use PNPID:i... |
216 |
result = device_create_file(&dev->dev, &dev_attr_eject); |
0c526d96a ACPI: clean up wh... |
217 |
end: |
e49bd2dd5 ACPI: use PNPID:i... |
218 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
219 |
} |
f883d9db0 ACPI: convert to ... |
220 |
static void acpi_device_remove_files(struct acpi_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
221 |
{ |
f883d9db0 ACPI: convert to ... |
222 223 |
acpi_status status; acpi_handle temp; |
1da177e4c Linux-2.6.12-rc2 |
224 |
|
f883d9db0 ACPI: convert to ... |
225 226 227 228 229 230 231 |
/* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland. */ status = acpi_get_handle(dev->handle, "_EJ0", &temp); if (ACPI_SUCCESS(status)) device_remove_file(&dev->dev, &dev_attr_eject); |
1da177e4c Linux-2.6.12-rc2 |
232 |
|
1131b938f ACPI: remove acpi... |
233 234 |
device_remove_file(&dev->dev, &dev_attr_modalias); device_remove_file(&dev->dev, &dev_attr_hid); |
0c526d96a ACPI: clean up wh... |
235 |
if (dev->handle) |
e49bd2dd5 ACPI: use PNPID:i... |
236 |
device_remove_file(&dev->dev, &dev_attr_path); |
1da177e4c Linux-2.6.12-rc2 |
237 |
} |
1da177e4c Linux-2.6.12-rc2 |
238 |
/* -------------------------------------------------------------------------- |
9e89dde2b ACPI: clean up sc... |
239 |
ACPI Bus operations |
1da177e4c Linux-2.6.12-rc2 |
240 |
-------------------------------------------------------------------------- */ |
29b71a1ca ACPI: autoload mo... |
241 242 243 244 245 |
int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids) { const struct acpi_device_id *id; |
7f47fa6c2 ACPI: maintain a ... |
246 |
struct acpi_hardware_id *hwid; |
29b71a1ca ACPI: autoload mo... |
247 |
|
39a0ad871 ACPI : Load devic... |
248 249 250 251 252 253 |
/* * If the device is not present, it is unnecessary to load device * driver for it. */ if (!device->status.present) return -ENODEV; |
7f47fa6c2 ACPI: maintain a ... |
254 255 256 |
for (id = ids; id->id[0]; id++) list_for_each_entry(hwid, &device->pnp.ids, list) if (!strcmp((char *) id->id, hwid->id)) |
29b71a1ca ACPI: autoload mo... |
257 |
return 0; |
29b71a1ca ACPI: autoload mo... |
258 259 260 261 |
return -ENOENT; } EXPORT_SYMBOL(acpi_match_device_ids); |
7f47fa6c2 ACPI: maintain a ... |
262 263 264 265 266 267 268 269 270 |
static void acpi_free_ids(struct acpi_device *device) { struct acpi_hardware_id *id, *tmp; list_for_each_entry_safe(id, tmp, &device->pnp.ids, list) { kfree(id->id); kfree(id); } } |
1890a97ab ACPI: change regi... |
271 |
static void acpi_device_release(struct device *dev) |
1da177e4c Linux-2.6.12-rc2 |
272 |
{ |
1890a97ab ACPI: change regi... |
273 |
struct acpi_device *acpi_dev = to_acpi_device(dev); |
1da177e4c Linux-2.6.12-rc2 |
274 |
|
7f47fa6c2 ACPI: maintain a ... |
275 |
acpi_free_ids(acpi_dev); |
1890a97ab ACPI: change regi... |
276 |
kfree(acpi_dev); |
1da177e4c Linux-2.6.12-rc2 |
277 |
} |
5d9464a46 ACPI: add ACPI bu... |
278 |
static int acpi_device_suspend(struct device *dev, pm_message_t state) |
1da177e4c Linux-2.6.12-rc2 |
279 |
{ |
5d9464a46 ACPI: add ACPI bu... |
280 281 |
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; |
1da177e4c Linux-2.6.12-rc2 |
282 |
|
5d9464a46 ACPI: add ACPI bu... |
283 284 |
if (acpi_drv && acpi_drv->ops.suspend) return acpi_drv->ops.suspend(acpi_dev, state); |
1da177e4c Linux-2.6.12-rc2 |
285 286 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
287 |
|
5d9464a46 ACPI: add ACPI bu... |
288 |
static int acpi_device_resume(struct device *dev) |
9e89dde2b ACPI: clean up sc... |
289 |
{ |
5d9464a46 ACPI: add ACPI bu... |
290 291 |
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; |
1da177e4c Linux-2.6.12-rc2 |
292 |
|
5d9464a46 ACPI: add ACPI bu... |
293 294 |
if (acpi_drv && acpi_drv->ops.resume) return acpi_drv->ops.resume(acpi_dev); |
d550d98d3 ACPI: delete trac... |
295 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
296 |
} |
5d9464a46 ACPI: add ACPI bu... |
297 |
static int acpi_bus_match(struct device *dev, struct device_driver *drv) |
9e89dde2b ACPI: clean up sc... |
298 |
{ |
5d9464a46 ACPI: add ACPI bu... |
299 300 |
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = to_acpi_driver(drv); |
1da177e4c Linux-2.6.12-rc2 |
301 |
|
29b71a1ca ACPI: autoload mo... |
302 |
return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); |
5d9464a46 ACPI: add ACPI bu... |
303 |
} |
1da177e4c Linux-2.6.12-rc2 |
304 |
|
7eff2e7a8 Driver core: chan... |
305 |
static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
1da177e4c Linux-2.6.12-rc2 |
306 |
{ |
5d9464a46 ACPI: add ACPI bu... |
307 |
struct acpi_device *acpi_dev = to_acpi_device(dev); |
7eff2e7a8 Driver core: chan... |
308 |
int len; |
5d9464a46 ACPI: add ACPI bu... |
309 |
|
7eff2e7a8 Driver core: chan... |
310 311 312 313 314 315 316 |
if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen); if (len >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; env->buflen += len; |
9e89dde2b ACPI: clean up sc... |
317 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
318 |
} |
46ec8598f ACPI: support acp... |
319 320 321 322 323 324 325 326 327 328 |
static void acpi_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_device *device = data; device->driver->ops.notify(device, event); } static acpi_status acpi_device_notify_fixed(void *data) { struct acpi_device *device = data; |
53de5356b ACPI: don't pass ... |
329 330 |
/* Fixed hardware devices have no handles */ acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); |
46ec8598f ACPI: support acp... |
331 332 333 334 335 336 |
return AE_OK; } static int acpi_device_install_notify_handler(struct acpi_device *device) { acpi_status status; |
46ec8598f ACPI: support acp... |
337 |
|
ccba2a36d ACPI: use device_... |
338 |
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
46ec8598f ACPI: support acp... |
339 340 341 342 |
status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_device_notify_fixed, device); |
ccba2a36d ACPI: use device_... |
343 |
else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
46ec8598f ACPI: support acp... |
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, acpi_device_notify_fixed, device); else status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_device_notify, device); if (ACPI_FAILURE(status)) return -EINVAL; return 0; } static void acpi_device_remove_notify_handler(struct acpi_device *device) { |
ccba2a36d ACPI: use device_... |
361 |
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
46ec8598f ACPI: support acp... |
362 363 |
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_device_notify_fixed); |
ccba2a36d ACPI: use device_... |
364 |
else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
46ec8598f ACPI: support acp... |
365 366 367 368 369 370 |
acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, acpi_device_notify_fixed); else acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_device_notify); } |
5d9464a46 ACPI: add ACPI bu... |
371 372 373 |
static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); static int acpi_start_single_object(struct acpi_device *); static int acpi_device_probe(struct device * dev) |
1da177e4c Linux-2.6.12-rc2 |
374 |
{ |
5d9464a46 ACPI: add ACPI bu... |
375 376 377 378 379 380 |
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); int ret; ret = acpi_bus_driver_init(acpi_dev, acpi_drv); if (!ret) { |
c4168bff3 ACPI: add acpi_bu... |
381 382 |
if (acpi_dev->bus_ops.acpi_op_start) acpi_start_single_object(acpi_dev); |
46ec8598f ACPI: support acp... |
383 384 385 386 |
if (acpi_drv->ops.notify) { ret = acpi_device_install_notify_handler(acpi_dev); if (ret) { |
46ec8598f ACPI: support acp... |
387 388 389 390 391 392 |
if (acpi_drv->ops.remove) acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); return ret; } } |
5d9464a46 ACPI: add ACPI bu... |
393 394 395 396 397 398 399 400 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s] ", acpi_drv->name, acpi_dev->pnp.bus_id)); get_device(dev); } return ret; } |
1da177e4c Linux-2.6.12-rc2 |
401 |
|
5d9464a46 ACPI: add ACPI bu... |
402 403 404 405 406 407 |
static int acpi_device_remove(struct device * dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; if (acpi_drv) { |
46ec8598f ACPI: support acp... |
408 409 |
if (acpi_drv->ops.notify) acpi_device_remove_notify_handler(acpi_dev); |
5d9464a46 ACPI: add ACPI bu... |
410 |
if (acpi_drv->ops.remove) |
96333578b ACPI: add acpi_bu... |
411 |
acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
1da177e4c Linux-2.6.12-rc2 |
412 |
} |
5d9464a46 ACPI: add ACPI bu... |
413 |
acpi_dev->driver = NULL; |
db89b4f0d ACPI: catch calls... |
414 |
acpi_dev->driver_data = NULL; |
1da177e4c Linux-2.6.12-rc2 |
415 |
|
5d9464a46 ACPI: add ACPI bu... |
416 |
put_device(dev); |
9e89dde2b ACPI: clean up sc... |
417 418 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
419 |
|
55955aad7 PNPACPI sets pnpd... |
420 |
struct bus_type acpi_bus_type = { |
9e89dde2b ACPI: clean up sc... |
421 422 423 |
.name = "acpi", .suspend = acpi_device_suspend, .resume = acpi_device_resume, |
5d9464a46 ACPI: add ACPI bu... |
424 425 426 427 |
.match = acpi_bus_match, .probe = acpi_device_probe, .remove = acpi_device_remove, .uevent = acpi_device_uevent, |
9e89dde2b ACPI: clean up sc... |
428 |
}; |
66b7ed40a ACPI: remove redu... |
429 |
static int acpi_device_register(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
430 |
{ |
4be44fcd3 [ACPI] Lindent al... |
431 |
int result; |
e49bd2dd5 ACPI: use PNPID:i... |
432 433 |
struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; int found = 0; |
66b7ed40a ACPI: remove redu... |
434 |
|
9e89dde2b ACPI: clean up sc... |
435 436 437 438 439 440 441 |
/* * Linkage * ------- * Link this device to its parent and siblings. */ INIT_LIST_HEAD(&device->children); INIT_LIST_HEAD(&device->node); |
9e89dde2b ACPI: clean up sc... |
442 |
INIT_LIST_HEAD(&device->wakeup_list); |
1da177e4c Linux-2.6.12-rc2 |
443 |
|
e49bd2dd5 ACPI: use PNPID:i... |
444 445 446 447 448 |
new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); if (!new_bus_id) { printk(KERN_ERR PREFIX "Memory allocation error "); return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
449 |
} |
e49bd2dd5 ACPI: use PNPID:i... |
450 |
|
9090589d8 ACPI: convert acp... |
451 |
mutex_lock(&acpi_device_lock); |
e49bd2dd5 ACPI: use PNPID:i... |
452 453 454 455 456 |
/* * Find suitable bus_id and instance number in acpi_bus_id_list * If failed, create one and link it into acpi_bus_id_list */ list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { |
1131b938f ACPI: remove acpi... |
457 458 459 |
if (!strcmp(acpi_device_bus_id->bus_id, acpi_device_hid(device))) { acpi_device_bus_id->instance_no++; |
e49bd2dd5 ACPI: use PNPID:i... |
460 461 462 463 |
found = 1; kfree(new_bus_id); break; } |
1da177e4c Linux-2.6.12-rc2 |
464 |
} |
0c526d96a ACPI: clean up wh... |
465 |
if (!found) { |
e49bd2dd5 ACPI: use PNPID:i... |
466 |
acpi_device_bus_id = new_bus_id; |
1131b938f ACPI: remove acpi... |
467 |
strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); |
e49bd2dd5 ACPI: use PNPID:i... |
468 469 |
acpi_device_bus_id->instance_no = 0; list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
1da177e4c Linux-2.6.12-rc2 |
470 |
} |
0794469da ACPI: struct devi... |
471 |
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
1da177e4c Linux-2.6.12-rc2 |
472 |
|
33b571501 ACPI: delete acpi... |
473 |
if (device->parent) |
9e89dde2b ACPI: clean up sc... |
474 |
list_add_tail(&device->node, &device->parent->children); |
33b571501 ACPI: delete acpi... |
475 |
|
9e89dde2b ACPI: clean up sc... |
476 477 |
if (device->wakeup.flags.valid) list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); |
9090589d8 ACPI: convert acp... |
478 |
mutex_unlock(&acpi_device_lock); |
1da177e4c Linux-2.6.12-rc2 |
479 |
|
1890a97ab ACPI: change regi... |
480 |
if (device->parent) |
66b7ed40a ACPI: remove redu... |
481 |
device->dev.parent = &device->parent->dev; |
1890a97ab ACPI: change regi... |
482 |
device->dev.bus = &acpi_bus_type; |
1890a97ab ACPI: change regi... |
483 |
device->dev.release = &acpi_device_release; |
8b12b922e ACPI: acpi_device... |
484 |
result = device_register(&device->dev); |
0c526d96a ACPI: clean up wh... |
485 |
if (result) { |
8b12b922e ACPI: acpi_device... |
486 487 |
dev_err(&device->dev, "Error registering device "); |
e49bd2dd5 ACPI: use PNPID:i... |
488 |
goto end; |
1da177e4c Linux-2.6.12-rc2 |
489 |
} |
1da177e4c Linux-2.6.12-rc2 |
490 |
|
e49bd2dd5 ACPI: use PNPID:i... |
491 |
result = acpi_device_setup_files(device); |
0c526d96a ACPI: clean up wh... |
492 |
if (result) |
0794469da ACPI: struct devi... |
493 494 495 |
printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s ", dev_name(&device->dev)); |
1da177e4c Linux-2.6.12-rc2 |
496 |
|
96333578b ACPI: add acpi_bu... |
497 |
device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
1da177e4c Linux-2.6.12-rc2 |
498 |
return 0; |
0c526d96a ACPI: clean up wh... |
499 |
end: |
9090589d8 ACPI: convert acp... |
500 |
mutex_lock(&acpi_device_lock); |
33b571501 ACPI: delete acpi... |
501 |
if (device->parent) |
e49bd2dd5 ACPI: use PNPID:i... |
502 |
list_del(&device->node); |
e49bd2dd5 ACPI: use PNPID:i... |
503 |
list_del(&device->wakeup_list); |
9090589d8 ACPI: convert acp... |
504 |
mutex_unlock(&acpi_device_lock); |
e49bd2dd5 ACPI: use PNPID:i... |
505 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
506 |
} |
9e89dde2b ACPI: clean up sc... |
507 508 |
static void acpi_device_unregister(struct acpi_device *device, int type) { |
9090589d8 ACPI: convert acp... |
509 |
mutex_lock(&acpi_device_lock); |
33b571501 ACPI: delete acpi... |
510 |
if (device->parent) |
9e89dde2b ACPI: clean up sc... |
511 |
list_del(&device->node); |
1da177e4c Linux-2.6.12-rc2 |
512 |
|
9e89dde2b ACPI: clean up sc... |
513 |
list_del(&device->wakeup_list); |
9090589d8 ACPI: convert acp... |
514 |
mutex_unlock(&acpi_device_lock); |
1da177e4c Linux-2.6.12-rc2 |
515 |
|
9e89dde2b ACPI: clean up sc... |
516 |
acpi_detach_data(device->handle, acpi_bus_data_handler); |
1890a97ab ACPI: change regi... |
517 |
|
f883d9db0 ACPI: convert to ... |
518 |
acpi_device_remove_files(device); |
1890a97ab ACPI: change regi... |
519 |
device_unregister(&device->dev); |
1da177e4c Linux-2.6.12-rc2 |
520 |
} |
9e89dde2b ACPI: clean up sc... |
521 522 523 |
/* -------------------------------------------------------------------------- Driver Management -------------------------------------------------------------------------- */ |
1da177e4c Linux-2.6.12-rc2 |
524 |
/** |
d758a8fa8 [ACPI] fix kernel... |
525 526 527 528 |
* acpi_bus_driver_init - add a device to a driver * @device: the device to add and initialize * @driver: driver for the device * |
0c526d96a ACPI: clean up wh... |
529 |
* Used to initialize a device via its device driver. Called whenever a |
1890a97ab ACPI: change regi... |
530 |
* driver is bound to a device. Invokes the driver's add() ops. |
1da177e4c Linux-2.6.12-rc2 |
531 532 |
*/ static int |
4be44fcd3 [ACPI] Lindent al... |
533 |
acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) |
1da177e4c Linux-2.6.12-rc2 |
534 |
{ |
4be44fcd3 [ACPI] Lindent al... |
535 |
int result = 0; |
1da177e4c Linux-2.6.12-rc2 |
536 |
|
1da177e4c Linux-2.6.12-rc2 |
537 |
if (!device || !driver) |
d550d98d3 ACPI: delete trac... |
538 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
539 540 |
if (!driver->ops.add) |
d550d98d3 ACPI: delete trac... |
541 |
return -ENOSYS; |
1da177e4c Linux-2.6.12-rc2 |
542 543 544 545 |
result = driver->ops.add(device); if (result) { device->driver = NULL; |
db89b4f0d ACPI: catch calls... |
546 |
device->driver_data = NULL; |
d550d98d3 ACPI: delete trac... |
547 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
548 549 550 551 552 553 554 555 |
} device->driver = driver; /* * TBD - Configuration Management: Assign resources to device based * upon possible configuration and currently allocated resources. */ |
4be44fcd3 [ACPI] Lindent al... |
556 557 558 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device ")); |
d550d98d3 ACPI: delete trac... |
559 |
return 0; |
3fb02738b [PATCH] acpi brid... |
560 |
} |
8713cbefa [ACPI] add static... |
561 |
static int acpi_start_single_object(struct acpi_device *device) |
3fb02738b [PATCH] acpi brid... |
562 563 564 |
{ int result = 0; struct acpi_driver *driver; |
3fb02738b [PATCH] acpi brid... |
565 566 |
if (!(driver = device->driver)) |
d550d98d3 ACPI: delete trac... |
567 |
return 0; |
3fb02738b [PATCH] acpi brid... |
568 |
|
1da177e4c Linux-2.6.12-rc2 |
569 570 571 572 |
if (driver->ops.start) { result = driver->ops.start(device); if (result && driver->ops.remove) driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); |
1da177e4c Linux-2.6.12-rc2 |
573 |
} |
d550d98d3 ACPI: delete trac... |
574 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
575 |
} |
9e89dde2b ACPI: clean up sc... |
576 577 578 579 580 581 582 583 584 |
/** * acpi_bus_register_driver - register a driver with the ACPI bus * @driver: driver being registered * * Registers a driver with the ACPI bus. Searches the namespace for all * devices that match the driver's criteria and binds. Returns zero for * success or a negative error status for failure. */ int acpi_bus_register_driver(struct acpi_driver *driver) |
1da177e4c Linux-2.6.12-rc2 |
585 |
{ |
1890a97ab ACPI: change regi... |
586 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
587 |
|
9e89dde2b ACPI: clean up sc... |
588 589 |
if (acpi_disabled) return -ENODEV; |
1890a97ab ACPI: change regi... |
590 591 592 |
driver->drv.name = driver->name; driver->drv.bus = &acpi_bus_type; driver->drv.owner = driver->owner; |
1da177e4c Linux-2.6.12-rc2 |
593 |
|
1890a97ab ACPI: change regi... |
594 595 |
ret = driver_register(&driver->drv); return ret; |
9e89dde2b ACPI: clean up sc... |
596 |
} |
1da177e4c Linux-2.6.12-rc2 |
597 |
|
9e89dde2b ACPI: clean up sc... |
598 599 600 601 602 603 604 605 606 607 608 |
EXPORT_SYMBOL(acpi_bus_register_driver); /** * acpi_bus_unregister_driver - unregisters a driver with the APIC bus * @driver: driver to unregister * * Unregisters a driver with the ACPI bus. Searches the namespace for all * devices that match the driver's criteria and unbinds. */ void acpi_bus_unregister_driver(struct acpi_driver *driver) { |
1890a97ab ACPI: change regi... |
609 |
driver_unregister(&driver->drv); |
9e89dde2b ACPI: clean up sc... |
610 611 612 |
} EXPORT_SYMBOL(acpi_bus_unregister_driver); |
9e89dde2b ACPI: clean up sc... |
613 614 615 |
/* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ |
5c478f499 ACPI: add acpi_bu... |
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) { acpi_status status; int ret; struct acpi_device *device; /* * Fixed hardware devices do not appear in the namespace and do not * have handles, but we fabricate acpi_devices for them, so we have * to deal with them specially. */ if (handle == NULL) return acpi_root; do { status = acpi_get_parent(handle, &handle); if (status == AE_NULL_ENTRY) return NULL; if (ACPI_FAILURE(status)) return acpi_root; ret = acpi_bus_get_device(handle, &device); if (ret == 0) return device; } while (1); } |
9e89dde2b ACPI: clean up sc... |
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 |
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) { acpi_status status; acpi_handle tmp; struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *obj; status = acpi_get_handle(handle, "_EJD", &tmp); if (ACPI_FAILURE(status)) return status; status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); if (ACPI_SUCCESS(status)) { obj = buffer.pointer; |
3b5fee595 ACPI: Do not pass... |
657 658 |
status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, ejd); |
9e89dde2b ACPI: clean up sc... |
659 660 661 662 663 |
kfree(buffer.pointer); } return status; } EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
8e4319c42 ACPICA: Fix sever... |
664 |
void acpi_bus_data_handler(acpi_handle handle, void *context) |
9e89dde2b ACPI: clean up sc... |
665 666 667 668 669 670 |
{ /* TBD */ return; } |
9e89dde2b ACPI: clean up sc... |
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
static int acpi_bus_get_perf_flags(struct acpi_device *device) { device->performance.state = ACPI_STATE_UNKNOWN; return 0; } static acpi_status acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, union acpi_object *package) { int i = 0; union acpi_object *element = NULL; if (!device || !package || (package->package.count < 2)) return AE_BAD_PARAMETER; element = &(package->package.elements[0]); if (!element) return AE_BAD_PARAMETER; if (element->type == ACPI_TYPE_PACKAGE) { if ((element->package.count < 2) || (element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) return AE_BAD_DATA; device->wakeup.gpe_device = element->package.elements[0].reference.handle; device->wakeup.gpe_number = (u32) element->package.elements[1].integer.value; } else if (element->type == ACPI_TYPE_INTEGER) { device->wakeup.gpe_number = element->integer.value; } else return AE_BAD_DATA; element = &(package->package.elements[1]); if (element->type != ACPI_TYPE_INTEGER) { return AE_BAD_DATA; } device->wakeup.sleep_state = element->integer.value; if ((package->package.count - 2) > ACPI_MAX_HANDLES) { return AE_NO_MEMORY; } device->wakeup.resources.count = package->package.count - 2; for (i = 0; i < device->wakeup.resources.count; i++) { element = &(package->package.elements[i + 2]); |
cd0b22482 ACPICA: Fixes for... |
717 |
if (element->type != ACPI_TYPE_LOCAL_REFERENCE) |
9e89dde2b ACPI: clean up sc... |
718 |
return AE_BAD_DATA; |
9e89dde2b ACPI: clean up sc... |
719 720 |
device->wakeup.resources.handles[i] = element->reference.handle; |
1da177e4c Linux-2.6.12-rc2 |
721 |
} |
9e89dde2b ACPI: clean up sc... |
722 |
|
9874647ba ACPI / ACPICA: Do... |
723 |
acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); |
9e89dde2b ACPI: clean up sc... |
724 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
725 |
} |
f517709d6 ACPI / PM: Add mo... |
726 |
static void acpi_bus_set_run_wake_flags(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
727 |
{ |
29b71a1ca ACPI: autoload mo... |
728 729 730 731 732 733 |
struct acpi_device_id button_device_ids[] = { {"PNP0C0D", 0}, {"PNP0C0C", 0}, {"PNP0C0E", 0}, {"", 0}, }; |
f517709d6 ACPI / PM: Add mo... |
734 735 736 737 |
acpi_status status; acpi_event_status event_status; device->wakeup.run_wake_count = 0; |
b67ea7617 PCI / ACPI / PM: ... |
738 |
device->wakeup.flags.notifier_present = 0; |
f517709d6 ACPI / PM: Add mo... |
739 740 741 742 743 744 745 |
/* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) { device->wakeup.flags.run_wake = 1; device->wakeup.flags.always_enabled = 1; return; } |
e8e18c956 ACPI: Fix bogus G... |
746 747 748 |
status = acpi_get_gpe_status(device->wakeup.gpe_device, device->wakeup.gpe_number, &event_status); |
f517709d6 ACPI / PM: Add mo... |
749 750 751 752 753 754 755 756 757 758 759 |
if (status == AE_OK) device->wakeup.flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE); } static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) { acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *package = NULL; int psw_error; |
29b71a1ca ACPI: autoload mo... |
760 |
|
9e89dde2b ACPI: clean up sc... |
761 762 763 764 765 |
/* _PRW */ status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); goto end; |
1da177e4c Linux-2.6.12-rc2 |
766 |
} |
1da177e4c Linux-2.6.12-rc2 |
767 |
|
9e89dde2b ACPI: clean up sc... |
768 769 770 771 772 773 |
package = (union acpi_object *)buffer.pointer; status = acpi_bus_extract_wakeup_device_power_package(device, package); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); goto end; } |
1da177e4c Linux-2.6.12-rc2 |
774 |
|
9e89dde2b ACPI: clean up sc... |
775 |
kfree(buffer.pointer); |
1da177e4c Linux-2.6.12-rc2 |
776 |
|
9e89dde2b ACPI: clean up sc... |
777 |
device->wakeup.flags.valid = 1; |
9b83ccd2f ACPI PM: Replace ... |
778 |
device->wakeup.prepare_count = 0; |
f517709d6 ACPI / PM: Add mo... |
779 |
acpi_bus_set_run_wake_flags(device); |
729b2bdbf ACPI : Disable th... |
780 781 782 783 784 785 |
/* Call _PSW/_DSW object to disable its ability to wake the sleeping * system for the ACPI device with the _PRW object. * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. * So it is necessary to call _DSW object first. Only when it is not * present will the _PSW object used. */ |
77e766099 ACPI: Introduce a... |
786 787 788 789 790 |
psw_error = acpi_device_sleep_wake(device, 0, 0, 0); if (psw_error) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in _DSW or _PSW evaluation ")); |
0c526d96a ACPI: clean up wh... |
791 |
end: |
9e89dde2b ACPI: clean up sc... |
792 793 |
if (ACPI_FAILURE(status)) device->flags.wake_capable = 0; |
d550d98d3 ACPI: delete trac... |
794 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
795 |
} |
1da177e4c Linux-2.6.12-rc2 |
796 |
|
9e89dde2b ACPI: clean up sc... |
797 |
static int acpi_bus_get_power_flags(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
798 |
{ |
9e89dde2b ACPI: clean up sc... |
799 800 801 |
acpi_status status = 0; acpi_handle handle = NULL; u32 i = 0; |
1a3656160 ACPI: simplify sc... |
802 |
|
4be44fcd3 [ACPI] Lindent al... |
803 |
|
9e89dde2b ACPI: clean up sc... |
804 805 806 807 808 809 810 811 812 |
/* * Power Management Flags */ status = acpi_get_handle(device->handle, "_PSC", &handle); if (ACPI_SUCCESS(status)) device->power.flags.explicit_get = 1; status = acpi_get_handle(device->handle, "_IRC", &handle); if (ACPI_SUCCESS(status)) device->power.flags.inrush_current = 1; |
1da177e4c Linux-2.6.12-rc2 |
813 |
|
9e89dde2b ACPI: clean up sc... |
814 815 816 817 818 819 |
/* * Enumerate supported power management states */ for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { struct acpi_device_power_state *ps = &device->power.states[i]; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; |
1da177e4c Linux-2.6.12-rc2 |
820 |
|
9e89dde2b ACPI: clean up sc... |
821 822 823 824 825 826 |
/* Evaluate "_PRx" to se if power resources are referenced */ acpi_evaluate_reference(device->handle, object_name, NULL, &ps->resources); if (ps->resources.count) { device->power.flags.power_resources = 1; ps->flags.valid = 1; |
1da177e4c Linux-2.6.12-rc2 |
827 |
} |
1da177e4c Linux-2.6.12-rc2 |
828 |
|
9e89dde2b ACPI: clean up sc... |
829 830 831 832 833 834 |
/* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); if (ACPI_SUCCESS(status)) { ps->flags.explicit_set = 1; ps->flags.valid = 1; |
1da177e4c Linux-2.6.12-rc2 |
835 |
} |
1da177e4c Linux-2.6.12-rc2 |
836 |
|
9e89dde2b ACPI: clean up sc... |
837 838 839 |
/* State is valid if we have some power control */ if (ps->resources.count || ps->flags.explicit_set) ps->flags.valid = 1; |
1da177e4c Linux-2.6.12-rc2 |
840 |
|
9e89dde2b ACPI: clean up sc... |
841 842 843 |
ps->power = -1; /* Unknown - driver assigned */ ps->latency = -1; /* Unknown - driver assigned */ } |
1da177e4c Linux-2.6.12-rc2 |
844 |
|
9e89dde2b ACPI: clean up sc... |
845 846 847 848 849 |
/* Set defaults for D0 and D3 states (always valid) */ device->power.states[ACPI_STATE_D0].flags.valid = 1; device->power.states[ACPI_STATE_D0].power = 100; device->power.states[ACPI_STATE_D3].flags.valid = 1; device->power.states[ACPI_STATE_D3].power = 0; |
c8f7a62cd Revert "Revert "A... |
850 |
|
9e89dde2b ACPI: clean up sc... |
851 |
/* TBD: System wake support and resource requirements. */ |
c8f7a62cd Revert "Revert "A... |
852 |
|
9e89dde2b ACPI: clean up sc... |
853 |
device->power.state = ACPI_STATE_UNKNOWN; |
a51e145f3 ACPI: Get the dev... |
854 |
acpi_bus_get_power(device->handle, &(device->power.state)); |
c8f7a62cd Revert "Revert "A... |
855 |
|
9e89dde2b ACPI: clean up sc... |
856 857 |
return 0; } |
c8f7a62cd Revert "Revert "A... |
858 |
|
4be44fcd3 [ACPI] Lindent al... |
859 |
static int acpi_bus_get_flags(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
860 |
{ |
4be44fcd3 [ACPI] Lindent al... |
861 862 |
acpi_status status = AE_OK; acpi_handle temp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
863 |
|
1da177e4c Linux-2.6.12-rc2 |
864 865 866 867 868 |
/* Presence of _STA indicates 'dynamic_status' */ status = acpi_get_handle(device->handle, "_STA", &temp); if (ACPI_SUCCESS(status)) device->flags.dynamic_status = 1; |
1da177e4c Linux-2.6.12-rc2 |
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 |
/* Presence of _RMV indicates 'removable' */ status = acpi_get_handle(device->handle, "_RMV", &temp); if (ACPI_SUCCESS(status)) device->flags.removable = 1; /* Presence of _EJD|_EJ0 indicates 'ejectable' */ status = acpi_get_handle(device->handle, "_EJD", &temp); if (ACPI_SUCCESS(status)) device->flags.ejectable = 1; else { status = acpi_get_handle(device->handle, "_EJ0", &temp); if (ACPI_SUCCESS(status)) device->flags.ejectable = 1; } /* Presence of _LCK indicates 'lockable' */ status = acpi_get_handle(device->handle, "_LCK", &temp); if (ACPI_SUCCESS(status)) device->flags.lockable = 1; /* Presence of _PS0|_PR0 indicates 'power manageable' */ status = acpi_get_handle(device->handle, "_PS0", &temp); if (ACPI_FAILURE(status)) status = acpi_get_handle(device->handle, "_PR0", &temp); if (ACPI_SUCCESS(status)) device->flags.power_manageable = 1; /* Presence of _PRW indicates wake capable */ status = acpi_get_handle(device->handle, "_PRW", &temp); if (ACPI_SUCCESS(status)) device->flags.wake_capable = 1; |
3c5f9be46 drivers/acpi/: Sp... |
900 |
/* TBD: Performance management */ |
1da177e4c Linux-2.6.12-rc2 |
901 |
|
d550d98d3 ACPI: delete trac... |
902 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
903 |
} |
c7bcb4e98 ACPI: remove redu... |
904 |
static void acpi_device_get_busid(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
905 |
{ |
4be44fcd3 [ACPI] Lindent al... |
906 907 908 |
char bus_id[5] = { '?', 0 }; struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; int i = 0; |
1da177e4c Linux-2.6.12-rc2 |
909 910 911 912 913 914 915 |
/* * Bus ID * ------ * The device's Bus ID is simply the object name. * TBD: Shouldn't this value be unique (within the ACPI namespace)? */ |
859ac9a4b ACPI: identify de... |
916 |
if (ACPI_IS_ROOT_DEVICE(device)) { |
1da177e4c Linux-2.6.12-rc2 |
917 |
strcpy(device->pnp.bus_id, "ACPI"); |
859ac9a4b ACPI: identify de... |
918 919 920 921 |
return; } switch (device->device_type) { |
1da177e4c Linux-2.6.12-rc2 |
922 923 924 925 926 927 928 |
case ACPI_BUS_TYPE_POWER_BUTTON: strcpy(device->pnp.bus_id, "PWRF"); break; case ACPI_BUS_TYPE_SLEEP_BUTTON: strcpy(device->pnp.bus_id, "SLPF"); break; default: |
66b7ed40a ACPI: remove redu... |
929 |
acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
930 931 932 933 934 935 936 937 938 939 940 |
/* Clean up trailing underscores (if any) */ for (i = 3; i > 1; i--) { if (bus_id[i] == '_') bus_id[i] = '\0'; else break; } strcpy(device->pnp.bus_id, bus_id); break; } } |
547352660 ACPI: bay: Conver... |
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 |
/* * acpi_bay_match - see if a device is an ejectable driver bay * * If an acpi object is ejectable and has one of the ACPI ATA methods defined, * then we can safely call it an ejectable drive bay */ static int acpi_bay_match(struct acpi_device *device){ acpi_status status; acpi_handle handle; acpi_handle tmp; acpi_handle phandle; handle = device->handle; status = acpi_get_handle(handle, "_EJ0", &tmp); if (ACPI_FAILURE(status)) return -ENODEV; if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) return 0; if (acpi_get_parent(handle, &phandle)) return -ENODEV; if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) || (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp)))) return 0; return -ENODEV; } |
3620f2f2f ACPI: Fix autload... |
976 977 978 979 980 981 982 983 |
/* * acpi_dock_match - see if a device has a _DCK method */ static int acpi_dock_match(struct acpi_device *device) { acpi_handle tmp; return acpi_get_handle(device->handle, "_DCK", &tmp); } |
7f47fa6c2 ACPI: maintain a ... |
984 |
char *acpi_device_hid(struct acpi_device *device) |
15b8dd53f ACPICA: Major upd... |
985 |
{ |
7f47fa6c2 ACPI: maintain a ... |
986 |
struct acpi_hardware_id *hid; |
15b8dd53f ACPICA: Major upd... |
987 |
|
7f47fa6c2 ACPI: maintain a ... |
988 989 990 991 |
hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); return hid->id; } EXPORT_SYMBOL(acpi_device_hid); |
15b8dd53f ACPICA: Major upd... |
992 |
|
7f47fa6c2 ACPI: maintain a ... |
993 994 995 |
static void acpi_add_id(struct acpi_device *device, const char *dev_id) { struct acpi_hardware_id *id; |
15b8dd53f ACPICA: Major upd... |
996 |
|
7f47fa6c2 ACPI: maintain a ... |
997 998 999 |
id = kmalloc(sizeof(*id), GFP_KERNEL); if (!id) return; |
15b8dd53f ACPICA: Major upd... |
1000 |
|
7f47fa6c2 ACPI: maintain a ... |
1001 1002 1003 1004 |
id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL); if (!id->id) { kfree(id); return; |
15b8dd53f ACPICA: Major upd... |
1005 |
} |
7f47fa6c2 ACPI: maintain a ... |
1006 1007 |
strcpy(id->id, dev_id); list_add_tail(&id->list, &device->pnp.ids); |
15b8dd53f ACPICA: Major upd... |
1008 |
} |
222e82ac9 acpi: Support IBM... |
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 |
/* * Old IBM workstations have a DSDT bug wherein the SMBus object * lacks the SMBUS01 HID and the methods do not have the necessary "_" * prefix. Work around this. */ static int acpi_ibm_smbus_match(struct acpi_device *device) { acpi_handle h_dummy; struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; int result; if (!dmi_name_in_vendors("IBM")) return -ENODEV; /* Look for SMBS object */ result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path); if (result) return result; if (strcmp("SMBS", path.pointer)) { result = -ENODEV; goto out; } /* Does it have the necessary (but misnamed) methods? */ result = -ENODEV; if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) && ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) && ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy))) result = 0; out: kfree(path.pointer); return result; } |
c7bcb4e98 ACPI: remove redu... |
1043 |
static void acpi_device_set_id(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1044 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1045 |
acpi_status status; |
57f3674f5 ACPI: simplify bu... |
1046 1047 |
struct acpi_device_info *info; struct acpica_device_id_list *cid_list; |
7f47fa6c2 ACPI: maintain a ... |
1048 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
1049 |
|
c7bcb4e98 ACPI: remove redu... |
1050 |
switch (device->device_type) { |
1da177e4c Linux-2.6.12-rc2 |
1051 |
case ACPI_BUS_TYPE_DEVICE: |
859ac9a4b ACPI: identify de... |
1052 |
if (ACPI_IS_ROOT_DEVICE(device)) { |
57f3674f5 ACPI: simplify bu... |
1053 |
acpi_add_id(device, ACPI_SYSTEM_HID); |
859ac9a4b ACPI: identify de... |
1054 1055 |
break; } |
66b7ed40a ACPI: remove redu... |
1056 |
status = acpi_get_object_info(device->handle, &info); |
1da177e4c Linux-2.6.12-rc2 |
1057 |
if (ACPI_FAILURE(status)) { |
96b2dd1f1 ACPI: replace rem... |
1058 1059 |
printk(KERN_ERR PREFIX "%s: Error reading device info ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1060 1061 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
1062 |
if (info->valid & ACPI_VALID_HID) |
57f3674f5 ACPI: simplify bu... |
1063 1064 |
acpi_add_id(device, info->hardware_id.string); if (info->valid & ACPI_VALID_CID) { |
15b8dd53f ACPICA: Major upd... |
1065 |
cid_list = &info->compatible_id_list; |
57f3674f5 ACPI: simplify bu... |
1066 1067 1068 |
for (i = 0; i < cid_list->count; i++) acpi_add_id(device, cid_list->ids[i].string); } |
1da177e4c Linux-2.6.12-rc2 |
1069 1070 1071 1072 |
if (info->valid & ACPI_VALID_ADR) { device->pnp.bus_address = info->address; device->flags.bus_address = 1; } |
ae8433324 ACPI: Set fake hi... |
1073 |
|
a83893ae9 ACPI: fix bus sca... |
1074 |
kfree(info); |
57f3674f5 ACPI: simplify bu... |
1075 1076 1077 1078 |
/* * Some devices don't reliably have _HIDs & _CIDs, so add * synthetic HIDs to make sure drivers can find them. */ |
c3d6de698 ACPI video: if no... |
1079 |
if (acpi_is_video_device(device)) |
57f3674f5 ACPI: simplify bu... |
1080 |
acpi_add_id(device, ACPI_VIDEO_HID); |
3620f2f2f ACPI: Fix autload... |
1081 |
else if (ACPI_SUCCESS(acpi_bay_match(device))) |
57f3674f5 ACPI: simplify bu... |
1082 |
acpi_add_id(device, ACPI_BAY_HID); |
3620f2f2f ACPI: Fix autload... |
1083 |
else if (ACPI_SUCCESS(acpi_dock_match(device))) |
57f3674f5 ACPI: simplify bu... |
1084 |
acpi_add_id(device, ACPI_DOCK_HID); |
222e82ac9 acpi: Support IBM... |
1085 1086 |
else if (!acpi_ibm_smbus_match(device)) acpi_add_id(device, ACPI_SMBUS_IBM_HID); |
b7b30de53 ACPI: use _HID wh... |
1087 1088 1089 1090 1091 1092 |
else if (!acpi_device_hid(device) && ACPI_IS_ROOT_DEVICE(device->parent)) { acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); strcpy(device->pnp.device_class, ACPI_BUS_CLASS); } |
547352660 ACPI: bay: Conver... |
1093 |
|
1da177e4c Linux-2.6.12-rc2 |
1094 1095 |
break; case ACPI_BUS_TYPE_POWER: |
57f3674f5 ACPI: simplify bu... |
1096 |
acpi_add_id(device, ACPI_POWER_HID); |
1da177e4c Linux-2.6.12-rc2 |
1097 1098 |
break; case ACPI_BUS_TYPE_PROCESSOR: |
57f3674f5 ACPI: simplify bu... |
1099 |
acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID); |
1da177e4c Linux-2.6.12-rc2 |
1100 |
break; |
1da177e4c Linux-2.6.12-rc2 |
1101 |
case ACPI_BUS_TYPE_THERMAL: |
57f3674f5 ACPI: simplify bu... |
1102 |
acpi_add_id(device, ACPI_THERMAL_HID); |
1da177e4c Linux-2.6.12-rc2 |
1103 1104 |
break; case ACPI_BUS_TYPE_POWER_BUTTON: |
57f3674f5 ACPI: simplify bu... |
1105 |
acpi_add_id(device, ACPI_BUTTON_HID_POWERF); |
1da177e4c Linux-2.6.12-rc2 |
1106 1107 |
break; case ACPI_BUS_TYPE_SLEEP_BUTTON: |
57f3674f5 ACPI: simplify bu... |
1108 |
acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); |
1da177e4c Linux-2.6.12-rc2 |
1109 1110 |
break; } |
b1fbfb2ae ACPI: make sure e... |
1111 1112 1113 1114 1115 1116 1117 |
/* * We build acpi_devices for some objects that don't have _HID or _CID, * e.g., PCI bridges and slots. Drivers can't bind to these objects, * but we do use them indirectly by traversing the acpi_device tree. * This generic ID isn't useful for driver binding, but it provides * the useful property that "every acpi_device has an ID." */ |
57f3674f5 ACPI: simplify bu... |
1118 1119 |
if (list_empty(&device->pnp.ids)) acpi_add_id(device, "device"); |
1da177e4c Linux-2.6.12-rc2 |
1120 |
} |
bc3b07726 ACPI: remove acpi... |
1121 |
static int acpi_device_set_context(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1122 |
{ |
bc3b07726 ACPI: remove acpi... |
1123 |
acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
1124 1125 1126 1127 |
/* * Context * ------- * Attach this 'struct acpi_device' to the ACPI object. This makes |
bc3b07726 ACPI: remove acpi... |
1128 1129 |
* resolutions from handle->device very efficient. Fixed hardware * devices have no handles, so we skip them. |
1da177e4c Linux-2.6.12-rc2 |
1130 |
*/ |
bc3b07726 ACPI: remove acpi... |
1131 1132 |
if (!device->handle) return 0; |
1da177e4c Linux-2.6.12-rc2 |
1133 |
|
bc3b07726 ACPI: remove acpi... |
1134 1135 1136 1137 1138 1139 1140 1141 |
status = acpi_attach_data(device->handle, acpi_bus_data_handler, device); if (ACPI_SUCCESS(status)) return 0; printk(KERN_ERR PREFIX "Error attaching device data "); return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
1142 |
} |
4be44fcd3 [ACPI] Lindent al... |
1143 |
static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) |
1da177e4c Linux-2.6.12-rc2 |
1144 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1145 |
if (!dev) |
d550d98d3 ACPI: delete trac... |
1146 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1147 |
|
96333578b ACPI: add acpi_bu... |
1148 |
dev->removal_type = ACPI_BUS_REMOVAL_EJECT; |
1890a97ab ACPI: change regi... |
1149 |
device_release_driver(&dev->dev); |
1da177e4c Linux-2.6.12-rc2 |
1150 1151 |
if (!rmdevice) |
d550d98d3 ACPI: delete trac... |
1152 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1153 |
|
2786f6e38 ACPI: fix Supermi... |
1154 1155 1156 |
/* * unbind _ADR-Based Devices when hot removal */ |
1da177e4c Linux-2.6.12-rc2 |
1157 1158 1159 1160 |
if (dev->flags.bus_address) { if ((dev->parent) && (dev->parent->ops.unbind)) dev->parent->ops.unbind(dev); } |
1da177e4c Linux-2.6.12-rc2 |
1161 |
acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); |
d550d98d3 ACPI: delete trac... |
1162 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1163 |
} |
5c478f499 ACPI: add acpi_bu... |
1164 1165 |
static int acpi_add_single_object(struct acpi_device **child, acpi_handle handle, int type, |
778cbc1d3 ACPI: factor out ... |
1166 |
unsigned long long sta, |
5c478f499 ACPI: add acpi_bu... |
1167 |
struct acpi_bus_ops *ops) |
1da177e4c Linux-2.6.12-rc2 |
1168 |
{ |
77c24888b ACPI: remove unne... |
1169 1170 |
int result; struct acpi_device *device; |
29aaefa68 ACPI: add debug f... |
1171 |
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
1172 |
|
36bcbec7c ACPI: replace kma... |
1173 |
device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
1174 |
if (!device) { |
6468463ab ACPI: un-export A... |
1175 1176 |
printk(KERN_ERR PREFIX "Memory allocation error "); |
d550d98d3 ACPI: delete trac... |
1177 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1178 |
} |
1da177e4c Linux-2.6.12-rc2 |
1179 |
|
7f47fa6c2 ACPI: maintain a ... |
1180 |
INIT_LIST_HEAD(&device->pnp.ids); |
caaa6efb3 ACPI: save device... |
1181 |
device->device_type = type; |
1da177e4c Linux-2.6.12-rc2 |
1182 |
device->handle = handle; |
5c478f499 ACPI: add acpi_bu... |
1183 |
device->parent = acpi_bus_get_parent(handle); |
c4168bff3 ACPI: add acpi_bu... |
1184 |
device->bus_ops = *ops; /* workround for not call .start */ |
778cbc1d3 ACPI: factor out ... |
1185 |
STRUCT_TO_INT(device->status) = sta; |
c4168bff3 ACPI: add acpi_bu... |
1186 |
|
c7bcb4e98 ACPI: remove redu... |
1187 |
acpi_device_get_busid(device); |
1da177e4c Linux-2.6.12-rc2 |
1188 1189 1190 1191 |
/* * Flags * ----- |
778cbc1d3 ACPI: factor out ... |
1192 1193 |
* Note that we only look for object handles -- cannot evaluate objects * until we know the device is present and properly initialized. |
1da177e4c Linux-2.6.12-rc2 |
1194 1195 1196 1197 1198 1199 |
*/ result = acpi_bus_get_flags(device); if (result) goto end; /* |
1da177e4c Linux-2.6.12-rc2 |
1200 1201 1202 1203 |
* Initialize Device * ----------------- * TBD: Synch with Core's enumeration/initialization process. */ |
c7bcb4e98 ACPI: remove redu... |
1204 |
acpi_device_set_id(device); |
1da177e4c Linux-2.6.12-rc2 |
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 |
/* * Power Management * ---------------- */ if (device->flags.power_manageable) { result = acpi_bus_get_power_flags(device); if (result) goto end; } |
4be44fcd3 [ACPI] Lindent al... |
1215 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 |
* Wakeup device management *----------------------- */ if (device->flags.wake_capable) { result = acpi_bus_get_wakeup_device_flags(device); if (result) goto end; } /* * Performance Management * ---------------------- */ if (device->flags.performance_manageable) { result = acpi_bus_get_perf_flags(device); if (result) goto end; } |
bc3b07726 ACPI: remove acpi... |
1234 |
if ((result = acpi_device_set_context(device))) |
f61f92585 Revert "ACPI: Att... |
1235 |
goto end; |
1da177e4c Linux-2.6.12-rc2 |
1236 |
|
66b7ed40a ACPI: remove redu... |
1237 |
result = acpi_device_register(device); |
1da177e4c Linux-2.6.12-rc2 |
1238 1239 |
/* |
2786f6e38 ACPI: fix Supermi... |
1240 |
* Bind _ADR-Based Devices when hot add |
1da177e4c Linux-2.6.12-rc2 |
1241 1242 1243 1244 1245 |
*/ if (device->flags.bus_address) { if (device->parent && device->parent->ops.bind) device->parent->ops.bind(device); } |
0c526d96a ACPI: clean up wh... |
1246 |
end: |
29aaefa68 ACPI: add debug f... |
1247 1248 1249 1250 1251 1252 1253 1254 1255 |
if (!result) { acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Adding %s [%s] parent %s ", dev_name(&device->dev), (char *) buffer.pointer, device->parent ? dev_name(&device->parent->dev) : "(null)")); kfree(buffer.pointer); |
1da177e4c Linux-2.6.12-rc2 |
1256 |
*child = device; |
29aaefa68 ACPI: add debug f... |
1257 |
} else |
718fb0de8 ACPI: fix NULL bu... |
1258 |
acpi_device_release(&device->dev); |
1da177e4c Linux-2.6.12-rc2 |
1259 |
|
d550d98d3 ACPI: delete trac... |
1260 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
1261 |
} |
1da177e4c Linux-2.6.12-rc2 |
1262 |
|
778cbc1d3 ACPI: factor out ... |
1263 1264 1265 1266 1267 |
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) static int acpi_bus_type_and_status(acpi_handle handle, int *type, unsigned long long *sta) |
1da177e4c Linux-2.6.12-rc2 |
1268 |
{ |
778cbc1d3 ACPI: factor out ... |
1269 1270 |
acpi_status status; acpi_object_type acpi_type; |
1da177e4c Linux-2.6.12-rc2 |
1271 |
|
778cbc1d3 ACPI: factor out ... |
1272 |
status = acpi_get_type(handle, &acpi_type); |
51a85faf2 ACPI: use acpi_wa... |
1273 |
if (ACPI_FAILURE(status)) |
778cbc1d3 ACPI: factor out ... |
1274 |
return -ENODEV; |
4be44fcd3 [ACPI] Lindent al... |
1275 |
|
778cbc1d3 ACPI: factor out ... |
1276 |
switch (acpi_type) { |
51a85faf2 ACPI: use acpi_wa... |
1277 1278 |
case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ case ACPI_TYPE_DEVICE: |
778cbc1d3 ACPI: factor out ... |
1279 1280 1281 1282 |
*type = ACPI_BUS_TYPE_DEVICE; status = acpi_bus_get_status_handle(handle, sta); if (ACPI_FAILURE(status)) return -ENODEV; |
51a85faf2 ACPI: use acpi_wa... |
1283 1284 |
break; case ACPI_TYPE_PROCESSOR: |
778cbc1d3 ACPI: factor out ... |
1285 1286 1287 1288 |
*type = ACPI_BUS_TYPE_PROCESSOR; status = acpi_bus_get_status_handle(handle, sta); if (ACPI_FAILURE(status)) return -ENODEV; |
51a85faf2 ACPI: use acpi_wa... |
1289 1290 |
break; case ACPI_TYPE_THERMAL: |
778cbc1d3 ACPI: factor out ... |
1291 1292 |
*type = ACPI_BUS_TYPE_THERMAL; *sta = ACPI_STA_DEFAULT; |
51a85faf2 ACPI: use acpi_wa... |
1293 1294 |
break; case ACPI_TYPE_POWER: |
778cbc1d3 ACPI: factor out ... |
1295 1296 |
*type = ACPI_BUS_TYPE_POWER; *sta = ACPI_STA_DEFAULT; |
51a85faf2 ACPI: use acpi_wa... |
1297 1298 |
break; default: |
778cbc1d3 ACPI: factor out ... |
1299 |
return -ENODEV; |
51a85faf2 ACPI: use acpi_wa... |
1300 |
} |
1da177e4c Linux-2.6.12-rc2 |
1301 |
|
778cbc1d3 ACPI: factor out ... |
1302 1303 1304 1305 1306 1307 1308 |
return 0; } static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, void *context, void **return_value) { struct acpi_bus_ops *ops = context; |
778cbc1d3 ACPI: factor out ... |
1309 1310 |
int type; unsigned long long sta; |
e3b87f8a9 ACPI: handle re-e... |
1311 1312 |
struct acpi_device *device; acpi_status status; |
778cbc1d3 ACPI: factor out ... |
1313 1314 1315 1316 1317 1318 1319 1320 1321 |
int result; result = acpi_bus_type_and_status(handle, &type, &sta); if (result) return AE_OK; if (!(sta & ACPI_STA_DEVICE_PRESENT) && !(sta & ACPI_STA_DEVICE_FUNCTIONING)) return AE_CTRL_DEPTH; |
e3b87f8a9 ACPI: handle re-e... |
1322 1323 1324 1325 1326 1327 1328 1329 |
/* * We may already have an acpi_device from a previous enumeration. If * so, we needn't add it again, but we may still have to start it. */ device = NULL; acpi_bus_get_device(handle, &device); if (ops->acpi_op_add && !device) acpi_add_single_object(&device, handle, type, sta, ops); |
1da177e4c Linux-2.6.12-rc2 |
1330 |
|
e3b87f8a9 ACPI: handle re-e... |
1331 |
if (!device) |
51a85faf2 ACPI: use acpi_wa... |
1332 |
return AE_CTRL_DEPTH; |
1da177e4c Linux-2.6.12-rc2 |
1333 |
|
51a85faf2 ACPI: use acpi_wa... |
1334 1335 |
if (ops->acpi_op_start && !(ops->acpi_op_add)) { status = acpi_start_single_object(device); |
1da177e4c Linux-2.6.12-rc2 |
1336 |
if (ACPI_FAILURE(status)) |
51a85faf2 ACPI: use acpi_wa... |
1337 1338 |
return AE_CTRL_DEPTH; } |
1da177e4c Linux-2.6.12-rc2 |
1339 |
|
51a85faf2 ACPI: use acpi_wa... |
1340 1341 1342 1343 |
if (!*return_value) *return_value = device; return AE_OK; } |
3fb02738b [PATCH] acpi brid... |
1344 |
|
51a85faf2 ACPI: use acpi_wa... |
1345 1346 1347 1348 |
static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, struct acpi_device **child) { acpi_status status; |
51a85faf2 ACPI: use acpi_wa... |
1349 |
void *device = NULL; |
3fb02738b [PATCH] acpi brid... |
1350 |
|
51a85faf2 ACPI: use acpi_wa... |
1351 1352 1353 |
status = acpi_bus_check_add(handle, 0, ops, &device); if (ACPI_SUCCESS(status)) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
2263576cf ACPICA: Add post-... |
1354 |
acpi_bus_check_add, NULL, ops, &device); |
1da177e4c Linux-2.6.12-rc2 |
1355 |
|
51a85faf2 ACPI: use acpi_wa... |
1356 1357 |
if (child) *child = device; |
7779688fc ACPI: acpi_bus_{s... |
1358 1359 1360 1361 1362 |
if (device) return 0; else return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
1363 |
} |
1da177e4c Linux-2.6.12-rc2 |
1364 |
|
7779688fc ACPI: acpi_bus_{s... |
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 |
/* * acpi_bus_add and acpi_bus_start * * scan a given ACPI tree and (probably recently hot-plugged) * create and add or starts found devices. * * If no devices were found -ENODEV is returned which does not * mean that this is a real error, there just have been no suitable * ACPI objects in the table trunk from which the kernel could create * a device and add/start an appropriate driver. */ |
3fb02738b [PATCH] acpi brid... |
1376 |
int |
4be44fcd3 [ACPI] Lindent al... |
1377 1378 |
acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type) |
3fb02738b [PATCH] acpi brid... |
1379 |
{ |
3fb02738b [PATCH] acpi brid... |
1380 |
struct acpi_bus_ops ops; |
c4168bff3 ACPI: add acpi_bu... |
1381 1382 |
memset(&ops, 0, sizeof(ops)); ops.acpi_op_add = 1; |
3fb02738b [PATCH] acpi brid... |
1383 |
|
7779688fc ACPI: acpi_bus_{s... |
1384 |
return acpi_bus_scan(handle, &ops, child); |
3fb02738b [PATCH] acpi brid... |
1385 1386 |
} EXPORT_SYMBOL(acpi_bus_add); |
4be44fcd3 [ACPI] Lindent al... |
1387 |
int acpi_bus_start(struct acpi_device *device) |
3fb02738b [PATCH] acpi brid... |
1388 |
{ |
3fb02738b [PATCH] acpi brid... |
1389 |
struct acpi_bus_ops ops; |
d2f6650a9 ACPI: Add NULL po... |
1390 1391 |
if (!device) return -EINVAL; |
8e029bf0a ACPI: convert acp... |
1392 1393 |
memset(&ops, 0, sizeof(ops)); ops.acpi_op_start = 1; |
3fb02738b [PATCH] acpi brid... |
1394 |
|
7779688fc ACPI: acpi_bus_{s... |
1395 |
return acpi_bus_scan(device->handle, &ops, NULL); |
3fb02738b [PATCH] acpi brid... |
1396 1397 |
} EXPORT_SYMBOL(acpi_bus_start); |
1da177e4c Linux-2.6.12-rc2 |
1398 |
|
ceaba6630 [PATCH] acpi: exp... |
1399 |
int acpi_bus_trim(struct acpi_device *start, int rmdevice) |
1da177e4c Linux-2.6.12-rc2 |
1400 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1401 1402 1403 1404 1405 1406 1407 1408 |
acpi_status status; struct acpi_device *parent, *child; acpi_handle phandle, chandle; acpi_object_type type; u32 level = 1; int err = 0; parent = start; |
1da177e4c Linux-2.6.12-rc2 |
1409 1410 1411 1412 1413 |
phandle = start->handle; child = chandle = NULL; while ((level > 0) && parent && (!err)) { status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, |
4be44fcd3 [ACPI] Lindent al... |
1414 |
chandle, &chandle); |
1da177e4c Linux-2.6.12-rc2 |
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 |
/* * If this scope is exhausted then move our way back up. */ if (ACPI_FAILURE(status)) { level--; chandle = phandle; acpi_get_parent(phandle, &phandle); child = parent; parent = parent->parent; if (level == 0) err = acpi_bus_remove(child, rmdevice); else err = acpi_bus_remove(child, 1); continue; } status = acpi_get_type(chandle, &type); if (ACPI_FAILURE(status)) { continue; } /* * If there is a device corresponding to chandle then * parse it (depth-first). */ if (acpi_bus_get_device(chandle, &child) == 0) { level++; phandle = chandle; chandle = NULL; parent = child; } continue; } return err; } |
ceaba6630 [PATCH] acpi: exp... |
1452 |
EXPORT_SYMBOL_GPL(acpi_bus_trim); |
e8b945c9c ACPI: remove unus... |
1453 |
static int acpi_bus_scan_fixed(void) |
1da177e4c Linux-2.6.12-rc2 |
1454 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1455 1456 |
int result = 0; struct acpi_device *device = NULL; |
c4168bff3 ACPI: add acpi_bu... |
1457 |
struct acpi_bus_ops ops; |
1da177e4c Linux-2.6.12-rc2 |
1458 |
|
c4168bff3 ACPI: add acpi_bu... |
1459 1460 1461 |
memset(&ops, 0, sizeof(ops)); ops.acpi_op_add = 1; ops.acpi_op_start = 1; |
1da177e4c Linux-2.6.12-rc2 |
1462 1463 1464 |
/* * Enumerate all fixed-feature devices. */ |
cee324b14 ACPICA: use new A... |
1465 |
if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { |
5c478f499 ACPI: add acpi_bu... |
1466 |
result = acpi_add_single_object(&device, NULL, |
c4168bff3 ACPI: add acpi_bu... |
1467 |
ACPI_BUS_TYPE_POWER_BUTTON, |
778cbc1d3 ACPI: factor out ... |
1468 |
ACPI_STA_DEFAULT, |
c4168bff3 ACPI: add acpi_bu... |
1469 |
&ops); |
3fb02738b [PATCH] acpi brid... |
1470 |
} |
1da177e4c Linux-2.6.12-rc2 |
1471 |
|
cee324b14 ACPICA: use new A... |
1472 |
if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { |
5c478f499 ACPI: add acpi_bu... |
1473 |
result = acpi_add_single_object(&device, NULL, |
c4168bff3 ACPI: add acpi_bu... |
1474 |
ACPI_BUS_TYPE_SLEEP_BUTTON, |
778cbc1d3 ACPI: factor out ... |
1475 |
ACPI_STA_DEFAULT, |
c4168bff3 ACPI: add acpi_bu... |
1476 |
&ops); |
3fb02738b [PATCH] acpi brid... |
1477 |
} |
1da177e4c Linux-2.6.12-rc2 |
1478 |
|
d550d98d3 ACPI: delete trac... |
1479 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
1480 |
} |
e747f2749 ACPI: call acpi_s... |
1481 |
int __init acpi_scan_init(void) |
1da177e4c Linux-2.6.12-rc2 |
1482 1483 |
{ int result; |
3fb02738b [PATCH] acpi brid... |
1484 |
struct acpi_bus_ops ops; |
1da177e4c Linux-2.6.12-rc2 |
1485 |
|
c4168bff3 ACPI: add acpi_bu... |
1486 1487 1488 |
memset(&ops, 0, sizeof(ops)); ops.acpi_op_add = 1; ops.acpi_op_start = 1; |
1da177e4c Linux-2.6.12-rc2 |
1489 |
|
5b3272655 ACPI: create acpi... |
1490 1491 1492 1493 1494 1495 |
result = bus_register(&acpi_bus_type); if (result) { /* We don't want to quit even if we failed to add suspend/resume */ printk(KERN_ERR PREFIX "Could not register bus type "); } |
1da177e4c Linux-2.6.12-rc2 |
1496 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1497 1498 |
* Enumerate devices in the ACPI namespace. */ |
51a85faf2 ACPI: use acpi_wa... |
1499 |
result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root); |
c04209a79 ACPI: EC: Enable ... |
1500 |
|
c4168bff3 ACPI: add acpi_bu... |
1501 |
if (!result) |
adc08e203 ACPI: enumerate n... |
1502 |
result = acpi_bus_scan_fixed(); |
1da177e4c Linux-2.6.12-rc2 |
1503 1504 1505 |
if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
d550d98d3 ACPI: delete trac... |
1506 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
1507 |
} |