root/drivers/usb/dwc3/host.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dwc3_host_get_irq
  2. dwc3_host_init
  3. dwc3_host_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /**
   3  * host.c - DesignWare USB3 DRD Controller Host Glue
   4  *
   5  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
   6  *
   7  * Authors: Felipe Balbi <balbi@ti.com>,
   8  */
   9 
  10 #include <linux/platform_device.h>
  11 
  12 #include "core.h"
  13 
  14 static int dwc3_host_get_irq(struct dwc3 *dwc)
  15 {
  16         struct platform_device  *dwc3_pdev = to_platform_device(dwc->dev);
  17         int irq;
  18 
  19         irq = platform_get_irq_byname_optional(dwc3_pdev, "host");
  20         if (irq > 0)
  21                 goto out;
  22 
  23         if (irq == -EPROBE_DEFER)
  24                 goto out;
  25 
  26         irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3");
  27         if (irq > 0)
  28                 goto out;
  29 
  30         if (irq == -EPROBE_DEFER)
  31                 goto out;
  32 
  33         irq = platform_get_irq(dwc3_pdev, 0);
  34         if (irq > 0)
  35                 goto out;
  36 
  37         if (!irq)
  38                 irq = -EINVAL;
  39 
  40 out:
  41         return irq;
  42 }
  43 
  44 int dwc3_host_init(struct dwc3 *dwc)
  45 {
  46         struct property_entry   props[4];
  47         struct platform_device  *xhci;
  48         int                     ret, irq;
  49         struct resource         *res;
  50         struct platform_device  *dwc3_pdev = to_platform_device(dwc->dev);
  51         int                     prop_idx = 0;
  52 
  53         irq = dwc3_host_get_irq(dwc);
  54         if (irq < 0)
  55                 return irq;
  56 
  57         res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ, "host");
  58         if (!res)
  59                 res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ,
  60                                 "dwc_usb3");
  61         if (!res)
  62                 res = platform_get_resource(dwc3_pdev, IORESOURCE_IRQ, 0);
  63         if (!res)
  64                 return -ENOMEM;
  65 
  66         dwc->xhci_resources[1].start = irq;
  67         dwc->xhci_resources[1].end = irq;
  68         dwc->xhci_resources[1].flags = res->flags;
  69         dwc->xhci_resources[1].name = res->name;
  70 
  71         xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
  72         if (!xhci) {
  73                 dev_err(dwc->dev, "couldn't allocate xHCI device\n");
  74                 return -ENOMEM;
  75         }
  76 
  77         xhci->dev.parent        = dwc->dev;
  78 
  79         dwc->xhci = xhci;
  80 
  81         ret = platform_device_add_resources(xhci, dwc->xhci_resources,
  82                                                 DWC3_XHCI_RESOURCES_NUM);
  83         if (ret) {
  84                 dev_err(dwc->dev, "couldn't add resources to xHCI device\n");
  85                 goto err;
  86         }
  87 
  88         memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
  89 
  90         if (dwc->usb3_lpm_capable)
  91                 props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable");
  92 
  93         if (dwc->usb2_lpm_disable)
  94                 props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable");
  95 
  96         /**
  97          * WORKAROUND: dwc3 revisions <=3.00a have a limitation
  98          * where Port Disable command doesn't work.
  99          *
 100          * The suggested workaround is that we avoid Port Disable
 101          * completely.
 102          *
 103          * This following flag tells XHCI to do just that.
 104          */
 105         if (dwc->revision <= DWC3_REVISION_300A)
 106                 props[prop_idx++] = PROPERTY_ENTRY_BOOL("quirk-broken-port-ped");
 107 
 108         if (prop_idx) {
 109                 ret = platform_device_add_properties(xhci, props);
 110                 if (ret) {
 111                         dev_err(dwc->dev, "failed to add properties to xHCI\n");
 112                         goto err;
 113                 }
 114         }
 115 
 116         ret = platform_device_add(xhci);
 117         if (ret) {
 118                 dev_err(dwc->dev, "failed to register xHCI device\n");
 119                 goto err;
 120         }
 121 
 122         return 0;
 123 err:
 124         platform_device_put(xhci);
 125         return ret;
 126 }
 127 
 128 void dwc3_host_exit(struct dwc3 *dwc)
 129 {
 130         platform_device_unregister(dwc->xhci);
 131 }

/* [<][>][^][v][top][bottom][index][help] */