-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
xhci: Add Intel extended cap / otg phy mux handling
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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- Loading branch information
Hans de Goede
authored and
Greg Kroah-Hartman
committed
Mar 22, 2018
1 parent
d0a0fa9
commit fa31b3c
Showing
5 changed files
with
100 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters