X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fscan.c;h=a0ab828b2cc5fc589335fe9ffe1c1462985288eb;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=698a1540e3033ce1960d4c72a45f3a8177397d94;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 698a1540e..a0ab828b2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -114,8 +113,6 @@ static struct kset acpi_namespace_kset = { static void acpi_device_register(struct acpi_device *device, struct acpi_device *parent) { - int err; - /* * Linkage * ------- @@ -141,14 +138,11 @@ static void acpi_device_register(struct acpi_device *device, device->kobj.parent = &parent->kobj; device->kobj.ktype = &ktype_acpi_ns; device->kobj.kset = &acpi_namespace_kset; - err = kobject_register(&device->kobj); - if (err < 0) - printk(KERN_WARNING "%s: kobject_register error: %d\n", - __FUNCTION__, err); + kobject_register(&device->kobj); create_sysfs_device_files(device); } -static void acpi_device_unregister(struct acpi_device *device, int type) +static int acpi_device_unregister(struct acpi_device *device, int type) { spin_lock(&acpi_device_lock); if (device->parent) { @@ -164,14 +158,16 @@ static void acpi_device_unregister(struct acpi_device *device, int type) acpi_detach_data(device->handle, acpi_bus_data_handler); remove_sysfs_device_files(device); kobject_unregister(&device->kobj); + return 0; } void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) { + ACPI_FUNCTION_TRACE("acpi_bus_data_handler"); /* TBD */ - return; + return_VOID; } static int acpi_bus_get_power_flags(struct acpi_device *device) @@ -180,6 +176,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) acpi_handle handle = NULL; u32 i = 0; + ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags"); /* * Power Management Flags @@ -232,14 +229,17 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) device->power.state = ACPI_STATE_UNKNOWN; - return 0; + return_VALUE(0); } int acpi_match_ids(struct acpi_device *device, char *ids) { + int error = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + if (device->flags.hardware_id) if (strstr(ids, device->pnp.hardware_id)) - return 0; + goto Done; if (device->flags.compatible_ids) { struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; @@ -248,10 +248,15 @@ int acpi_match_ids(struct acpi_device *device, char *ids) /* compare multiple _CID entries against driver ids */ for (i = 0; i < cid_list->count; i++) { if (strstr(ids, cid_list->id[i].value)) - return 0; + goto Done; } } - return -ENOENT; + error = -ENOENT; + + Done: + if (buffer.pointer) + acpi_os_free(buffer.pointer); + return error; } static acpi_status @@ -310,22 +315,24 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *package = NULL; + ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags"); /* _PRW */ status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n")); goto end; } 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")); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error extracting _PRW package\n")); goto end; } - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); device->wakeup.flags.valid = 1; /* Power button, Lid switch always enable wakeup */ @@ -335,7 +342,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) end: if (ACPI_FAILURE(status)) device->flags.wake_capable = 0; - return 0; + return_VALUE(0); } /* -------------------------------------------------------------------------- @@ -434,7 +441,10 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count) islockable = device->flags.lockable; handle = device->handle; - result = acpi_bus_trim(device, 1); + if (type == ACPI_TYPE_PROCESSOR) + result = acpi_bus_trim(device, 0); + else + result = acpi_bus_trim(device, 1); if (!result) result = acpi_eject_operation(handle, islockable); @@ -461,6 +471,7 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device) -------------------------------------------------------------------------- */ static LIST_HEAD(acpi_bus_drivers); +static DECLARE_MUTEX(acpi_bus_drivers_lock); /** * acpi_bus_match - match device IDs to driver's supported IDs @@ -491,18 +502,19 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) { int result = 0; + ACPI_FUNCTION_TRACE("acpi_bus_driver_init"); if (!device || !driver) - return -EINVAL; + return_VALUE(-EINVAL); if (!driver->ops.add) - return -ENOSYS; + return_VALUE(-ENOSYS); result = driver->ops.add(device); if (result) { device->driver = NULL; acpi_driver_data(device) = NULL; - return result; + return_VALUE(result); } device->driver = driver; @@ -514,7 +526,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); - return 0; + return_VALUE(0); } static int acpi_start_single_object(struct acpi_device *device) @@ -522,9 +534,10 @@ static int acpi_start_single_object(struct acpi_device *device) int result = 0; struct acpi_driver *driver; + ACPI_FUNCTION_TRACE("acpi_start_single_object"); if (!(driver = device->driver)) - return 0; + return_VALUE(0); if (driver->ops.start) { result = driver->ops.start(device); @@ -532,13 +545,15 @@ static int acpi_start_single_object(struct acpi_device *device) driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); } - return result; + return_VALUE(result); } -static void acpi_driver_attach(struct acpi_driver *drv) +static int acpi_driver_attach(struct acpi_driver *drv) { struct list_head *node, *next; + int count = 0; + ACPI_FUNCTION_TRACE("acpi_driver_attach"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_device_list) { @@ -553,6 +568,7 @@ static void acpi_driver_attach(struct acpi_driver *drv) if (!acpi_bus_driver_init(dev, drv)) { acpi_start_single_object(dev); atomic_inc(&drv->references); + count++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", drv->name, dev->pnp.bus_id)); @@ -561,12 +577,14 @@ static void acpi_driver_attach(struct acpi_driver *drv) spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); + return_VALUE(count); } -static void acpi_driver_detach(struct acpi_driver *drv) +static int acpi_driver_detach(struct acpi_driver *drv) { struct list_head *node, *next; + ACPI_FUNCTION_TRACE("acpi_driver_detach"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_device_list) { @@ -584,6 +602,7 @@ static void acpi_driver_detach(struct acpi_driver *drv) } } spin_unlock(&acpi_device_lock); + return_VALUE(0); } /** @@ -591,21 +610,28 @@ static void acpi_driver_detach(struct acpi_driver *drv) * @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. + * devices that match the driver's criteria and binds. Returns the + * number of devices that were claimed by the driver, or a negative + * error status for failure. */ int acpi_bus_register_driver(struct acpi_driver *driver) { + int count; + + ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); if (acpi_disabled) - return -ENODEV; + return_VALUE(-ENODEV); + + if (!driver) + return_VALUE(-EINVAL); spin_lock(&acpi_device_lock); list_add_tail(&driver->node, &acpi_bus_drivers); spin_unlock(&acpi_device_lock); - acpi_driver_attach(driver); + count = acpi_driver_attach(driver); - return 0; + return_VALUE(count); } EXPORT_SYMBOL(acpi_bus_register_driver); @@ -617,16 +643,23 @@ EXPORT_SYMBOL(acpi_bus_register_driver); * 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) +int acpi_bus_unregister_driver(struct acpi_driver *driver) { - acpi_driver_detach(driver); + int error = 0; - if (!atomic_read(&driver->references)) { - spin_lock(&acpi_device_lock); - list_del_init(&driver->node); - spin_unlock(&acpi_device_lock); - } - return; + ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver"); + + if (driver) { + acpi_driver_detach(driver); + + if (!atomic_read(&driver->references)) { + spin_lock(&acpi_device_lock); + list_del_init(&driver->node); + spin_unlock(&acpi_device_lock); + } + } else + error = -EINVAL; + return_VALUE(error); } EXPORT_SYMBOL(acpi_bus_unregister_driver); @@ -643,6 +676,7 @@ static int acpi_bus_find_driver(struct acpi_device *device) int result = 0; struct list_head *node, *next; + ACPI_FUNCTION_TRACE("acpi_bus_find_driver"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_bus_drivers) { @@ -662,41 +696,19 @@ static int acpi_bus_find_driver(struct acpi_device *device) spin_unlock(&acpi_device_lock); Done: - return result; + return_VALUE(result); } /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ -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; - status = acpi_get_handle(NULL, obj->string.pointer, ejd); - kfree(buffer.pointer); - } - return status; -} -EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); - - static int acpi_bus_get_flags(struct acpi_device *device) { acpi_status status = AE_OK; acpi_handle temp = NULL; + ACPI_FUNCTION_TRACE("acpi_bus_get_flags"); /* Presence of _STA indicates 'dynamic_status' */ status = acpi_get_handle(device->handle, "_STA", &temp); @@ -742,7 +754,7 @@ static int acpi_bus_get_flags(struct acpi_device *device) /* TBD: Peformance management */ - return 0; + return_VALUE(0); } static void acpi_device_get_busid(struct acpi_device *device, @@ -860,7 +872,7 @@ static void acpi_device_set_id(struct acpi_device *device, printk(KERN_ERR "Memory allocation error\n"); } - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); } static int acpi_device_set_context(struct acpi_device *device, int type) @@ -936,9 +948,10 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) int result = 0; struct acpi_driver *driver; + ACPI_FUNCTION_TRACE("acpi_bus_remove"); if (!dev) - return -EINVAL; + return_VALUE(-EINVAL); driver = dev->driver; @@ -947,12 +960,12 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) if (driver->ops.stop) { result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT); if (result) - return result; + return_VALUE(result); } result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT); if (result) { - return result; + return_VALUE(result); } atomic_dec(&dev->driver->references); @@ -961,7 +974,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) } if (!rmdevice) - return 0; + return_VALUE(0); if (dev->flags.bus_address) { if ((dev->parent) && (dev->parent->ops.unbind)) @@ -970,7 +983,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); - return 0; + return_VALUE(0); } static int @@ -980,14 +993,15 @@ acpi_add_single_object(struct acpi_device **child, int result = 0; struct acpi_device *device = NULL; + ACPI_FUNCTION_TRACE("acpi_add_single_object"); if (!child) - return -EINVAL; + return_VALUE(-EINVAL); device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL); if (!device) { - printk(KERN_ERR PREFIX "Memory allocation error\n"); - return -ENOMEM; + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); + return_VALUE(-ENOMEM); } memset(device, 0, sizeof(struct acpi_device)); @@ -1112,7 +1126,7 @@ acpi_add_single_object(struct acpi_device **child, kfree(device); } - return result; + return_VALUE(result); } static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) @@ -1125,9 +1139,10 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) acpi_object_type type = 0; u32 level = 1; + ACPI_FUNCTION_TRACE("acpi_bus_scan"); if (!start) - return -EINVAL; + return_VALUE(-EINVAL); parent = start; phandle = start->handle; @@ -1224,7 +1239,7 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) } } - return 0; + return_VALUE(0); } int @@ -1234,6 +1249,7 @@ acpi_bus_add(struct acpi_device **child, int result; struct acpi_bus_ops ops; + ACPI_FUNCTION_TRACE("acpi_bus_add"); result = acpi_add_single_object(child, parent, handle, type); if (!result) { @@ -1241,7 +1257,7 @@ acpi_bus_add(struct acpi_device **child, ops.acpi_op_add = 1; result = acpi_bus_scan(*child, &ops); } - return result; + return_VALUE(result); } EXPORT_SYMBOL(acpi_bus_add); @@ -1251,9 +1267,10 @@ int acpi_bus_start(struct acpi_device *device) int result; struct acpi_bus_ops ops; + ACPI_FUNCTION_TRACE("acpi_bus_start"); if (!device) - return -EINVAL; + return_VALUE(-EINVAL); result = acpi_start_single_object(device); if (!result) { @@ -1261,7 +1278,7 @@ int acpi_bus_start(struct acpi_device *device) ops.acpi_op_start = 1; result = acpi_bus_scan(device, &ops); } - return result; + return_VALUE(result); } EXPORT_SYMBOL(acpi_bus_start); @@ -1327,9 +1344,10 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) int result = 0; struct acpi_device *device = NULL; + ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed"); if (!root) - return -ENODEV; + return_VALUE(-ENODEV); /* * Enumerate all fixed-feature devices. @@ -1350,121 +1368,20 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) result = acpi_start_single_object(device); } - return result; -} - - -static inline struct acpi_device * to_acpi_dev(struct device * dev) -{ - return container_of(dev, struct acpi_device, dev); -} - - -static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state) -{ - struct acpi_device * dev, * next; - int result; - - spin_lock(&acpi_device_lock); - list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) { - if (dev->driver && dev->driver->ops.suspend) { - spin_unlock(&acpi_device_lock); - result = dev->driver->ops.suspend(dev, 0); - if (result) { - printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n", - acpi_device_name(dev), - acpi_device_bid(dev), result); - } - spin_lock(&acpi_device_lock); - } - } - spin_unlock(&acpi_device_lock); - return 0; -} - - -static int acpi_device_suspend(struct device * dev, pm_message_t state) -{ - struct acpi_device * acpi_dev = to_acpi_dev(dev); - - /* - * For now, we should only register 1 generic device - - * the ACPI root device - and from there, we walk the - * tree of ACPI devices to suspend each one using the - * ACPI driver methods. - */ - if (acpi_dev->handle == ACPI_ROOT_OBJECT) - root_suspend(acpi_dev, state); - return 0; -} - - - -static int root_resume(struct acpi_device * acpi_dev) -{ - struct acpi_device * dev, * next; - int result; - - spin_lock(&acpi_device_lock); - list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) { - if (dev->driver && dev->driver->ops.resume) { - spin_unlock(&acpi_device_lock); - result = dev->driver->ops.resume(dev, 0); - if (result) { - printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n", - acpi_device_name(dev), - acpi_device_bid(dev), result); - } - spin_lock(&acpi_device_lock); - } - } - spin_unlock(&acpi_device_lock); - return 0; -} - - -static int acpi_device_resume(struct device * dev) -{ - struct acpi_device * acpi_dev = to_acpi_dev(dev); - - /* - * For now, we should only register 1 generic device - - * the ACPI root device - and from there, we walk the - * tree of ACPI devices to resume each one using the - * ACPI driver methods. - */ - if (acpi_dev->handle == ACPI_ROOT_OBJECT) - root_resume(acpi_dev); - return 0; + return_VALUE(result); } - -static struct bus_type acpi_bus_type = { - .name = "acpi", - .suspend = acpi_device_suspend, - .resume = acpi_device_resume, -}; - - - static int __init acpi_scan_init(void) { int result; struct acpi_bus_ops ops; + ACPI_FUNCTION_TRACE("acpi_scan_init"); if (acpi_disabled) - return 0; - - result = kset_register(&acpi_namespace_kset); - if (result < 0) - printk(KERN_ERR PREFIX "kset_register error: %d\n", result); + return_VALUE(0); - 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\n"); - } + kset_register(&acpi_namespace_kset); /* * Create the root device in the bus's device tree @@ -1475,16 +1392,6 @@ static int __init acpi_scan_init(void) goto Done; result = acpi_start_single_object(acpi_root); - if (result) - goto Done; - - acpi_root->dev.bus = &acpi_bus_type; - snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name); - result = device_register(&acpi_root->dev); - if (result) { - /* We don't want to quit even if we failed to add suspend/resume */ - printk(KERN_ERR PREFIX "Could not register device\n"); - } /* * Enumerate devices in the ACPI namespace. @@ -1501,7 +1408,7 @@ static int __init acpi_scan_init(void) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); Done: - return result; + return_VALUE(result); } subsys_initcall(acpi_scan_init);