aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2007-02-03 01:14:35 -0500
committerLen Brown <len.brown@intel.com>2007-02-03 01:14:35 -0500
commit975a8e3ed2b9eab9f062a1e0ba7fe180e15204e1 (patch)
tree59b654df0b066b6d6b8ea16f5ae581b8fb45c1d5 /drivers/acpi/scan.c
parent1fcb71b84b05ff3bfd5b5b2eca9a9b3d13a76e3a (diff)
parentbfd80223d73f80e1d1c69dace9151756b3ef3b49 (diff)
Pull sysfs into test branch
Conflicts: Documentation/feature-removal-schedule.txt include/acpi/acpi_drivers.h Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c1176
1 files changed, 549 insertions, 627 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0de45866464..5049230ccf4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -21,101 +21,305 @@ extern struct acpi_device *acpi_root;
21#define ACPI_BUS_DEVICE_NAME "System Bus" 21#define ACPI_BUS_DEVICE_NAME "System Bus"
22 22
23static LIST_HEAD(acpi_device_list); 23static LIST_HEAD(acpi_device_list);
24static LIST_HEAD(acpi_bus_id_list);
24DEFINE_SPINLOCK(acpi_device_lock); 25DEFINE_SPINLOCK(acpi_device_lock);
25LIST_HEAD(acpi_wakeup_device_list); 26LIST_HEAD(acpi_wakeup_device_list);
26 27
28struct acpi_device_bus_id{
29 char bus_id[15];
30 unsigned int instance_no;
31 struct list_head node;
32};
33static int acpi_eject_operation(acpi_handle handle, int lockable)
34{
35 struct acpi_object_list arg_list;
36 union acpi_object arg;
37 acpi_status status = AE_OK;
38
39 /*
40 * TBD: evaluate _PS3?
41 */
42
43 if (lockable) {
44 arg_list.count = 1;
45 arg_list.pointer = &arg;
46 arg.type = ACPI_TYPE_INTEGER;
47 arg.integer.value = 0;
48 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
49 }
50
51 arg_list.count = 1;
52 arg_list.pointer = &arg;
53 arg.type = ACPI_TYPE_INTEGER;
54 arg.integer.value = 1;
27 55
28static void acpi_device_release(struct kobject *kobj) 56 /*
57 * TBD: _EJD support.
58 */
59
60 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
61 if (ACPI_FAILURE(status)) {
62 return (-ENODEV);
63 }
64
65 return (0);
66}
67
68static ssize_t
69acpi_eject_store(struct device *d, struct device_attribute *attr,
70 const char *buf, size_t count)
29{ 71{
30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); 72 int result;
31 kfree(dev->pnp.cid_list); 73 int ret = count;
32 kfree(dev); 74 int islockable;
75 acpi_status status;
76 acpi_handle handle;
77 acpi_object_type type = 0;
78 struct acpi_device *acpi_device = to_acpi_device(d);
79
80 if ((!count) || (buf[0] != '1')) {
81 return -EINVAL;
82 }
83#ifndef FORCE_EJECT
84 if (acpi_device->driver == NULL) {
85 ret = -ENODEV;
86 goto err;
87 }
88#endif
89 status = acpi_get_type(acpi_device->handle, &type);
90 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
91 ret = -ENODEV;
92 goto err;
93 }
94
95 islockable = acpi_device->flags.lockable;
96 handle = acpi_device->handle;
97
98 result = acpi_bus_trim(acpi_device, 1);
99
100 if (!result)
101 result = acpi_eject_operation(handle, islockable);
102
103 if (result) {
104 ret = -EBUSY;
105 }
106 err:
107 return ret;
33} 108}
34 109
35struct acpi_device_attribute { 110static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
36 struct attribute attr;
37 ssize_t(*show) (struct acpi_device *, char *);
38 ssize_t(*store) (struct acpi_device *, const char *, size_t);
39};
40 111
41typedef void acpi_device_sysfs_files(struct kobject *, 112static ssize_t
42 const struct attribute *); 113acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
114 struct acpi_device *acpi_dev = to_acpi_device(dev);
43 115
44static void setup_sys_fs_device_files(struct acpi_device *dev, 116 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
45 acpi_device_sysfs_files * func); 117}
118static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
46 119
47#define create_sysfs_device_files(dev) \ 120static ssize_t
48 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file) 121acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
49#define remove_sysfs_device_files(dev) \ 122 struct acpi_device *acpi_dev = to_acpi_device(dev);
50 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file) 123 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
124 int result;
125
126 result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
127 if(result)
128 goto end;
51 129
52#define to_acpi_device(n) container_of(n, struct acpi_device, kobj) 130 result = sprintf(buf, "%s\n", (char*)path.pointer);
53#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr); 131 kfree(path.pointer);
132 end:
133 return result;
134}
135static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
54 136
55static ssize_t acpi_device_attr_show(struct kobject *kobj, 137static int acpi_device_setup_files(struct acpi_device *dev)
56 struct attribute *attr, char *buf)
57{ 138{
58 struct acpi_device *device = to_acpi_device(kobj); 139 acpi_status status;
59 struct acpi_device_attribute *attribute = to_handle_attr(attr); 140 acpi_handle temp;
60 return attribute->show ? attribute->show(device, buf) : -EIO; 141 int result = 0;
142
143 /*
144 * Devices gotten from FADT don't have a "path" attribute
145 */
146 if(dev->handle) {
147 result = device_create_file(&dev->dev, &dev_attr_path);
148 if(result)
149 goto end;
150 }
151
152 if(dev->flags.hardware_id) {
153 result = device_create_file(&dev->dev, &dev_attr_hid);
154 if(result)
155 goto end;
156 }
157
158 /*
159 * If device has _EJ0, 'eject' file is created that is used to trigger
160 * hot-removal function from userland.
161 */
162 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
163 if (ACPI_SUCCESS(status))
164 result = device_create_file(&dev->dev, &dev_attr_eject);
165 end:
166 return result;
61} 167}
62static ssize_t acpi_device_attr_store(struct kobject *kobj, 168
63 struct attribute *attr, const char *buf, 169static void acpi_device_remove_files(struct acpi_device *dev)
64 size_t len)
65{ 170{
66 struct acpi_device *device = to_acpi_device(kobj); 171 acpi_status status;
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 172 acpi_handle temp;
68 return attribute->store ? attribute->store(device, buf, len) : -EIO; 173
174 /*
175 * If device has _EJ0, 'eject' file is created that is used to trigger
176 * hot-removal function from userland.
177 */
178 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
179 if (ACPI_SUCCESS(status))
180 device_remove_file(&dev->dev, &dev_attr_eject);
181
182 if(dev->flags.hardware_id)
183 device_remove_file(&dev->dev, &dev_attr_hid);
184 if(dev->handle)
185 device_remove_file(&dev->dev, &dev_attr_path);
69} 186}
187/* --------------------------------------------------------------------------
188 ACPI Bus operations
189 -------------------------------------------------------------------------- */
190static void acpi_device_release(struct device *dev)
191{
192 struct acpi_device *acpi_dev = to_acpi_device(dev);
70 193
71static struct sysfs_ops acpi_device_sysfs_ops = { 194 kfree(acpi_dev->pnp.cid_list);
72 .show = acpi_device_attr_show, 195 kfree(acpi_dev);
73 .store = acpi_device_attr_store, 196}
74};
75 197
76static struct kobj_type ktype_acpi_ns = { 198static int acpi_device_suspend(struct device *dev, pm_message_t state)
77 .sysfs_ops = &acpi_device_sysfs_ops, 199{
78 .release = acpi_device_release, 200 struct acpi_device *acpi_dev = to_acpi_device(dev);
79}; 201 struct acpi_driver *acpi_drv = acpi_dev->driver;
202
203 if (acpi_drv && acpi_drv->ops.suspend)
204 return acpi_drv->ops.suspend(acpi_dev, state);
205 return 0;
206}
80 207
81static int namespace_uevent(struct kset *kset, struct kobject *kobj, 208static int acpi_device_resume(struct device *dev)
82 char **envp, int num_envp, char *buffer,
83 int buffer_size)
84{ 209{
85 struct acpi_device *dev = to_acpi_device(kobj); 210 struct acpi_device *acpi_dev = to_acpi_device(dev);
86 int i = 0; 211 struct acpi_driver *acpi_drv = acpi_dev->driver;
87 int len = 0;
88 212
89 if (!dev->driver) 213 if (acpi_drv && acpi_drv->ops.resume)
90 return 0; 214 return acpi_drv->ops.resume(acpi_dev);
215 return 0;
216}
217
218static int acpi_bus_match(struct device *dev, struct device_driver *drv)
219{
220 struct acpi_device *acpi_dev = to_acpi_device(dev);
221 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
91 222
92 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 223 return !acpi_match_ids(acpi_dev, acpi_drv->ids);
93 "PHYSDEVDRIVER=%s", dev->driver->name)) 224}
225
226static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
227 char *buffer, int buffer_size)
228{
229 struct acpi_device *acpi_dev = to_acpi_device(dev);
230 int i = 0, length = 0, ret = 0;
231
232 if (acpi_dev->flags.hardware_id)
233 ret = add_uevent_var(envp, num_envp, &i,
234 buffer, buffer_size, &length,
235 "HWID=%s", acpi_dev->pnp.hardware_id);
236 if (ret)
94 return -ENOMEM; 237 return -ENOMEM;
238 if (acpi_dev->flags.compatible_ids) {
239 int j;
240 struct acpi_compatible_id_list *cid_list;
241
242 cid_list = acpi_dev->pnp.cid_list;
243
244 for (j = 0; j < cid_list->count; j++) {
245 ret = add_uevent_var(envp, num_envp, &i, buffer,
246 buffer_size, &length, "COMPTID=%s",
247 cid_list->id[j].value);
248 if (ret)
249 return -ENOMEM;
250 }
251 }
95 252
96 envp[i] = NULL; 253 envp[i] = NULL;
254 return 0;
255}
256
257static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
258static int acpi_start_single_object(struct acpi_device *);
259static int acpi_device_probe(struct device * dev)
260{
261 struct acpi_device *acpi_dev = to_acpi_device(dev);
262 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
263 int ret;
264
265 ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
266 if (!ret) {
267 if (acpi_dev->bus_ops.acpi_op_start)
268 acpi_start_single_object(acpi_dev);
269 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
270 "Found driver [%s] for device [%s]\n",
271 acpi_drv->name, acpi_dev->pnp.bus_id));
272 get_device(dev);
273 }
274 return ret;
275}
276
277static int acpi_device_remove(struct device * dev)
278{
279 struct acpi_device *acpi_dev = to_acpi_device(dev);
280 struct acpi_driver *acpi_drv = acpi_dev->driver;
281
282 if (acpi_drv) {
283 if (acpi_drv->ops.stop)
284 acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
285 if (acpi_drv->ops.remove)
286 acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
287 }
288 acpi_dev->driver = NULL;
289 acpi_driver_data(dev) = NULL;
97 290
291 put_device(dev);
98 return 0; 292 return 0;
99} 293}
100 294
101static struct kset_uevent_ops namespace_uevent_ops = { 295static void acpi_device_shutdown(struct device *dev)
102 .uevent = &namespace_uevent, 296{
103}; 297 struct acpi_device *acpi_dev = to_acpi_device(dev);
298 struct acpi_driver *acpi_drv = acpi_dev->driver;
104 299
105static struct kset acpi_namespace_kset = { 300 if (acpi_drv && acpi_drv->ops.shutdown)
106 .kobj = { 301 acpi_drv->ops.shutdown(acpi_dev);
107 .name = "namespace", 302
108 }, 303 return ;
109 .subsys = &acpi_subsys, 304}
110 .ktype = &ktype_acpi_ns, 305
111 .uevent_ops = &namespace_uevent_ops, 306static struct bus_type acpi_bus_type = {
307 .name = "acpi",
308 .suspend = acpi_device_suspend,
309 .resume = acpi_device_resume,
310 .shutdown = acpi_device_shutdown,
311 .match = acpi_bus_match,
312 .probe = acpi_device_probe,
313 .remove = acpi_device_remove,
314 .uevent = acpi_device_uevent,
112}; 315};
113 316
114static void acpi_device_register(struct acpi_device *device, 317static int acpi_device_register(struct acpi_device *device,
115 struct acpi_device *parent) 318 struct acpi_device *parent)
116{ 319{
117 int err; 320 int result;
118 321 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
322 int found = 0;
119 /* 323 /*
120 * Linkage 324 * Linkage
121 * ------- 325 * -------
@@ -126,7 +330,33 @@ static void acpi_device_register(struct acpi_device *device,
126 INIT_LIST_HEAD(&device->g_list); 330 INIT_LIST_HEAD(&device->g_list);
127 INIT_LIST_HEAD(&device->wakeup_list); 331 INIT_LIST_HEAD(&device->wakeup_list);
128 332
333 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
334 if (!new_bus_id) {
335 printk(KERN_ERR PREFIX "Memory allocation error\n");
336 return -ENOMEM;
337 }
338
129 spin_lock(&acpi_device_lock); 339 spin_lock(&acpi_device_lock);
340 /*
341 * Find suitable bus_id and instance number in acpi_bus_id_list
342 * If failed, create one and link it into acpi_bus_id_list
343 */
344 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
345 if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) {
346 acpi_device_bus_id->instance_no ++;
347 found = 1;
348 kfree(new_bus_id);
349 break;
350 }
351 }
352 if(!found) {
353 acpi_device_bus_id = new_bus_id;
354 strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
355 acpi_device_bus_id->instance_no = 0;
356 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
357 }
358 sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
359
130 if (device->parent) { 360 if (device->parent) {
131 list_add_tail(&device->node, &device->parent->children); 361 list_add_tail(&device->node, &device->parent->children);
132 list_add_tail(&device->g_list, &device->parent->g_list); 362 list_add_tail(&device->g_list, &device->parent->g_list);
@@ -136,16 +366,33 @@ static void acpi_device_register(struct acpi_device *device,
136 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); 366 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
137 spin_unlock(&acpi_device_lock); 367 spin_unlock(&acpi_device_lock);
138 368
139 strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN); 369 if (device->parent)
140 if (parent) 370 device->dev.parent = &parent->dev;
141 device->kobj.parent = &parent->kobj; 371 device->dev.bus = &acpi_bus_type;
142 device->kobj.ktype = &ktype_acpi_ns; 372 device_initialize(&device->dev);
143 device->kobj.kset = &acpi_namespace_kset; 373 device->dev.release = &acpi_device_release;
144 err = kobject_register(&device->kobj); 374 result = device_add(&device->dev);
145 if (err < 0) 375 if(result) {
146 printk(KERN_WARNING "%s: kobject_register error: %d\n", 376 printk("Error adding device %s", device->dev.bus_id);
147 __FUNCTION__, err); 377 goto end;
148 create_sysfs_device_files(device); 378 }
379
380 result = acpi_device_setup_files(device);
381 if(result)
382 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
383
384 device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
385 return 0;
386 end:
387 spin_lock(&acpi_device_lock);
388 if (device->parent) {
389 list_del(&device->node);
390 list_del(&device->g_list);
391 } else
392 list_del(&device->g_list);
393 list_del(&device->wakeup_list);
394 spin_unlock(&acpi_device_lock);
395 return result;
149} 396}
150 397
151static void acpi_device_unregister(struct acpi_device *device, int type) 398static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -158,81 +405,143 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
158 list_del(&device->g_list); 405 list_del(&device->g_list);
159 406
160 list_del(&device->wakeup_list); 407 list_del(&device->wakeup_list);
161
162 spin_unlock(&acpi_device_lock); 408 spin_unlock(&acpi_device_lock);
163 409
164 acpi_detach_data(device->handle, acpi_bus_data_handler); 410 acpi_detach_data(device->handle, acpi_bus_data_handler);
165 remove_sysfs_device_files(device); 411
166 kobject_unregister(&device->kobj); 412 acpi_device_remove_files(device);
413 device_unregister(&device->dev);
167} 414}
168 415
169void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 416/* --------------------------------------------------------------------------
417 Driver Management
418 -------------------------------------------------------------------------- */
419/**
420 * acpi_bus_driver_init - add a device to a driver
421 * @device: the device to add and initialize
422 * @driver: driver for the device
423 *
424 * Used to initialize a device via its device driver. Called whenever a
425 * driver is bound to a device. Invokes the driver's add() ops.
426 */
427static int
428acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
170{ 429{
430 int result = 0;
171 431
172 /* TBD */
173 432
174 return; 433 if (!device || !driver)
175} 434 return -EINVAL;
176 435
177static int acpi_bus_get_power_flags(struct acpi_device *device) 436 if (!driver->ops.add)
178{ 437 return -ENOSYS;
179 acpi_status status = 0;
180 acpi_handle handle = NULL;
181 u32 i = 0;
182 438
439 result = driver->ops.add(device);
440 if (result) {
441 device->driver = NULL;
442 acpi_driver_data(device) = NULL;
443 return result;
444 }
183 445
184 /* 446 device->driver = driver;
185 * Power Management Flags
186 */
187 status = acpi_get_handle(device->handle, "_PSC", &handle);
188 if (ACPI_SUCCESS(status))
189 device->power.flags.explicit_get = 1;
190 status = acpi_get_handle(device->handle, "_IRC", &handle);
191 if (ACPI_SUCCESS(status))
192 device->power.flags.inrush_current = 1;
193 447
194 /* 448 /*
195 * Enumerate supported power management states 449 * TBD - Configuration Management: Assign resources to device based
450 * upon possible configuration and currently allocated resources.
196 */ 451 */
197 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
198 struct acpi_device_power_state *ps = &device->power.states[i];
199 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
200 452
201 /* Evaluate "_PRx" to se if power resources are referenced */ 453 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
202 acpi_evaluate_reference(device->handle, object_name, NULL, 454 "Driver successfully bound to device\n"));
203 &ps->resources); 455 return 0;
204 if (ps->resources.count) { 456}
205 device->power.flags.power_resources = 1;
206 ps->flags.valid = 1;
207 }
208 457
209 /* Evaluate "_PSx" to see if we can do explicit sets */ 458static int acpi_start_single_object(struct acpi_device *device)
210 object_name[2] = 'S'; 459{
211 status = acpi_get_handle(device->handle, object_name, &handle); 460 int result = 0;
212 if (ACPI_SUCCESS(status)) { 461 struct acpi_driver *driver;
213 ps->flags.explicit_set = 1;
214 ps->flags.valid = 1;
215 }
216 462
217 /* State is valid if we have some power control */
218 if (ps->resources.count || ps->flags.explicit_set)
219 ps->flags.valid = 1;
220 463
221 ps->power = -1; /* Unknown - driver assigned */ 464 if (!(driver = device->driver))
222 ps->latency = -1; /* Unknown - driver assigned */ 465 return 0;
466
467 if (driver->ops.start) {
468 result = driver->ops.start(device);
469 if (result && driver->ops.remove)
470 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
223 } 471 }
224 472
225 /* Set defaults for D0 and D3 states (always valid) */ 473 return result;
226 device->power.states[ACPI_STATE_D0].flags.valid = 1; 474}
227 device->power.states[ACPI_STATE_D0].power = 100;
228 device->power.states[ACPI_STATE_D3].flags.valid = 1;
229 device->power.states[ACPI_STATE_D3].power = 0;
230 475
231 /* TBD: System wake support and resource requirements. */ 476/**
477 * acpi_bus_register_driver - register a driver with the ACPI bus
478 * @driver: driver being registered
479 *
480 * Registers a driver with the ACPI bus. Searches the namespace for all
481 * devices that match the driver's criteria and binds. Returns zero for
482 * success or a negative error status for failure.
483 */
484int acpi_bus_register_driver(struct acpi_driver *driver)
485{
486 int ret;
232 487
233 device->power.state = ACPI_STATE_UNKNOWN; 488 if (acpi_disabled)
489 return -ENODEV;
490 driver->drv.name = driver->name;
491 driver->drv.bus = &acpi_bus_type;
492 driver->drv.owner = driver->owner;
234 493
235 return 0; 494 ret = driver_register(&driver->drv);
495 return ret;
496}
497
498EXPORT_SYMBOL(acpi_bus_register_driver);
499
500/**
501 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
502 * @driver: driver to unregister
503 *
504 * Unregisters a driver with the ACPI bus. Searches the namespace for all
505 * devices that match the driver's criteria and unbinds.
506 */
507void acpi_bus_unregister_driver(struct acpi_driver *driver)
508{
509 driver_unregister(&driver->drv);
510}
511
512EXPORT_SYMBOL(acpi_bus_unregister_driver);
513
514/* --------------------------------------------------------------------------
515 Device Enumeration
516 -------------------------------------------------------------------------- */
517acpi_status
518acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
519{
520 acpi_status status;
521 acpi_handle tmp;
522 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
523 union acpi_object *obj;
524
525 status = acpi_get_handle(handle, "_EJD", &tmp);
526 if (ACPI_FAILURE(status))
527 return status;
528
529 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
530 if (ACPI_SUCCESS(status)) {
531 obj = buffer.pointer;
532 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
533 kfree(buffer.pointer);
534 }
535 return status;
536}
537EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
538
539void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
540{
541
542 /* TBD */
543
544 return;
236} 545}
237 546
238int acpi_match_ids(struct acpi_device *device, char *ids) 547int acpi_match_ids(struct acpi_device *device, char *ids)
@@ -254,6 +563,12 @@ int acpi_match_ids(struct acpi_device *device, char *ids)
254 return -ENOENT; 563 return -ENOENT;
255} 564}
256 565
566static int acpi_bus_get_perf_flags(struct acpi_device *device)
567{
568 device->performance.state = ACPI_STATE_UNKNOWN;
569 return 0;
570}
571
257static acpi_status 572static acpi_status
258acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 573acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
259 union acpi_object *package) 574 union acpi_object *package)
@@ -338,359 +653,66 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
338 return 0; 653 return 0;
339} 654}
340 655
341/* -------------------------------------------------------------------------- 656static int acpi_bus_get_power_flags(struct acpi_device *device)
342 ACPI sysfs device file support
343 -------------------------------------------------------------------------- */
344static ssize_t acpi_eject_store(struct acpi_device *device,
345 const char *buf, size_t count);
346
347#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
348static struct acpi_device_attribute acpi_device_attr_##_name = \
349 __ATTR(_name, _mode, _show, _store)
350
351ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
352
353/**
354 * setup_sys_fs_device_files - sets up the device files under device namespace
355 * @dev: acpi_device object
356 * @func: function pointer to create or destroy the device file
357 */
358static void
359setup_sys_fs_device_files(struct acpi_device *dev,
360 acpi_device_sysfs_files * func)
361{
362 acpi_status status;
363 acpi_handle temp = NULL;
364
365 /*
366 * If device has _EJ0, 'eject' file is created that is used to trigger
367 * hot-removal function from userland.
368 */
369 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
370 if (ACPI_SUCCESS(status))
371 (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
372}
373
374static int acpi_eject_operation(acpi_handle handle, int lockable)
375{ 657{
376 struct acpi_object_list arg_list; 658 acpi_status status = 0;
377 union acpi_object arg; 659 acpi_handle handle = NULL;
378 acpi_status status = AE_OK; 660 u32 i = 0;
379
380 /*
381 * TBD: evaluate _PS3?
382 */
383
384 if (lockable) {
385 arg_list.count = 1;
386 arg_list.pointer = &arg;
387 arg.type = ACPI_TYPE_INTEGER;
388 arg.integer.value = 0;
389 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
390 }
391 661
392 arg_list.count = 1;
393 arg_list.pointer = &arg;
394 arg.type = ACPI_TYPE_INTEGER;
395 arg.integer.value = 1;
396 662
397 /* 663 /*
398 * TBD: _EJD support. 664 * Power Management Flags
399 */ 665 */
400 666 status = acpi_get_handle(device->handle, "_PSC", &handle);
401 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); 667 if (ACPI_SUCCESS(status))
402 if (ACPI_FAILURE(status)) { 668 device->power.flags.explicit_get = 1;
403 return (-ENODEV); 669 status = acpi_get_handle(device->handle, "_IRC", &handle);
404 } 670 if (ACPI_SUCCESS(status))
405 671 device->power.flags.inrush_current = 1;
406 return (0);
407}
408
409static ssize_t
410acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
411{
412 int result;
413 int ret = count;
414 int islockable;
415 acpi_status status;
416 acpi_handle handle;
417 acpi_object_type type = 0;
418
419 if ((!count) || (buf[0] != '1')) {
420 return -EINVAL;
421 }
422#ifndef FORCE_EJECT
423 if (device->driver == NULL) {
424 ret = -ENODEV;
425 goto err;
426 }
427#endif
428 status = acpi_get_type(device->handle, &type);
429 if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
430 ret = -ENODEV;
431 goto err;
432 }
433
434 islockable = device->flags.lockable;
435 handle = device->handle;
436
437 result = acpi_bus_trim(device, 1);
438
439 if (!result)
440 result = acpi_eject_operation(handle, islockable);
441
442 if (result) {
443 ret = -EBUSY;
444 }
445 err:
446 return ret;
447}
448
449/* --------------------------------------------------------------------------
450 Performance Management
451 -------------------------------------------------------------------------- */
452
453static int acpi_bus_get_perf_flags(struct acpi_device *device)
454{
455 device->performance.state = ACPI_STATE_UNKNOWN;
456 return 0;
457}
458
459/* --------------------------------------------------------------------------
460 Driver Management
461 -------------------------------------------------------------------------- */
462
463static LIST_HEAD(acpi_bus_drivers);
464
465/**
466 * acpi_bus_match - match device IDs to driver's supported IDs
467 * @device: the device that we are trying to match to a driver
468 * @driver: driver whose device id table is being checked
469 *
470 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
471 * matches the specified driver's criteria.
472 */
473static int
474acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
475{
476 if (driver && driver->ops.match)
477 return driver->ops.match(device, driver);
478 return acpi_match_ids(device, driver->ids);
479}
480
481/**
482 * acpi_bus_driver_init - add a device to a driver
483 * @device: the device to add and initialize
484 * @driver: driver for the device
485 *
486 * Used to initialize a device via its device driver. Called whenever a
487 * driver is bound to a device. Invokes the driver's add() and start() ops.
488 */
489static int
490acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
491{
492 int result = 0;
493
494
495 if (!device || !driver)
496 return -EINVAL;
497
498 if (!driver->ops.add)
499 return -ENOSYS;
500
501 result = driver->ops.add(device);
502 if (result) {
503 device->driver = NULL;
504 acpi_driver_data(device) = NULL;
505 return result;
506 }
507
508 device->driver = driver;
509 672
510 /* 673 /*
511 * TBD - Configuration Management: Assign resources to device based 674 * Enumerate supported power management states
512 * upon possible configuration and currently allocated resources.
513 */ 675 */
676 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
677 struct acpi_device_power_state *ps = &device->power.states[i];
678 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
514 679
515 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 680 /* Evaluate "_PRx" to se if power resources are referenced */
516 "Driver successfully bound to device\n")); 681 acpi_evaluate_reference(device->handle, object_name, NULL,
517 return 0; 682 &ps->resources);
518} 683 if (ps->resources.count) {
519 684 device->power.flags.power_resources = 1;
520static int acpi_start_single_object(struct acpi_device *device) 685 ps->flags.valid = 1;
521{
522 int result = 0;
523 struct acpi_driver *driver;
524
525
526 if (!(driver = device->driver))
527 return 0;
528
529 if (driver->ops.start) {
530 result = driver->ops.start(device);
531 if (result && driver->ops.remove)
532 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
533 }
534
535 return result;
536}
537
538static void acpi_driver_attach(struct acpi_driver *drv)
539{
540 struct list_head *node, *next;
541
542
543 spin_lock(&acpi_device_lock);
544 list_for_each_safe(node, next, &acpi_device_list) {
545 struct acpi_device *dev =
546 container_of(node, struct acpi_device, g_list);
547
548 if (dev->driver || !dev->status.present)
549 continue;
550 spin_unlock(&acpi_device_lock);
551
552 if (!acpi_bus_match(dev, drv)) {
553 if (!acpi_bus_driver_init(dev, drv)) {
554 acpi_start_single_object(dev);
555 atomic_inc(&drv->references);
556 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
557 "Found driver [%s] for device [%s]\n",
558 drv->name, dev->pnp.bus_id));
559 }
560 } 686 }
561 spin_lock(&acpi_device_lock);
562 }
563 spin_unlock(&acpi_device_lock);
564}
565
566static void acpi_driver_detach(struct acpi_driver *drv)
567{
568 struct list_head *node, *next;
569
570 687
571 spin_lock(&acpi_device_lock); 688 /* Evaluate "_PSx" to see if we can do explicit sets */
572 list_for_each_safe(node, next, &acpi_device_list) { 689 object_name[2] = 'S';
573 struct acpi_device *dev = 690 status = acpi_get_handle(device->handle, object_name, &handle);
574 container_of(node, struct acpi_device, g_list); 691 if (ACPI_SUCCESS(status)) {
575 692 ps->flags.explicit_set = 1;
576 if (dev->driver == drv) { 693 ps->flags.valid = 1;
577 spin_unlock(&acpi_device_lock);
578 if (drv->ops.remove)
579 drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
580 spin_lock(&acpi_device_lock);
581 dev->driver = NULL;
582 dev->driver_data = NULL;
583 atomic_dec(&drv->references);
584 } 694 }
585 }
586 spin_unlock(&acpi_device_lock);
587}
588
589/**
590 * acpi_bus_register_driver - register a driver with the ACPI bus
591 * @driver: driver being registered
592 *
593 * Registers a driver with the ACPI bus. Searches the namespace for all
594 * devices that match the driver's criteria and binds. Returns zero for
595 * success or a negative error status for failure.
596 */
597int acpi_bus_register_driver(struct acpi_driver *driver)
598{
599
600 if (acpi_disabled)
601 return -ENODEV;
602
603 spin_lock(&acpi_device_lock);
604 list_add_tail(&driver->node, &acpi_bus_drivers);
605 spin_unlock(&acpi_device_lock);
606 acpi_driver_attach(driver);
607
608 return 0;
609}
610
611EXPORT_SYMBOL(acpi_bus_register_driver);
612
613/**
614 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
615 * @driver: driver to unregister
616 *
617 * Unregisters a driver with the ACPI bus. Searches the namespace for all
618 * devices that match the driver's criteria and unbinds.
619 */
620void acpi_bus_unregister_driver(struct acpi_driver *driver)
621{
622 acpi_driver_detach(driver);
623
624 if (!atomic_read(&driver->references)) {
625 spin_lock(&acpi_device_lock);
626 list_del_init(&driver->node);
627 spin_unlock(&acpi_device_lock);
628 }
629 return;
630}
631
632EXPORT_SYMBOL(acpi_bus_unregister_driver);
633
634/**
635 * acpi_bus_find_driver - check if there is a driver installed for the device
636 * @device: device that we are trying to find a supporting driver for
637 *
638 * Parses the list of registered drivers looking for a driver applicable for
639 * the specified device.
640 */
641static int acpi_bus_find_driver(struct acpi_device *device)
642{
643 int result = 0;
644 struct list_head *node, *next;
645 695
696 /* State is valid if we have some power control */
697 if (ps->resources.count || ps->flags.explicit_set)
698 ps->flags.valid = 1;
646 699
647 spin_lock(&acpi_device_lock); 700 ps->power = -1; /* Unknown - driver assigned */
648 list_for_each_safe(node, next, &acpi_bus_drivers) { 701 ps->latency = -1; /* Unknown - driver assigned */
649 struct acpi_driver *driver =
650 container_of(node, struct acpi_driver, node);
651
652 atomic_inc(&driver->references);
653 spin_unlock(&acpi_device_lock);
654 if (!acpi_bus_match(device, driver)) {
655 result = acpi_bus_driver_init(device, driver);
656 if (!result)
657 goto Done;
658 }
659 atomic_dec(&driver->references);
660 spin_lock(&acpi_device_lock);
661 } 702 }
662 spin_unlock(&acpi_device_lock);
663 703
664 Done: 704 /* Set defaults for D0 and D3 states (always valid) */
665 return result; 705 device->power.states[ACPI_STATE_D0].flags.valid = 1;
666} 706 device->power.states[ACPI_STATE_D0].power = 100;
667 707 device->power.states[ACPI_STATE_D3].flags.valid = 1;
668/* -------------------------------------------------------------------------- 708 device->power.states[ACPI_STATE_D3].power = 0;
669 Device Enumeration
670 -------------------------------------------------------------------------- */
671 709
672acpi_status 710 /* TBD: System wake support and resource requirements. */
673acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
674{
675 acpi_status status;
676 acpi_handle tmp;
677 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
678 union acpi_object *obj;
679 711
680 status = acpi_get_handle(handle, "_EJD", &tmp); 712 device->power.state = ACPI_STATE_UNKNOWN;
681 if (ACPI_FAILURE(status))
682 return status;
683 713
684 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); 714 return 0;
685 if (ACPI_SUCCESS(status)) {
686 obj = buffer.pointer;
687 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
688 kfree(buffer.pointer);
689 }
690 return status;
691} 715}
692EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
693
694 716
695static int acpi_bus_get_flags(struct acpi_device *device) 717static int acpi_bus_get_flags(struct acpi_device *device)
696{ 718{
@@ -782,6 +804,39 @@ static void acpi_device_get_busid(struct acpi_device *device,
782 } 804 }
783} 805}
784 806
807static int
808acpi_video_bus_match(struct acpi_device *device)
809{
810 acpi_handle h_dummy1;
811 acpi_handle h_dummy2;
812 acpi_handle h_dummy3;
813
814
815 if (!device)
816 return -EINVAL;
817
818 /* Since there is no HID, CID for ACPI Video drivers, we have
819 * to check well known required nodes for each feature we support.
820 */
821
822 /* Does this device able to support video switching ? */
823 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
824 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
825 return 0;
826
827 /* Does this device able to retrieve a video ROM ? */
828 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
829 return 0;
830
831 /* Does this device able to configure which video head to be POSTed ? */
832 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
833 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
834 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
835 return 0;
836
837 return -ENODEV;
838}
839
785static void acpi_device_set_id(struct acpi_device *device, 840static void acpi_device_set_id(struct acpi_device *device,
786 struct acpi_device *parent, acpi_handle handle, 841 struct acpi_device *parent, acpi_handle handle,
787 int type) 842 int type)
@@ -812,6 +867,12 @@ static void acpi_device_set_id(struct acpi_device *device,
812 device->pnp.bus_address = info->address; 867 device->pnp.bus_address = info->address;
813 device->flags.bus_address = 1; 868 device->flags.bus_address = 1;
814 } 869 }
870
871 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
872 status = acpi_video_bus_match(device);
873 if(ACPI_SUCCESS(status))
874 hid = ACPI_VIDEO_HID;
875 }
815 break; 876 break;
816 case ACPI_BUS_TYPE_POWER: 877 case ACPI_BUS_TYPE_POWER:
817 hid = ACPI_POWER_HID; 878 hid = ACPI_POWER_HID;
@@ -933,41 +994,22 @@ static void acpi_device_get_debug_info(struct acpi_device *device,
933 994
934static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 995static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
935{ 996{
936 int result = 0;
937 struct acpi_driver *driver;
938
939
940 if (!dev) 997 if (!dev)
941 return -EINVAL; 998 return -EINVAL;
942 999
943 driver = dev->driver; 1000 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
944 1001 device_release_driver(&dev->dev);
945 if ((driver) && (driver->ops.remove)) {
946
947 if (driver->ops.stop) {
948 result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
949 if (result)
950 return result;
951 }
952
953 result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
954 if (result) {
955 return result;
956 }
957
958 atomic_dec(&dev->driver->references);
959 dev->driver = NULL;
960 acpi_driver_data(dev) = NULL;
961 }
962 1002
963 if (!rmdevice) 1003 if (!rmdevice)
964 return 0; 1004 return 0;
965 1005
1006 /*
1007 * unbind _ADR-Based Devices when hot removal
1008 */
966 if (dev->flags.bus_address) { 1009 if (dev->flags.bus_address) {
967 if ((dev->parent) && (dev->parent->ops.unbind)) 1010 if ((dev->parent) && (dev->parent->ops.unbind))
968 dev->parent->ops.unbind(dev); 1011 dev->parent->ops.unbind(dev);
969 } 1012 }
970
971 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); 1013 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
972 1014
973 return 0; 1015 return 0;
@@ -975,7 +1017,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
975 1017
976static int 1018static int
977acpi_add_single_object(struct acpi_device **child, 1019acpi_add_single_object(struct acpi_device **child,
978 struct acpi_device *parent, acpi_handle handle, int type) 1020 struct acpi_device *parent, acpi_handle handle, int type,
1021 struct acpi_bus_ops *ops)
979{ 1022{
980 int result = 0; 1023 int result = 0;
981 struct acpi_device *device = NULL; 1024 struct acpi_device *device = NULL;
@@ -992,6 +1035,8 @@ acpi_add_single_object(struct acpi_device **child,
992 1035
993 device->handle = handle; 1036 device->handle = handle;
994 device->parent = parent; 1037 device->parent = parent;
1038 device->bus_ops = *ops; /* workround for not call .start */
1039
995 1040
996 acpi_device_get_busid(device, handle, type); 1041 acpi_device_get_busid(device, handle, type);
997 1042
@@ -1078,31 +1123,16 @@ acpi_add_single_object(struct acpi_device **child,
1078 1123
1079 acpi_device_get_debug_info(device, handle, type); 1124 acpi_device_get_debug_info(device, handle, type);
1080 1125
1081 acpi_device_register(device, parent); 1126 result = acpi_device_register(device, parent);
1082 1127
1083 /* 1128 /*
1084 * Bind _ADR-Based Devices 1129 * Bind _ADR-Based Devices when hot add
1085 * -----------------------
1086 * If there's a a bus address (_ADR) then we utilize the parent's
1087 * 'bind' function (if exists) to bind the ACPI- and natively-
1088 * enumerated device representations.
1089 */ 1130 */
1090 if (device->flags.bus_address) { 1131 if (device->flags.bus_address) {
1091 if (device->parent && device->parent->ops.bind) 1132 if (device->parent && device->parent->ops.bind)
1092 device->parent->ops.bind(device); 1133 device->parent->ops.bind(device);
1093 } 1134 }
1094 1135
1095 /*
1096 * Locate & Attach Driver
1097 * ----------------------
1098 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1099 * to see if there's a driver installed for this kind of device. Note
1100 * that drivers can install before or after a device is enumerated.
1101 *
1102 * TBD: Assumes LDM provides driver hot-plug capability.
1103 */
1104 acpi_bus_find_driver(device);
1105
1106 end: 1136 end:
1107 if (!result) 1137 if (!result)
1108 *child = device; 1138 *child = device;
@@ -1188,14 +1218,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1188 1218
1189 if (ops->acpi_op_add) 1219 if (ops->acpi_op_add)
1190 status = acpi_add_single_object(&child, parent, 1220 status = acpi_add_single_object(&child, parent,
1191 chandle, type); 1221 chandle, type, ops);
1192 else 1222 else
1193 status = acpi_bus_get_device(chandle, &child); 1223 status = acpi_bus_get_device(chandle, &child);
1194 1224
1195 if (ACPI_FAILURE(status)) 1225 if (ACPI_FAILURE(status))
1196 continue; 1226 continue;
1197 1227
1198 if (ops->acpi_op_start) { 1228 if (ops->acpi_op_start && !(ops->acpi_op_add)) {
1199 status = acpi_start_single_object(child); 1229 status = acpi_start_single_object(child);
1200 if (ACPI_FAILURE(status)) 1230 if (ACPI_FAILURE(status))
1201 continue; 1231 continue;
@@ -1233,13 +1263,13 @@ acpi_bus_add(struct acpi_device **child,
1233 int result; 1263 int result;
1234 struct acpi_bus_ops ops; 1264 struct acpi_bus_ops ops;
1235 1265
1266 memset(&ops, 0, sizeof(ops));
1267 ops.acpi_op_add = 1;
1236 1268
1237 result = acpi_add_single_object(child, parent, handle, type); 1269 result = acpi_add_single_object(child, parent, handle, type, &ops);
1238 if (!result) { 1270 if (!result)
1239 memset(&ops, 0, sizeof(ops));
1240 ops.acpi_op_add = 1;
1241 result = acpi_bus_scan(*child, &ops); 1271 result = acpi_bus_scan(*child, &ops);
1242 } 1272
1243 return result; 1273 return result;
1244} 1274}
1245 1275
@@ -1325,127 +1355,35 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1325{ 1355{
1326 int result = 0; 1356 int result = 0;
1327 struct acpi_device *device = NULL; 1357 struct acpi_device *device = NULL;
1328 1358 struct acpi_bus_ops ops;
1329 1359
1330 if (!root) 1360 if (!root)
1331 return -ENODEV; 1361 return -ENODEV;
1332 1362
1363 memset(&ops, 0, sizeof(ops));
1364 ops.acpi_op_add = 1;
1365 ops.acpi_op_start = 1;
1366
1333 /* 1367 /*
1334 * Enumerate all fixed-feature devices. 1368 * Enumerate all fixed-feature devices.
1335 */ 1369 */
1336 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { 1370 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
1337 result = acpi_add_single_object(&device, acpi_root, 1371 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, 1372 NULL,
1339 ACPI_BUS_TYPE_POWER_BUTTON); 1373 ACPI_BUS_TYPE_POWER_BUTTON,
1340 if (!result) 1374 &ops);
1341 result = acpi_start_single_object(device);
1342 } 1375 }
1343 1376
1344 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { 1377 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1345 result = acpi_add_single_object(&device, acpi_root, 1378 result = acpi_add_single_object(&device, acpi_root,
1346 NULL, 1379 NULL,
1347 ACPI_BUS_TYPE_SLEEP_BUTTON); 1380 ACPI_BUS_TYPE_SLEEP_BUTTON,
1348 if (!result) 1381 &ops);
1349 result = acpi_start_single_object(device);
1350 } 1382 }
1351 1383
1352 return result; 1384 return result;
1353} 1385}
1354 1386
1355
1356static inline struct acpi_device * to_acpi_dev(struct device * dev)
1357{
1358 return container_of(dev, struct acpi_device, dev);
1359}
1360
1361
1362static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
1363{
1364 struct acpi_device * dev, * next;
1365 int result;
1366
1367 spin_lock(&acpi_device_lock);
1368 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
1369 if (dev->driver && dev->driver->ops.suspend) {
1370 spin_unlock(&acpi_device_lock);
1371 result = dev->driver->ops.suspend(dev, 0);
1372 if (result) {
1373 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
1374 acpi_device_name(dev),
1375 acpi_device_bid(dev), result);
1376 }
1377 spin_lock(&acpi_device_lock);
1378 }
1379 }
1380 spin_unlock(&acpi_device_lock);
1381 return 0;
1382}
1383
1384
1385static int acpi_device_suspend(struct device * dev, pm_message_t state)
1386{
1387 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1388
1389 /*
1390 * For now, we should only register 1 generic device -
1391 * the ACPI root device - and from there, we walk the
1392 * tree of ACPI devices to suspend each one using the
1393 * ACPI driver methods.
1394 */
1395 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1396 root_suspend(acpi_dev, state);
1397 return 0;
1398}
1399
1400
1401
1402static int root_resume(struct acpi_device * acpi_dev)
1403{
1404 struct acpi_device * dev, * next;
1405 int result;
1406
1407 spin_lock(&acpi_device_lock);
1408 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
1409 if (dev->driver && dev->driver->ops.resume) {
1410 spin_unlock(&acpi_device_lock);
1411 result = dev->driver->ops.resume(dev, 0);
1412 if (result) {
1413 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
1414 acpi_device_name(dev),
1415 acpi_device_bid(dev), result);
1416 }
1417 spin_lock(&acpi_device_lock);
1418 }
1419 }
1420 spin_unlock(&acpi_device_lock);
1421 return 0;
1422}
1423
1424
1425static int acpi_device_resume(struct device * dev)
1426{
1427 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1428
1429 /*
1430 * For now, we should only register 1 generic device -
1431 * the ACPI root device - and from there, we walk the
1432 * tree of ACPI devices to resume each one using the
1433 * ACPI driver methods.
1434 */
1435 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1436 root_resume(acpi_dev);
1437 return 0;
1438}
1439
1440
1441static struct bus_type acpi_bus_type = {
1442 .name = "acpi",
1443 .suspend = acpi_device_suspend,
1444 .resume = acpi_device_resume,
1445};
1446
1447
1448
1449static int __init acpi_scan_init(void) 1387static int __init acpi_scan_init(void)
1450{ 1388{
1451 int result; 1389 int result;
@@ -1455,9 +1393,9 @@ static int __init acpi_scan_init(void)
1455 if (acpi_disabled) 1393 if (acpi_disabled)
1456 return 0; 1394 return 0;
1457 1395
1458 result = kset_register(&acpi_namespace_kset); 1396 memset(&ops, 0, sizeof(ops));
1459 if (result < 0) 1397 ops.acpi_op_add = 1;
1460 printk(KERN_ERR PREFIX "kset_register error: %d\n", result); 1398 ops.acpi_op_start = 1;
1461 1399
1462 result = bus_register(&acpi_bus_type); 1400 result = bus_register(&acpi_bus_type);
1463 if (result) { 1401 if (result) {
@@ -1469,32 +1407,16 @@ static int __init acpi_scan_init(void)
1469 * Create the root device in the bus's device tree 1407 * Create the root device in the bus's device tree
1470 */ 1408 */
1471 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1409 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1472 ACPI_BUS_TYPE_SYSTEM); 1410 ACPI_BUS_TYPE_SYSTEM, &ops);
1473 if (result)
1474 goto Done;
1475
1476 result = acpi_start_single_object(acpi_root);
1477 if (result) 1411 if (result)
1478 goto Done; 1412 goto Done;
1479 1413
1480 acpi_root->dev.bus = &acpi_bus_type;
1481 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1482 result = device_register(&acpi_root->dev);
1483 if (result) {
1484 /* We don't want to quit even if we failed to add suspend/resume */
1485 printk(KERN_ERR PREFIX "Could not register device\n");
1486 }
1487
1488 /* 1414 /*
1489 * Enumerate devices in the ACPI namespace. 1415 * Enumerate devices in the ACPI namespace.
1490 */ 1416 */
1491 result = acpi_bus_scan_fixed(acpi_root); 1417 result = acpi_bus_scan_fixed(acpi_root);
1492 if (!result) { 1418 if (!result)
1493 memset(&ops, 0, sizeof(ops));
1494 ops.acpi_op_add = 1;
1495 ops.acpi_op_start = 1;
1496 result = acpi_bus_scan(acpi_root, &ops); 1419 result = acpi_bus_scan(acpi_root, &ops);
1497 }
1498 1420
1499 if (result) 1421 if (result)
1500 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1422 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);