forked from mirrors/linux
		
	ACPI / scan: Change the implementation of acpi_bus_trim()
The current acpi_bus_trim() implementation is not really straightforward and may be simplified significantly by using acpi_walk_namespace() with acpi_bus_remove() as a post-order callback. Observe that acpi_bus_remove(), as called by acpi_bus_trim(), cannot actually fail, because its first argument is guaranteed not to be NULL thanks to the acpi_bus_get_device() check in acpi_bus_trim(), so simply move the acpi_bus_get_device() check to acpi_bus_remove() and use acpi_walk_namespace() to execute it for every device under start->handle as a post-order callback. The, run it directly for start->handle itself. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
This commit is contained in:
		
							parent
							
								
									ae281795ec
								
							
						
					
					
						commit
						cecdb193c8
					
				
					 1 changed files with 15 additions and 49 deletions
				
			
		|  | @ -1374,17 +1374,20 @@ static int acpi_device_set_context(struct acpi_device *device) | ||||||
| 	return -ENODEV; | 	return -ENODEV; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int acpi_bus_remove(struct acpi_device *dev) | static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, | ||||||
|  | 				   void *not_used, void **ret_not_used) | ||||||
| { | { | ||||||
| 	if (!dev) | 	struct acpi_device *dev = NULL; | ||||||
| 		return -EINVAL; | 
 | ||||||
|  | 	if (acpi_bus_get_device(handle, &dev)) | ||||||
|  | 		return AE_OK; | ||||||
| 
 | 
 | ||||||
| 	dev->removal_type = ACPI_BUS_REMOVAL_EJECT; | 	dev->removal_type = ACPI_BUS_REMOVAL_EJECT; | ||||||
| 	device_release_driver(&dev->dev); | 	device_release_driver(&dev->dev); | ||||||
| 
 | 
 | ||||||
| 	acpi_device_unregister(dev); | 	acpi_device_unregister(dev); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return AE_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int acpi_add_single_object(struct acpi_device **child, | static int acpi_add_single_object(struct acpi_device **child, | ||||||
|  | @ -1641,51 +1644,14 @@ EXPORT_SYMBOL(acpi_bus_add); | ||||||
| 
 | 
 | ||||||
| int acpi_bus_trim(struct acpi_device *start) | int acpi_bus_trim(struct acpi_device *start) | ||||||
| { | { | ||||||
| 	acpi_status status; |  | ||||||
| 	struct acpi_device *parent, *child; |  | ||||||
| 	acpi_handle phandle, chandle; |  | ||||||
| 	acpi_object_type type; |  | ||||||
| 	u32 level = 1; |  | ||||||
| 	int err = 0; |  | ||||||
| 
 |  | ||||||
| 	parent = start; |  | ||||||
| 	phandle = start->handle; |  | ||||||
| 	child = chandle = NULL; |  | ||||||
| 
 |  | ||||||
| 	while ((level > 0) && parent && (!err)) { |  | ||||||
| 		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, |  | ||||||
| 					      chandle, &chandle); |  | ||||||
| 
 |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 		 * If this scope is exhausted then move our way back up. | 	 * Execute acpi_bus_remove() as a post-order callback to remove device | ||||||
|  | 	 * nodes in the given namespace scope. | ||||||
| 	 */ | 	 */ | ||||||
| 		if (ACPI_FAILURE(status)) { | 	acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, | ||||||
| 			level--; | 			    acpi_bus_remove, NULL, NULL); | ||||||
| 			chandle = phandle; | 	acpi_bus_remove(start->handle, 0, NULL, NULL); | ||||||
| 			acpi_get_parent(phandle, &phandle); | 	return 0; | ||||||
| 			child = parent; |  | ||||||
| 			parent = parent->parent; |  | ||||||
| 			err = acpi_bus_remove(child); |  | ||||||
| 			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; |  | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(acpi_bus_trim); | EXPORT_SYMBOL_GPL(acpi_bus_trim); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Rafael J. Wysocki
						Rafael J. Wysocki