diff options
Diffstat (limited to 'drivers/acpi/glue.c')
| -rw-r--r-- | drivers/acpi/glue.c | 115 | 
1 files changed, 47 insertions, 68 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 01551840d236..40a84cc6740c 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -18,9 +18,14 @@  #define ACPI_GLUE_DEBUG	0  #if ACPI_GLUE_DEBUG -#define DBG(x...) printk(PREFIX x) +#define DBG(fmt, ...)						\ +	printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__)  #else -#define DBG(x...) do { } while(0) +#define DBG(fmt, ...)						\ +do {								\ +	if (0)							\ +		printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__);	\ +} while (0)  #endif  static LIST_HEAD(bus_type_list);  static DECLARE_RWSEM(bus_type_sem); @@ -31,12 +36,11 @@ int register_acpi_bus_type(struct acpi_bus_type *type)  {  	if (acpi_disabled)  		return -ENODEV; -	if (type && type->bus && type->find_device) { +	if (type && type->match && type->find_device) {  		down_write(&bus_type_sem);  		list_add_tail(&type->list, &bus_type_list);  		up_write(&bus_type_sem); -		printk(KERN_INFO PREFIX "bus type %s registered\n", -		       type->bus->name); +		printk(KERN_INFO PREFIX "bus type %s registered\n", type->name);  		return 0;  	}  	return -ENODEV; @@ -51,21 +55,21 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)  		down_write(&bus_type_sem);  		list_del_init(&type->list);  		up_write(&bus_type_sem); -		printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", -		       type->bus->name); +		printk(KERN_INFO PREFIX "bus type %s unregistered\n", +		       type->name);  		return 0;  	}  	return -ENODEV;  }  EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)  {  	struct acpi_bus_type *tmp, *ret = NULL;  	down_read(&bus_type_sem);  	list_for_each_entry(tmp, &bus_type_list, list) { -		if (tmp->bus == type) { +		if (tmp->match(dev)) {  			ret = tmp;  			break;  		} @@ -74,56 +78,31 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)  	return ret;  } -static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) -{ -	struct acpi_bus_type *tmp; -	int ret = -ENODEV; - -	down_read(&bus_type_sem); -	list_for_each_entry(tmp, &bus_type_list, list) { -		if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) { -			ret = 0; -			break; -		} -	} -	up_read(&bus_type_sem); -	return ret; -} - -/* Get device's handler per its address under its parent */ -struct acpi_find_child { -	acpi_handle handle; -	u64 address; -}; - -static acpi_status -do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) +static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, +				      void *addr_p, void **ret_p)  { +	unsigned long long addr;  	acpi_status status; -	struct acpi_device_info *info; -	struct acpi_find_child *find = context; - -	status = acpi_get_object_info(handle, &info); -	if (ACPI_SUCCESS(status)) { -		if ((info->address == find->address) -			&& (info->valid & ACPI_VALID_ADR)) -			find->handle = handle; -		kfree(info); + +	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); +	if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) { +		*ret_p = handle; +		return AE_CTRL_TERMINATE;  	}  	return AE_OK;  }  acpi_handle acpi_get_child(acpi_handle parent, u64 address)  { -	struct acpi_find_child find = { NULL, address }; +	void *ret = NULL;  	if (!parent)  		return NULL; -	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, -			    1, do_acpi_find_child, NULL, &find, NULL); -	return find.handle; -} +	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL, +			    do_acpi_find_child, &address, &ret); +	return (acpi_handle)ret; +}  EXPORT_SYMBOL(acpi_get_child);  static int acpi_bind_one(struct device *dev, acpi_handle handle) @@ -262,37 +241,31 @@ err:  static int acpi_platform_notify(struct device *dev)  { -	struct acpi_bus_type *type; +	struct acpi_bus_type *type = acpi_get_bus_type(dev);  	acpi_handle handle; -	int ret = -EINVAL; +	int ret;  	ret = acpi_bind_one(dev, NULL); -	if (!ret) -		goto out; - -	if (!dev->bus || !dev->parent) { -		/* bridge devices genernally haven't bus or parent */ -		ret = acpi_find_bridge_device(dev, &handle); -		goto end; -	} -	type = acpi_get_bus_type(dev->bus); -	if (!type) { -		DBG("No ACPI bus support for %s\n", dev_name(dev)); -		ret = -EINVAL; -		goto end; +	if (ret && type) { +		ret = type->find_device(dev, &handle); +		if (ret) { +			DBG("Unable to get handle for %s\n", dev_name(dev)); +			goto out; +		} +		ret = acpi_bind_one(dev, handle); +		if (ret) +			goto out;  	} -	if ((ret = type->find_device(dev, &handle)) != 0) -		DBG("Can't get handler for %s\n", dev_name(dev)); - end: -	if (!ret) -		acpi_bind_one(dev, handle); + +	if (type && type->setup) +		type->setup(dev);   out:  #if ACPI_GLUE_DEBUG  	if (!ret) {  		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; -		acpi_get_name(dev->acpi_handle, ACPI_FULL_PATHNAME, &buffer); +		acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer);  		DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);  		kfree(buffer.pointer);  	} else @@ -304,6 +277,12 @@ static int acpi_platform_notify(struct device *dev)  static int acpi_platform_notify_remove(struct device *dev)  { +	struct acpi_bus_type *type; + +	type = acpi_get_bus_type(dev); +	if (type && type->cleanup) +		type->cleanup(dev); +  	acpi_unbind_one(dev);  	return 0;  }  |