Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcfcd409 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Marcel Holtmann
Browse files

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: default avatarDmitry Torokhov <dtor@chromium.org>
Signed-off-by: default avatarRajat Jain <rajatja@google.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: default avatarSukumar Ghorai <sukumar.ghorai@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 6317950c
Loading
Loading
Loading
Loading
+72 −61
Original line number Diff line number Diff line
@@ -139,42 +139,16 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
	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 acpi_device *adev;
	acpi_handle *parent_handle;

	/*
	 * In the ACPI DSDT table, only usb root hub and usb ports are
	 * acpi device nodes. The hierarchy like following.
	 * Device (EHC1)
	 *	Device (HUBN)
	 *		Device (PR01)
	 *			Device (PR11)
	 *			Device (PR12)
	 *			Device (PR13)
	 *			...
	 * So all binding process is divided into two parts. binding
	 * root hub and usb ports.
	 */
	if (is_usb_device(dev)) {
		udev = to_usb_device(dev);
		if (udev->parent)
			return NULL;

		/* 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;
	int port1;

	/* Get the struct usb_device point of port's hub */
		udev = to_usb_device(dev->parent->parent);
	udev = to_usb_device(port_dev->dev.parent->parent);

	/*
	 * The root hub ports' parent is the root hub. The non-root-hub
@@ -182,43 +156,80 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
	 * 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;
		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,
		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);
}

			adev = 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)
			return adev;

	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
	 * acpi device nodes. The hierarchy like following.
	 * Device (EHC1)
	 *	Device (HUBN)
	 *		Device (PR01)
	 *			Device (PR11)
	 *			Device (PR12)
	 *			Device (PR13)
	 *			...
	 * So all binding process is divided into two parts. binding
	 * root hub and usb ports.
	 */
	if (is_usb_device(dev))
		return usb_acpi_find_companion_for_device(to_usb_device(dev));
	else if (is_usb_port(dev))
		return usb_acpi_find_companion_for_port(to_usb_port(dev));

	return NULL;
}