From: Heikki Krogerus <heikki.krogerus@linux.intel.com> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Hans de Goede <hdegoede@redhat.com> Cc: Darren Hart <dvhart@infradead.org>, Andy Shevchenko <andy@infradead.org>, MyungJoo Ham <myungjoo.ham@samsung.com>, Chanwoo Choi <cw00.choi@samsung.com>, Mathias Nyman <mathias.nyman@intel.com>, Guenter Roeck <linux@roeck-us.net>, Jun Li <jun.li@nxp.com>, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [PATCH v9 08/12] xhci: Add Intel extended cap / otg phy mux handling Date: Tue, 20 Mar 2018 15:57:09 +0300 [thread overview] Message-ID: <20180320125713.85465-9-heikki.krogerus@linux.intel.com> (raw) In-Reply-To: <20180320125713.85465-1-heikki.krogerus@linux.intel.com> From: Hans de Goede <hdegoede@redhat.com> The xHCI controller on various Intel SoCs has an extended cap mmio-range which contains registers to control the muxing to the xHCI (host mode) or the dwc3 (device mode) and vbus-detection for the otg usb-phy. Having a role-sw driver included in the xHCI code (under drivers/usb/host) is not desirable. So this commit adds a simple handler for this extended capability, which creates a platform device with the caps mmio region as resource, this allows us to write a separate platform role-sw driver for the role-switch. Note this commit adds a call to the new xhci_ext_cap_init() function to xhci_pci_probe(), it is added here because xhci_ext_cap_init() must be called only once. If in the future we also want to handle ext-caps on non pci xHCI HCDs from xhci_ext_cap_init() a call to it should also be added to other bus probe paths. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> --- Changes in v4: -Add Andy's Reviewed-by Changes in v2: -Use SPDX license header -Various small style cleanups / changes -Add Heikki's Reviewed-by Changes from some time ago when this patch was part of another patch-set: -Check xHCI controller PCI device-id instead of only checking for the Intel Extended capability ID, as the Extended capability ID is used on other model Intel xHCI controllers too -Add a new generic xhci_ext_cap_init() function and handle the new XHCI_INTEL_CHT_USB_MUX quirk there. -Stop using Cherry Trail / CHT in various places as other Intel SoCs (e.g. Broxton / Apollo Lake) also have this --- drivers/usb/host/Makefile | 2 +- drivers/usb/host/xhci-ext-caps.c | 90 ++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-ext-caps.h | 2 + drivers/usb/host/xhci-pci.c | 5 +++ drivers/usb/host/xhci.h | 2 + 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/xhci-ext-caps.c diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4ede4ce12366..8a8cffe0b445 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -11,7 +11,7 @@ fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o -xhci-hcd-y := xhci.o xhci-mem.o +xhci-hcd-y := xhci.o xhci-mem.o xhci-ext-caps.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o xhci-hcd-y += xhci-trace.o diff --git a/drivers/usb/host/xhci-ext-caps.c b/drivers/usb/host/xhci-ext-caps.c new file mode 100644 index 000000000000..399113f9fc5c --- /dev/null +++ b/drivers/usb/host/xhci-ext-caps.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * XHCI extended capability handling + * + * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com> + */ + +#include <linux/platform_device.h> +#include "xhci.h" + +#define USB_SW_DRV_NAME "intel_xhci_usb_sw" +#define USB_SW_RESOURCE_SIZE 0x400 + +static void xhci_intel_unregister_pdev(void *arg) +{ + platform_device_unregister(arg); +} + +static int xhci_create_intel_xhci_sw_pdev(struct xhci_hcd *xhci, u32 cap_offset) +{ + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct device *dev = hcd->self.controller; + struct platform_device *pdev; + struct resource res = { 0, }; + int ret; + + pdev = platform_device_alloc(USB_SW_DRV_NAME, PLATFORM_DEVID_NONE); + if (!pdev) { + xhci_err(xhci, "couldn't allocate %s platform device\n", + USB_SW_DRV_NAME); + return -ENOMEM; + } + + res.start = hcd->rsrc_start + cap_offset; + res.end = res.start + USB_SW_RESOURCE_SIZE - 1; + res.name = USB_SW_DRV_NAME; + res.flags = IORESOURCE_MEM; + + ret = platform_device_add_resources(pdev, &res, 1); + if (ret) { + dev_err(dev, "couldn't add resources to intel_xhci_usb_sw pdev\n"); + platform_device_put(pdev); + return ret; + } + + pdev->dev.parent = dev; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(dev, "couldn't register intel_xhci_usb_sw pdev\n"); + platform_device_put(pdev); + return ret; + } + + ret = devm_add_action_or_reset(dev, xhci_intel_unregister_pdev, pdev); + if (ret) { + dev_err(dev, "couldn't add unregister action for intel_xhci_usb_sw pdev\n"); + return ret; + } + + return 0; +} + +int xhci_ext_cap_init(struct xhci_hcd *xhci) +{ + void __iomem *base = &xhci->cap_regs->hc_capbase; + u32 offset, val; + int ret; + + offset = xhci_find_next_ext_cap(base, 0, 0); + + while (offset) { + val = readl(base + offset); + + switch (XHCI_EXT_CAPS_ID(val)) { + case XHCI_EXT_CAPS_VENDOR_INTEL: + if (xhci->quirks & XHCI_INTEL_USB_ROLE_SW) { + ret = xhci_create_intel_xhci_sw_pdev(xhci, + offset); + if (ret) + return ret; + } + break; + } + offset = xhci_find_next_ext_cap(base, offset, 0); + } + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_ext_cap_init); diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 631e7cc62604..268328c20681 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -39,6 +39,8 @@ #define XHCI_EXT_CAPS_ROUTE 5 /* IDs 6-9 reserved */ #define XHCI_EXT_CAPS_DEBUG 10 +/* Vendor caps */ +#define XHCI_EXT_CAPS_VENDOR_INTEL 192 /* USB Legacy Support Capability - section 7.1.1 */ #define XHCI_HC_BIOS_OWNED (1 << 16) #define XHCI_HC_OS_OWNED (1 << 24) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index d9f831b67e57..f17b7eab66cf 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -178,6 +178,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { xhci->quirks |= XHCI_SSIC_PORT_UNUSED; + xhci->quirks |= XHCI_INTEL_USB_ROLE_SW; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || @@ -311,6 +312,10 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) goto dealloc_usb2_hcd; } + retval = xhci_ext_cap_init(xhci); + if (retval) + goto put_usb3_hcd; + retval = usb_add_hcd(xhci->shared_hcd, dev->irq, IRQF_SHARED); if (retval) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8acc8f8d790f..05c909b04f14 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1829,6 +1829,7 @@ struct xhci_hcd { #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) #define XHCI_HW_LPM_DISABLE (1 << 29) #define XHCI_SUSPEND_DELAY (1 << 30) +#define XHCI_INTEL_USB_ROLE_SW (1 << 31) unsigned int num_active_eps; unsigned int limit_active_eps; @@ -2024,6 +2025,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); +int xhci_ext_cap_init(struct xhci_hcd *xhci); int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); int xhci_resume(struct xhci_hcd *xhci, bool hibernated); -- 2.16.2
WARNING: multiple messages have this Message-ID (diff)
From: Heikki Krogerus <heikki.krogerus@linux.intel.com> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Hans de Goede <hdegoede@redhat.com> Cc: Darren Hart <dvhart@infradead.org>, Andy Shevchenko <andy@infradead.org>, MyungJoo Ham <myungjoo.ham@samsung.com>, Chanwoo Choi <cw00.choi@samsung.com>, Mathias Nyman <mathias.nyman@intel.com>, Guenter Roeck <linux@roeck-us.net>, Jun Li <jun.li@nxp.com>, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [v9,08/12] xhci: Add Intel extended cap / otg phy mux handling Date: Tue, 20 Mar 2018 15:57:09 +0300 [thread overview] Message-ID: <20180320125713.85465-9-heikki.krogerus@linux.intel.com> (raw) From: Hans de Goede <hdegoede@redhat.com> The xHCI controller on various Intel SoCs has an extended cap mmio-range which contains registers to control the muxing to the xHCI (host mode) or the dwc3 (device mode) and vbus-detection for the otg usb-phy. Having a role-sw driver included in the xHCI code (under drivers/usb/host) is not desirable. So this commit adds a simple handler for this extended capability, which creates a platform device with the caps mmio region as resource, this allows us to write a separate platform role-sw driver for the role-switch. Note this commit adds a call to the new xhci_ext_cap_init() function to xhci_pci_probe(), it is added here because xhci_ext_cap_init() must be called only once. If in the future we also want to handle ext-caps on non pci xHCI HCDs from xhci_ext_cap_init() a call to it should also be added to other bus probe paths. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> --- Changes in v4: -Add Andy's Reviewed-by Changes in v2: -Use SPDX license header -Various small style cleanups / changes -Add Heikki's Reviewed-by Changes from some time ago when this patch was part of another patch-set: -Check xHCI controller PCI device-id instead of only checking for the Intel Extended capability ID, as the Extended capability ID is used on other model Intel xHCI controllers too -Add a new generic xhci_ext_cap_init() function and handle the new XHCI_INTEL_CHT_USB_MUX quirk there. -Stop using Cherry Trail / CHT in various places as other Intel SoCs (e.g. Broxton / Apollo Lake) also have this --- drivers/usb/host/Makefile | 2 +- drivers/usb/host/xhci-ext-caps.c | 90 ++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-ext-caps.h | 2 + drivers/usb/host/xhci-pci.c | 5 +++ drivers/usb/host/xhci.h | 2 + 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/xhci-ext-caps.c diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4ede4ce12366..8a8cffe0b445 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -11,7 +11,7 @@ fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o -xhci-hcd-y := xhci.o xhci-mem.o +xhci-hcd-y := xhci.o xhci-mem.o xhci-ext-caps.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o xhci-hcd-y += xhci-trace.o diff --git a/drivers/usb/host/xhci-ext-caps.c b/drivers/usb/host/xhci-ext-caps.c new file mode 100644 index 000000000000..399113f9fc5c --- /dev/null +++ b/drivers/usb/host/xhci-ext-caps.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * XHCI extended capability handling + * + * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com> + */ + +#include <linux/platform_device.h> +#include "xhci.h" + +#define USB_SW_DRV_NAME "intel_xhci_usb_sw" +#define USB_SW_RESOURCE_SIZE 0x400 + +static void xhci_intel_unregister_pdev(void *arg) +{ + platform_device_unregister(arg); +} + +static int xhci_create_intel_xhci_sw_pdev(struct xhci_hcd *xhci, u32 cap_offset) +{ + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct device *dev = hcd->self.controller; + struct platform_device *pdev; + struct resource res = { 0, }; + int ret; + + pdev = platform_device_alloc(USB_SW_DRV_NAME, PLATFORM_DEVID_NONE); + if (!pdev) { + xhci_err(xhci, "couldn't allocate %s platform device\n", + USB_SW_DRV_NAME); + return -ENOMEM; + } + + res.start = hcd->rsrc_start + cap_offset; + res.end = res.start + USB_SW_RESOURCE_SIZE - 1; + res.name = USB_SW_DRV_NAME; + res.flags = IORESOURCE_MEM; + + ret = platform_device_add_resources(pdev, &res, 1); + if (ret) { + dev_err(dev, "couldn't add resources to intel_xhci_usb_sw pdev\n"); + platform_device_put(pdev); + return ret; + } + + pdev->dev.parent = dev; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(dev, "couldn't register intel_xhci_usb_sw pdev\n"); + platform_device_put(pdev); + return ret; + } + + ret = devm_add_action_or_reset(dev, xhci_intel_unregister_pdev, pdev); + if (ret) { + dev_err(dev, "couldn't add unregister action for intel_xhci_usb_sw pdev\n"); + return ret; + } + + return 0; +} + +int xhci_ext_cap_init(struct xhci_hcd *xhci) +{ + void __iomem *base = &xhci->cap_regs->hc_capbase; + u32 offset, val; + int ret; + + offset = xhci_find_next_ext_cap(base, 0, 0); + + while (offset) { + val = readl(base + offset); + + switch (XHCI_EXT_CAPS_ID(val)) { + case XHCI_EXT_CAPS_VENDOR_INTEL: + if (xhci->quirks & XHCI_INTEL_USB_ROLE_SW) { + ret = xhci_create_intel_xhci_sw_pdev(xhci, + offset); + if (ret) + return ret; + } + break; + } + offset = xhci_find_next_ext_cap(base, offset, 0); + } + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_ext_cap_init); diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 631e7cc62604..268328c20681 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -39,6 +39,8 @@ #define XHCI_EXT_CAPS_ROUTE 5 /* IDs 6-9 reserved */ #define XHCI_EXT_CAPS_DEBUG 10 +/* Vendor caps */ +#define XHCI_EXT_CAPS_VENDOR_INTEL 192 /* USB Legacy Support Capability - section 7.1.1 */ #define XHCI_HC_BIOS_OWNED (1 << 16) #define XHCI_HC_OS_OWNED (1 << 24) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index d9f831b67e57..f17b7eab66cf 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -178,6 +178,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { xhci->quirks |= XHCI_SSIC_PORT_UNUSED; + xhci->quirks |= XHCI_INTEL_USB_ROLE_SW; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || @@ -311,6 +312,10 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) goto dealloc_usb2_hcd; } + retval = xhci_ext_cap_init(xhci); + if (retval) + goto put_usb3_hcd; + retval = usb_add_hcd(xhci->shared_hcd, dev->irq, IRQF_SHARED); if (retval) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8acc8f8d790f..05c909b04f14 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1829,6 +1829,7 @@ struct xhci_hcd { #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) #define XHCI_HW_LPM_DISABLE (1 << 29) #define XHCI_SUSPEND_DELAY (1 << 30) +#define XHCI_INTEL_USB_ROLE_SW (1 << 31) unsigned int num_active_eps; unsigned int limit_active_eps; @@ -2024,6 +2025,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); +int xhci_ext_cap_init(struct xhci_hcd *xhci); int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
next prev parent reply other threads:[~2018-03-20 12:57 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-20 12:57 [PATCH v9 00/12] USB Type-C device-connection, mux and switch support Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 01/12] drivers: base: Unified device connection lookup Heikki Krogerus 2018-03-20 12:57 ` [v9,01/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 02/12] usb: typec: API for controlling USB Type-C Multiplexers Heikki Krogerus 2018-03-20 12:57 ` [v9,02/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 03/12] usb: common: Small class for USB role switches Heikki Krogerus 2018-03-20 12:57 ` [v9,03/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 04/12] usb: typec: Separate the definitions for data and power roles Heikki Krogerus 2018-03-20 12:57 ` [v9,04/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 05/12] usb: typec: tcpm: Set USB role switch to device mode when configured as such Heikki Krogerus 2018-03-20 12:57 ` [v9,05/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 06/12] usb: typec: tcpm: Use new Type-C switch/mux and usb-role-switch functions Heikki Krogerus 2018-03-20 12:57 ` [v9,06/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 07/12] xhci: Add option to get next extended capability in list by passing id = 0 Heikki Krogerus 2018-03-20 12:57 ` [v9,07/12] " Heikki Krogerus 2018-03-20 12:57 ` Heikki Krogerus [this message] 2018-03-20 12:57 ` [v9,08/12] xhci: Add Intel extended cap / otg phy mux handling Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 09/12] usb: roles: Add Intel xHCI USB role switch driver Heikki Krogerus 2018-03-20 12:57 ` [v9,09/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 10/12] usb: typec: driver for Pericom PI3USB30532 Type-C cross switch Heikki Krogerus 2018-03-20 12:57 ` [v9,10/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 11/12] platform/x86: intel_cht_int33fe: Add device connections for the Type-C port Heikki Krogerus 2018-03-20 12:57 ` [v9,11/12] " Heikki Krogerus 2018-03-20 12:57 ` [PATCH v9 12/12] extcon: axp288: Set USB role where necessary Heikki Krogerus 2018-03-20 12:57 ` [v9,12/12] " Heikki Krogerus 2018-03-22 23:53 ` [PATCH v9 12/12] " Chanwoo Choi 2018-03-22 23:53 ` [v9,12/12] " Chanwoo Choi 2018-03-22 12:51 ` [PATCH v9 00/12] USB Type-C device-connection, mux and switch support Greg Kroah-Hartman
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180320125713.85465-9-heikki.krogerus@linux.intel.com \ --to=heikki.krogerus@linux.intel.com \ --cc=andy@infradead.org \ --cc=cw00.choi@samsung.com \ --cc=dvhart@infradead.org \ --cc=gregkh@linuxfoundation.org \ --cc=hdegoede@redhat.com \ --cc=jun.li@nxp.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-usb@vger.kernel.org \ --cc=linux@roeck-us.net \ --cc=mathias.nyman@intel.com \ --cc=myungjoo.ham@samsung.com \ --cc=platform-driver-x86@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.