lkml.org 
[lkml]   [2015]   [Dec]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH 2/2] usb: pci-quirks: register USB mux found on Cherrytrail SOC
    Date

    Hi,

    Heikki Krogerus <heikki.krogerus@linux.intel.com> writes:
    > Intel Braswell/Cherrytrail has an internal mux that shares
    > one USB port between USB Device Controller and xHCI. The
    > same mux is found on several SOCs from Intel, but only on
    > a few Cherrytrail based platforms the OS is expected to
    > configure it. Normally BIOS takes care of it.
    >
    > The driver for the mux is an "extcon" driver. With this we
    > only register the mux if it's detected.
    >
    > Suggested-by: Lu Baolu <baolu.lu@linux.intel.com>
    > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
    > ---
    > drivers/usb/host/pci-quirks.c | 30 +++++++++++++++++++++++++++++-
    > 1 file changed, 29 insertions(+), 1 deletion(-)
    >
    > diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
    > index f940056..4e3016a 100644
    > --- a/drivers/usb/host/pci-quirks.c
    > +++ b/drivers/usb/host/pci-quirks.c
    > @@ -16,6 +16,7 @@
    > #include <linux/export.h>
    > #include <linux/acpi.h>
    > #include <linux/dmi.h>
    > +#include <linux/extcon/intel_usb_mux.h>
    > #include "pci-quirks.h"
    > #include "xhci-ext-caps.h"
    >
    > @@ -1029,9 +1030,36 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
    > writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
    >
    > hc_init:
    > - if (pdev->vendor == PCI_VENDOR_ID_INTEL)
    > + if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
    > usb_enable_intel_xhci_ports(pdev);
    >
    > + /*
    > + * Initialize the internal mux that shares a port between USB
    > + * Device Controller and xHCI on platforms that have it.
    > + */
    > +#define XHCI_INTEL_VENDOR_CAPS 192
    > +#define XHCI_INTEL_USB_MUX_OFFSET 0x80d8
    > + ext_cap_offset = xhci_find_next_cap_offset(base,
    > + XHCI_HCC_PARAMS_OFFSET);
    > + ext_cap_offset = xhci_find_ext_cap_by_id(base, ext_cap_offset,
    > + XHCI_INTEL_VENDOR_CAPS);
    > + if (ext_cap_offset) {
    > + struct intel_usb_mux *mux;
    > + struct resource r;
    > +
    > + r.start = pci_resource_start(pdev, 0) +
    > + XHCI_INTEL_USB_MUX_OFFSET;
    > + r.end = r.start + 8;
    > + r.flags = IORESOURCE_MEM;
    > +
    > + mux = intel_usb_mux_register(&pdev->dev, &r);
    > + if (IS_ERR(mux) && PTR_ERR(mux) == -ENOTSUPP)
    > + dev_dbg(&pdev->dev, "USB mux not supported\n");
    > + else if (IS_ERR(mux))
    > + dev_err(&pdev->dev, "failed to register mux\n");

    IMHO, this should be creating a child device instead of calling
    intel_usb_mux_register() directly. That way, your mux driver could
    actually _be_ a driver. Seems like all you need to do from this point is
    a register a simple platform_device which is a child of xhci, see
    platform_device_register_simple() for how to do this.

    Or rather, platform_device_register_rsndata() passing xhci's device
    pointer as parent.

    --
    balbi
    [unhandled content-type:application/pgp-signature]
    \
     
     \ /
      Last update: 2015-12-01 22:01    [W:2.514 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site