forked from mirrors/linux
		
	usb: split code locating ACPI companion into port and device
In preparation for handling embedded USB devices let's split usb_acpi_find_companion() into usb_acpi_find_companion_for_device() and usb_acpi_find_companion_for_port(). Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Signed-off-by: Rajat Jain <rajatja@google.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Tested-by: Sukumar Ghorai <sukumar.ghorai@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
		
							parent
							
								
									6317950c1b
								
							
						
					
					
						commit
						bcfcd409d4
					
				
					 1 changed files with 72 additions and 61 deletions
				
			
		| 
						 | 
					@ -139,12 +139,79 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
 | 
				
			||||||
	return acpi_find_child_device(parent, raw, false);
 | 
						return acpi_find_child_device(parent, raw, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 | 
					static struct acpi_device *
 | 
				
			||||||
 | 
					usb_acpi_get_companion_for_port(struct usb_port *port_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct usb_device *udev;
 | 
						struct usb_device *udev;
 | 
				
			||||||
	struct acpi_device *adev;
 | 
						struct acpi_device *adev;
 | 
				
			||||||
	acpi_handle *parent_handle;
 | 
						acpi_handle *parent_handle;
 | 
				
			||||||
 | 
						int port1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get the struct usb_device point of port's hub */
 | 
				
			||||||
 | 
						udev = to_usb_device(port_dev->dev.parent->parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * The root hub ports' parent is the root hub. The non-root-hub
 | 
				
			||||||
 | 
						 * ports' parent is the parent hub port which the hub is
 | 
				
			||||||
 | 
						 * connected to.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!udev->parent) {
 | 
				
			||||||
 | 
							adev = ACPI_COMPANION(&udev->dev);
 | 
				
			||||||
 | 
							port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus),
 | 
				
			||||||
 | 
											     port_dev->portnum);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							parent_handle = usb_get_hub_port_acpi_handle(udev->parent,
 | 
				
			||||||
 | 
												     udev->portnum);
 | 
				
			||||||
 | 
							if (!parent_handle)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							acpi_bus_get_device(parent_handle, &adev);
 | 
				
			||||||
 | 
							port1 = port_dev->portnum;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return usb_acpi_find_port(adev, port1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct acpi_device *
 | 
				
			||||||
 | 
					usb_acpi_find_companion_for_port(struct usb_port *port_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acpi_device *adev;
 | 
				
			||||||
 | 
						struct acpi_pld_info *pld;
 | 
				
			||||||
 | 
						acpi_handle *handle;
 | 
				
			||||||
 | 
						acpi_status status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev = usb_acpi_get_companion_for_port(port_dev);
 | 
				
			||||||
 | 
						if (!adev)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handle = adev->handle;
 | 
				
			||||||
 | 
						status = acpi_get_physical_device_location(handle, &pld);
 | 
				
			||||||
 | 
						if (!ACPI_FAILURE(status) && pld) {
 | 
				
			||||||
 | 
							port_dev->location = USB_ACPI_LOCATION_VALID
 | 
				
			||||||
 | 
								| pld->group_token << 8 | pld->group_position;
 | 
				
			||||||
 | 
							port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
 | 
				
			||||||
 | 
							ACPI_FREE(pld);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return adev;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct acpi_device *
 | 
				
			||||||
 | 
					usb_acpi_find_companion_for_device(struct usb_device *udev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acpi_device *adev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!udev->parent)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* root hub is only child (_ADR=0) under its parent, the HC */
 | 
				
			||||||
 | 
						adev = ACPI_COMPANION(udev->dev.parent);
 | 
				
			||||||
 | 
						return acpi_find_child_device(adev, 0, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * In the ACPI DSDT table, only usb root hub and usb ports are
 | 
						 * In the ACPI DSDT table, only usb root hub and usb ports are
 | 
				
			||||||
	 * acpi device nodes. The hierarchy like following.
 | 
						 * acpi device nodes. The hierarchy like following.
 | 
				
			||||||
| 
						 | 
					@ -158,66 +225,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 | 
				
			||||||
	 * So all binding process is divided into two parts. binding
 | 
						 * So all binding process is divided into two parts. binding
 | 
				
			||||||
	 * root hub and usb ports.
 | 
						 * root hub and usb ports.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (is_usb_device(dev)) {
 | 
						if (is_usb_device(dev))
 | 
				
			||||||
		udev = to_usb_device(dev);
 | 
							return usb_acpi_find_companion_for_device(to_usb_device(dev));
 | 
				
			||||||
		if (udev->parent)
 | 
						else if (is_usb_port(dev))
 | 
				
			||||||
			return NULL;
 | 
							return usb_acpi_find_companion_for_port(to_usb_port(dev));
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* root hub is only child (_ADR=0) under its parent, the HC */
 | 
					 | 
				
			||||||
		adev = ACPI_COMPANION(dev->parent);
 | 
					 | 
				
			||||||
		return acpi_find_child_device(adev, 0, false);
 | 
					 | 
				
			||||||
	} else if (is_usb_port(dev)) {
 | 
					 | 
				
			||||||
		struct usb_port *port_dev = to_usb_port(dev);
 | 
					 | 
				
			||||||
		int port1 = port_dev->portnum;
 | 
					 | 
				
			||||||
		struct acpi_pld_info *pld;
 | 
					 | 
				
			||||||
		acpi_handle *handle;
 | 
					 | 
				
			||||||
		acpi_status status;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Get the struct usb_device point of port's hub */
 | 
					 | 
				
			||||||
		udev = to_usb_device(dev->parent->parent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * The root hub ports' parent is the root hub. The non-root-hub
 | 
					 | 
				
			||||||
		 * ports' parent is the parent hub port which the hub is
 | 
					 | 
				
			||||||
		 * connected to.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (!udev->parent) {
 | 
					 | 
				
			||||||
			struct usb_hcd *hcd = bus_to_hcd(udev->bus);
 | 
					 | 
				
			||||||
			int raw;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			raw = usb_hcd_find_raw_port_number(hcd, port1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev),
 | 
					 | 
				
			||||||
						  raw);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!adev)
 | 
					 | 
				
			||||||
				return NULL;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			parent_handle =
 | 
					 | 
				
			||||||
				usb_get_hub_port_acpi_handle(udev->parent,
 | 
					 | 
				
			||||||
				udev->portnum);
 | 
					 | 
				
			||||||
			if (!parent_handle)
 | 
					 | 
				
			||||||
				return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			acpi_bus_get_device(parent_handle, &adev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			adev = usb_acpi_find_port(adev, port1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!adev)
 | 
					 | 
				
			||||||
				return NULL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		handle = adev->handle;
 | 
					 | 
				
			||||||
		status = acpi_get_physical_device_location(handle, &pld);
 | 
					 | 
				
			||||||
		if (ACPI_FAILURE(status) || !pld)
 | 
					 | 
				
			||||||
			return adev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		port_dev->location = USB_ACPI_LOCATION_VALID
 | 
					 | 
				
			||||||
			| pld->group_token << 8 | pld->group_position;
 | 
					 | 
				
			||||||
		port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
 | 
					 | 
				
			||||||
		ACPI_FREE(pld);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return adev;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue