Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.3-rc2 90 lines 2.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * XHCI extended capability handling 4 * 5 * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com> 6 */ 7 8#include <linux/platform_device.h> 9#include "xhci.h" 10 11#define USB_SW_DRV_NAME "intel_xhci_usb_sw" 12#define USB_SW_RESOURCE_SIZE 0x400 13 14static void xhci_intel_unregister_pdev(void *arg) 15{ 16 platform_device_unregister(arg); 17} 18 19static int xhci_create_intel_xhci_sw_pdev(struct xhci_hcd *xhci, u32 cap_offset) 20{ 21 struct usb_hcd *hcd = xhci_to_hcd(xhci); 22 struct device *dev = hcd->self.controller; 23 struct platform_device *pdev; 24 struct resource res = { 0, }; 25 int ret; 26 27 pdev = platform_device_alloc(USB_SW_DRV_NAME, PLATFORM_DEVID_NONE); 28 if (!pdev) { 29 xhci_err(xhci, "couldn't allocate %s platform device\n", 30 USB_SW_DRV_NAME); 31 return -ENOMEM; 32 } 33 34 res.start = hcd->rsrc_start + cap_offset; 35 res.end = res.start + USB_SW_RESOURCE_SIZE - 1; 36 res.name = USB_SW_DRV_NAME; 37 res.flags = IORESOURCE_MEM; 38 39 ret = platform_device_add_resources(pdev, &res, 1); 40 if (ret) { 41 dev_err(dev, "couldn't add resources to intel_xhci_usb_sw pdev\n"); 42 platform_device_put(pdev); 43 return ret; 44 } 45 46 pdev->dev.parent = dev; 47 48 ret = platform_device_add(pdev); 49 if (ret) { 50 dev_err(dev, "couldn't register intel_xhci_usb_sw pdev\n"); 51 platform_device_put(pdev); 52 return ret; 53 } 54 55 ret = devm_add_action_or_reset(dev, xhci_intel_unregister_pdev, pdev); 56 if (ret) { 57 dev_err(dev, "couldn't add unregister action for intel_xhci_usb_sw pdev\n"); 58 return ret; 59 } 60 61 return 0; 62} 63 64int xhci_ext_cap_init(struct xhci_hcd *xhci) 65{ 66 void __iomem *base = &xhci->cap_regs->hc_capbase; 67 u32 offset, val; 68 int ret; 69 70 offset = xhci_find_next_ext_cap(base, 0, 0); 71 72 while (offset) { 73 val = readl(base + offset); 74 75 switch (XHCI_EXT_CAPS_ID(val)) { 76 case XHCI_EXT_CAPS_VENDOR_INTEL: 77 if (xhci->quirks & XHCI_INTEL_USB_ROLE_SW) { 78 ret = xhci_create_intel_xhci_sw_pdev(xhci, 79 offset); 80 if (ret) 81 return ret; 82 } 83 break; 84 } 85 offset = xhci_find_next_ext_cap(base, offset, 0); 86 } 87 88 return 0; 89} 90EXPORT_SYMBOL_GPL(xhci_ext_cap_init);