LCOV - code coverage report
Current view: top level - drivers/usb/host - xhci-ext-caps.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 53 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 3 0.0 %
Branches: 0 20 0.0 %

           Branch data     Line data    Source code
       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 <linux/property.h>
      10                 :            : #include <linux/pci.h>
      11                 :            : #include "xhci.h"
      12                 :            : 
      13                 :            : #define USB_SW_DRV_NAME         "intel_xhci_usb_sw"
      14                 :            : #define USB_SW_RESOURCE_SIZE    0x400
      15                 :            : 
      16                 :            : #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI     0x22b5
      17                 :            : 
      18                 :            : static const struct property_entry role_switch_props[] = {
      19                 :            :         PROPERTY_ENTRY_BOOL("sw_switch_disable"),
      20                 :            :         {},
      21                 :            : };
      22                 :            : 
      23                 :          0 : static void xhci_intel_unregister_pdev(void *arg)
      24                 :            : {
      25                 :          0 :         platform_device_unregister(arg);
      26                 :          0 : }
      27                 :            : 
      28                 :          0 : static int xhci_create_intel_xhci_sw_pdev(struct xhci_hcd *xhci, u32 cap_offset)
      29                 :            : {
      30                 :          0 :         struct usb_hcd *hcd = xhci_to_hcd(xhci);
      31                 :          0 :         struct device *dev = hcd->self.controller;
      32                 :          0 :         struct platform_device *pdev;
      33                 :          0 :         struct pci_dev *pci = to_pci_dev(dev);
      34                 :          0 :         struct resource res = { 0, };
      35                 :          0 :         int ret;
      36                 :            : 
      37                 :          0 :         pdev = platform_device_alloc(USB_SW_DRV_NAME, PLATFORM_DEVID_NONE);
      38         [ #  # ]:          0 :         if (!pdev) {
      39                 :          0 :                 xhci_err(xhci, "couldn't allocate %s platform device\n",
      40                 :            :                          USB_SW_DRV_NAME);
      41                 :          0 :                 return -ENOMEM;
      42                 :            :         }
      43                 :            : 
      44                 :          0 :         res.start = hcd->rsrc_start + cap_offset;
      45                 :          0 :         res.end   = res.start + USB_SW_RESOURCE_SIZE - 1;
      46                 :          0 :         res.name  = USB_SW_DRV_NAME;
      47                 :          0 :         res.flags = IORESOURCE_MEM;
      48                 :            : 
      49                 :          0 :         ret = platform_device_add_resources(pdev, &res, 1);
      50         [ #  # ]:          0 :         if (ret) {
      51                 :          0 :                 dev_err(dev, "couldn't add resources to intel_xhci_usb_sw pdev\n");
      52                 :          0 :                 platform_device_put(pdev);
      53                 :          0 :                 return ret;
      54                 :            :         }
      55                 :            : 
      56         [ #  # ]:          0 :         if (pci->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
      57                 :          0 :                 ret = platform_device_add_properties(pdev, role_switch_props);
      58         [ #  # ]:          0 :                 if (ret) {
      59                 :          0 :                         dev_err(dev, "failed to register device properties\n");
      60                 :          0 :                         platform_device_put(pdev);
      61                 :          0 :                         return ret;
      62                 :            :                 }
      63                 :            :         }
      64                 :            : 
      65                 :          0 :         pdev->dev.parent = dev;
      66                 :            : 
      67                 :          0 :         ret = platform_device_add(pdev);
      68         [ #  # ]:          0 :         if (ret) {
      69                 :          0 :                 dev_err(dev, "couldn't register intel_xhci_usb_sw pdev\n");
      70                 :          0 :                 platform_device_put(pdev);
      71                 :          0 :                 return ret;
      72                 :            :         }
      73                 :            : 
      74                 :          0 :         ret = devm_add_action_or_reset(dev, xhci_intel_unregister_pdev, pdev);
      75         [ #  # ]:          0 :         if (ret) {
      76                 :          0 :                 dev_err(dev, "couldn't add unregister action for intel_xhci_usb_sw pdev\n");
      77                 :          0 :                 return ret;
      78                 :            :         }
      79                 :            : 
      80                 :            :         return 0;
      81                 :            : }
      82                 :            : 
      83                 :          0 : int xhci_ext_cap_init(struct xhci_hcd *xhci)
      84                 :            : {
      85                 :          0 :         void __iomem *base = &xhci->cap_regs->hc_capbase;
      86                 :          0 :         u32 offset, val;
      87                 :          0 :         int ret;
      88                 :            : 
      89                 :          0 :         offset = xhci_find_next_ext_cap(base, 0, 0);
      90                 :            : 
      91         [ #  # ]:          0 :         while (offset) {
      92                 :          0 :                 val = readl(base + offset);
      93                 :            : 
      94         [ #  # ]:          0 :                 switch (XHCI_EXT_CAPS_ID(val)) {
      95                 :          0 :                 case XHCI_EXT_CAPS_VENDOR_INTEL:
      96         [ #  # ]:          0 :                         if (xhci->quirks & XHCI_INTEL_USB_ROLE_SW) {
      97                 :          0 :                                 ret = xhci_create_intel_xhci_sw_pdev(xhci,
      98                 :            :                                                                      offset);
      99         [ #  # ]:          0 :                                 if (ret)
     100                 :          0 :                                         return ret;
     101                 :            :                         }
     102                 :            :                         break;
     103                 :            :                 }
     104                 :          0 :                 offset = xhci_find_next_ext_cap(base, offset, 0);
     105                 :            :         }
     106                 :            : 
     107                 :            :         return 0;
     108                 :            : }
     109                 :            : EXPORT_SYMBOL_GPL(xhci_ext_cap_init);

Generated by: LCOV version 1.14