mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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;
 | 
						 * Execute acpi_bus_remove() as a post-order callback to remove device
 | 
				
			||||||
	acpi_handle phandle, chandle;
 | 
						 * nodes in the given namespace scope.
 | 
				
			||||||
	acpi_object_type type;
 | 
						 */
 | 
				
			||||||
	u32 level = 1;
 | 
						acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
 | 
				
			||||||
	int err = 0;
 | 
								    acpi_bus_remove, NULL, NULL);
 | 
				
			||||||
 | 
						acpi_bus_remove(start->handle, 0, NULL, NULL);
 | 
				
			||||||
	parent = start;
 | 
						return 0;
 | 
				
			||||||
	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.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (ACPI_FAILURE(status)) {
 | 
					 | 
				
			||||||
			level--;
 | 
					 | 
				
			||||||
			chandle = phandle;
 | 
					 | 
				
			||||||
			acpi_get_parent(phandle, &phandle);
 | 
					 | 
				
			||||||
			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