linux/drivers/usb/gadget/udc/bdc/bdc_pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * bdc_pci.c - BRCM BDC USB3.0 device controller PCI interface file.
   4 *
   5 * Copyright (C) 2014 Broadcom Corporation
   6 *
   7 * Author: Ashwini Pahuja
   8 *
   9 * Based on drivers under drivers/usb/
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/slab.h>
  15#include <linux/pci.h>
  16#include <linux/pci_ids.h>
  17#include <linux/platform_device.h>
  18
  19#include "bdc.h"
  20
  21#define BDC_PCI_PID 0x1570
  22
  23struct bdc_pci {
  24        struct device *dev;
  25        struct platform_device *bdc;
  26};
  27
  28static int bdc_setup_msi(struct pci_dev *pci)
  29{
  30        int ret;
  31
  32        ret = pci_enable_msi(pci);
  33        if (ret) {
  34                pr_err("failed to allocate MSI entry\n");
  35                return ret;
  36        }
  37
  38        return ret;
  39}
  40
  41static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
  42{
  43        struct resource res[2];
  44        struct platform_device *bdc;
  45        struct bdc_pci *glue;
  46        int ret = -ENOMEM;
  47
  48        glue = devm_kzalloc(&pci->dev, sizeof(*glue), GFP_KERNEL);
  49        if (!glue)
  50                return -ENOMEM;
  51
  52        glue->dev = &pci->dev;
  53        ret = pci_enable_device(pci);
  54        if (ret) {
  55                dev_err(&pci->dev, "failed to enable pci device\n");
  56                return -ENODEV;
  57        }
  58        pci_set_master(pci);
  59
  60        bdc = platform_device_alloc(BRCM_BDC_NAME, PLATFORM_DEVID_AUTO);
  61        if (!bdc)
  62                return -ENOMEM;
  63
  64        memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
  65        bdc_setup_msi(pci);
  66
  67        res[0].start    = pci_resource_start(pci, 0);
  68        res[0].end      = pci_resource_end(pci, 0);
  69        res[0].name     = BRCM_BDC_NAME;
  70        res[0].flags    = IORESOURCE_MEM;
  71
  72        res[1].start    = pci->irq;
  73        res[1].name     = BRCM_BDC_NAME;
  74        res[1].flags    = IORESOURCE_IRQ;
  75
  76        ret = platform_device_add_resources(bdc, res, ARRAY_SIZE(res));
  77        if (ret) {
  78                dev_err(&pci->dev,
  79                        "couldn't add resources to bdc device\n");
  80                platform_device_put(bdc);
  81                return ret;
  82        }
  83
  84        pci_set_drvdata(pci, glue);
  85
  86        dma_set_coherent_mask(&bdc->dev, pci->dev.coherent_dma_mask);
  87
  88        bdc->dev.dma_mask = pci->dev.dma_mask;
  89        bdc->dev.dma_parms = pci->dev.dma_parms;
  90        bdc->dev.parent = &pci->dev;
  91        glue->bdc = bdc;
  92
  93        ret = platform_device_add(bdc);
  94        if (ret) {
  95                dev_err(&pci->dev, "failed to register bdc device\n");
  96                platform_device_put(bdc);
  97                return ret;
  98        }
  99
 100        return 0;
 101}
 102
 103static void bdc_pci_remove(struct pci_dev *pci)
 104{
 105        struct bdc_pci *glue = pci_get_drvdata(pci);
 106
 107        platform_device_unregister(glue->bdc);
 108        pci_disable_msi(pci);
 109}
 110
 111static struct pci_device_id bdc_pci_id_table[] = {
 112        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BDC_PCI_PID), },
 113        {} /* Terminating Entry */
 114};
 115
 116MODULE_DEVICE_TABLE(pci, bdc_pci_id_table);
 117
 118static struct pci_driver bdc_pci_driver = {
 119        .name = "bdc-pci",
 120        .id_table = bdc_pci_id_table,
 121        .probe = bdc_pci_probe,
 122        .remove = bdc_pci_remove,
 123};
 124
 125MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>");
 126MODULE_LICENSE("GPL");
 127MODULE_DESCRIPTION("BRCM BDC USB3 PCI Glue layer");
 128module_pci_driver(bdc_pci_driver);
 129