linux/drivers/usb/gadget/udc/amd5536udc_pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * amd5536udc_pci.c -- AMD 5536 UDC high/full speed USB device controller
   4 *
   5 * Copyright (C) 2005-2007 AMD (http://www.amd.com)
   6 * Author: Thomas Dahlmann
   7 */
   8
   9/*
  10 * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536.
  11 * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it
  12 * provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
  13 *
  14 * Make sure that UDC is assigned to port 4 by BIOS settings (port can also
  15 * be used as host port) and UOC bits PAD_EN and APU are set (should be done
  16 * by BIOS init).
  17 *
  18 * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not
  19 * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0")
  20 * can be used with gadget ether.
  21 *
  22 * This file does pci device registration, and the core driver implementation
  23 * is done in amd5536udc.c
  24 *
  25 * The driver is split so as to use the core UDC driver which is based on
  26 * Synopsys device controller IP (different than HS OTG IP) in UDCs
  27 * integrated to SoC platforms.
  28 *
  29 */
  30
  31/* Driver strings */
  32#define UDC_MOD_DESCRIPTION             "AMD 5536 UDC - USB Device Controller"
  33
  34/* system */
  35#include <linux/device.h>
  36#include <linux/dmapool.h>
  37#include <linux/interrupt.h>
  38#include <linux/io.h>
  39#include <linux/irq.h>
  40#include <linux/module.h>
  41#include <linux/moduleparam.h>
  42#include <linux/prefetch.h>
  43#include <linux/pci.h>
  44
  45/* udc specific */
  46#include "amd5536udc.h"
  47
  48/* pointer to device object */
  49static struct udc *udc;
  50
  51/* description */
  52static const char mod_desc[] = UDC_MOD_DESCRIPTION;
  53static const char name[] = "amd5536udc-pci";
  54
  55/* Reset all pci context */
  56static void udc_pci_remove(struct pci_dev *pdev)
  57{
  58        struct udc              *dev;
  59
  60        dev = pci_get_drvdata(pdev);
  61
  62        usb_del_gadget_udc(&udc->gadget);
  63        /* gadget driver must not be registered */
  64        if (WARN_ON(dev->driver))
  65                return;
  66
  67        /* dma pool cleanup */
  68        free_dma_pools(dev);
  69
  70        /* reset controller */
  71        writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
  72        free_irq(pdev->irq, dev);
  73        iounmap(dev->virt_addr);
  74        release_mem_region(pci_resource_start(pdev, 0),
  75                           pci_resource_len(pdev, 0));
  76        pci_disable_device(pdev);
  77
  78        udc_remove(dev);
  79}
  80
  81/* Called by pci bus driver to init pci context */
  82static int udc_pci_probe(
  83        struct pci_dev *pdev,
  84        const struct pci_device_id *id
  85)
  86{
  87        struct udc              *dev;
  88        unsigned long           resource;
  89        unsigned long           len;
  90        int                     retval = 0;
  91
  92        /* one udc only */
  93        if (udc) {
  94                dev_dbg(&pdev->dev, "already probed\n");
  95                return -EBUSY;
  96        }
  97
  98        /* init */
  99        dev = kzalloc(sizeof(struct udc), GFP_KERNEL);
 100        if (!dev)
 101                return -ENOMEM;
 102
 103        /* pci setup */
 104        if (pci_enable_device(pdev) < 0) {
 105                retval = -ENODEV;
 106                goto err_pcidev;
 107        }
 108
 109        /* PCI resource allocation */
 110        resource = pci_resource_start(pdev, 0);
 111        len = pci_resource_len(pdev, 0);
 112
 113        if (!request_mem_region(resource, len, name)) {
 114                dev_dbg(&pdev->dev, "pci device used already\n");
 115                retval = -EBUSY;
 116                goto err_memreg;
 117        }
 118
 119        dev->virt_addr = ioremap_nocache(resource, len);
 120        if (!dev->virt_addr) {
 121                dev_dbg(&pdev->dev, "start address cannot be mapped\n");
 122                retval = -EFAULT;
 123                goto err_ioremap;
 124        }
 125
 126        if (!pdev->irq) {
 127                dev_err(&pdev->dev, "irq not set\n");
 128                retval = -ENODEV;
 129                goto err_irq;
 130        }
 131
 132        spin_lock_init(&dev->lock);
 133        /* udc csr registers base */
 134        dev->csr = dev->virt_addr + UDC_CSR_ADDR;
 135        /* dev registers base */
 136        dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
 137        /* ep registers base */
 138        dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
 139        /* fifo's base */
 140        dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
 141        dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
 142
 143        if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
 144                dev_dbg(&pdev->dev, "request_irq(%d) fail\n", pdev->irq);
 145                retval = -EBUSY;
 146                goto err_irq;
 147        }
 148
 149        pci_set_drvdata(pdev, dev);
 150
 151        /* chip revision for Hs AMD5536 */
 152        dev->chiprev = pdev->revision;
 153
 154        pci_set_master(pdev);
 155        pci_try_set_mwi(pdev);
 156
 157        /* init dma pools */
 158        if (use_dma) {
 159                retval = init_dma_pools(dev);
 160                if (retval != 0)
 161                        goto err_dma;
 162        }
 163
 164        dev->phys_addr = resource;
 165        dev->irq = pdev->irq;
 166        dev->pdev = pdev;
 167        dev->dev = &pdev->dev;
 168
 169        /* general probing */
 170        if (udc_probe(dev)) {
 171                retval = -ENODEV;
 172                goto err_probe;
 173        }
 174        return 0;
 175
 176err_probe:
 177        if (use_dma)
 178                free_dma_pools(dev);
 179err_dma:
 180        free_irq(pdev->irq, dev);
 181err_irq:
 182        iounmap(dev->virt_addr);
 183err_ioremap:
 184        release_mem_region(resource, len);
 185err_memreg:
 186        pci_disable_device(pdev);
 187err_pcidev:
 188        kfree(dev);
 189        return retval;
 190}
 191
 192/* PCI device parameters */
 193static const struct pci_device_id pci_id[] = {
 194        {
 195                PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096),
 196                .class =        PCI_CLASS_SERIAL_USB_DEVICE,
 197                .class_mask =   0xffffffff,
 198        },
 199        {},
 200};
 201MODULE_DEVICE_TABLE(pci, pci_id);
 202
 203/* PCI functions */
 204static struct pci_driver udc_pci_driver = {
 205        .name =         (char *) name,
 206        .id_table =     pci_id,
 207        .probe =        udc_pci_probe,
 208        .remove =       udc_pci_remove,
 209};
 210module_pci_driver(udc_pci_driver);
 211
 212MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION);
 213MODULE_AUTHOR("Thomas Dahlmann");
 214MODULE_LICENSE("GPL");
 215