lkml.org 
[lkml]   [2018]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v3 2/5] usb: assign ACPI companions for embedded USB devices
    From
    From: Dmitry Torokhov <dtor@chromium.org>

    USB devices permanently connected to USB ports may be described in ACPI
    tables and share ACPI devices with ports they are connected to. See [1]
    for details.

    This will allow us to describe sideband resources for devices, such as,
    for example, hard reset line for BT USB controllers.

    [1] https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/other-acpi-namespace-objects#acpi-namespace-hierarchy-and-adr-for-embedded-usb-devices

    Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
    Signed-off-by: Rajat Jain <rajatja@google.com> (changed how we get the usb_port)
    ---
    v3: same as v1
    v2: same as v1

    drivers/usb/core/usb-acpi.c | 44 +++++++++++++++++++++++++++++--------
    1 file changed, 35 insertions(+), 9 deletions(-)

    diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
    index 8ff73c83e8e8..9043d7242d67 100644
    --- a/drivers/usb/core/usb-acpi.c
    +++ b/drivers/usb/core/usb-acpi.c
    @@ -200,30 +200,56 @@ static struct acpi_device *
    usb_acpi_find_companion_for_device(struct usb_device *udev)
    {
    struct acpi_device *adev;
    + struct usb_port *port_dev;
    + struct usb_hub *hub;
    +
    + if (!udev->parent) {
    + /* 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);
    + }

    - if (!udev->parent)
    + hub = usb_hub_to_struct_hub(udev->parent);
    + if (!hub)
    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);
    + /*
    + * This is an embedded USB device connected to a port and such
    + * devices share port's ACPI companion.
    + */
    + port_dev = hub->ports[udev->portnum - 1];
    + return usb_acpi_get_companion_for_port(port_dev);
    }

    -
    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.
    + * The USB hierarchy like following:
    + *
    * Device (EHC1)
    * Device (HUBN)
    * Device (PR01)
    * Device (PR11)
    * Device (PR12)
    + * Device (FN12)
    + * Device (FN13)
    * Device (PR13)
    * ...
    - * So all binding process is divided into two parts. binding
    - * root hub and usb ports.
    + * where HUBN is root hub, and PRNN are USB ports and devices
    + * connected to them, and FNNN are individualk functions for
    + * connected composite USB devices. PRNN and FNNN may contain
    + * _CRS and other methods describing sideband resources for
    + * the connected device.
    + *
    + * On the kernel side both root hub and embedded USB devices are
    + * represented as instances of usb_device structure, and ports
    + * are represented as usb_port structures, so the whole process
    + * is split into 2 parts: finding companions for devices and
    + * finding companions for ports.
    + *
    + * Note that we do not handle individual functions of composite
    + * devices yet, for that we would need to assign companions to
    + * devices corresponding to USB interfaces.
    */
    if (is_usb_device(dev))
    return usb_acpi_find_companion_for_device(to_usb_device(dev));
    --
    2.19.1.1215.g8438c0b245-goog
    \
     
     \ /
      Last update: 2018-11-22 00:51    [W:3.298 / U:0.456 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site