root/drivers/usb/chipidea/ci_hdrc_pci.c

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

DEFINITIONS

This source file includes following definitions.
  1. ci_hdrc_pci_probe
  2. ci_hdrc_pci_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * ci_hdrc_pci.c - MIPS USB IP core family device controller
   4  *
   5  * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
   6  *
   7  * Author: David Lopo
   8  */
   9 
  10 #include <linux/platform_device.h>
  11 #include <linux/module.h>
  12 #include <linux/pci.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/usb/gadget.h>
  15 #include <linux/usb/chipidea.h>
  16 #include <linux/usb/usb_phy_generic.h>
  17 
  18 /* driver name */
  19 #define UDC_DRIVER_NAME   "ci_hdrc_pci"
  20 
  21 struct ci_hdrc_pci {
  22         struct platform_device  *ci;
  23         struct platform_device  *phy;
  24 };
  25 
  26 /******************************************************************************
  27  * PCI block
  28  *****************************************************************************/
  29 static struct ci_hdrc_platform_data pci_platdata = {
  30         .name           = UDC_DRIVER_NAME,
  31         .capoffset      = DEF_CAPOFFSET,
  32 };
  33 
  34 static struct ci_hdrc_platform_data langwell_pci_platdata = {
  35         .name           = UDC_DRIVER_NAME,
  36         .capoffset      = 0,
  37 };
  38 
  39 static struct ci_hdrc_platform_data penwell_pci_platdata = {
  40         .name           = UDC_DRIVER_NAME,
  41         .capoffset      = 0,
  42         .power_budget   = 200,
  43 };
  44 
  45 /**
  46  * ci_hdrc_pci_probe: PCI probe
  47  * @pdev: USB device controller being probed
  48  * @id:   PCI hotplug ID connecting controller to UDC framework
  49  *
  50  * This function returns an error code
  51  * Allocates basic PCI resources for this USB device controller, and then
  52  * invokes the udc_probe() method to start the UDC associated with it
  53  */
  54 static int ci_hdrc_pci_probe(struct pci_dev *pdev,
  55                                        const struct pci_device_id *id)
  56 {
  57         struct ci_hdrc_platform_data *platdata = (void *)id->driver_data;
  58         struct ci_hdrc_pci *ci;
  59         struct resource res[3];
  60         int retval = 0, nres = 2;
  61 
  62         if (!platdata) {
  63                 dev_err(&pdev->dev, "device doesn't provide driver data\n");
  64                 return -ENODEV;
  65         }
  66 
  67         ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
  68         if (!ci)
  69                 return -ENOMEM;
  70 
  71         retval = pcim_enable_device(pdev);
  72         if (retval)
  73                 return retval;
  74 
  75         if (!pdev->irq) {
  76                 dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
  77                 return -ENODEV;
  78         }
  79 
  80         pci_set_master(pdev);
  81         pci_try_set_mwi(pdev);
  82 
  83         /* register a nop PHY */
  84         ci->phy = usb_phy_generic_register();
  85         if (IS_ERR(ci->phy))
  86                 return PTR_ERR(ci->phy);
  87 
  88         memset(res, 0, sizeof(res));
  89         res[0].start    = pci_resource_start(pdev, 0);
  90         res[0].end      = pci_resource_end(pdev, 0);
  91         res[0].flags    = IORESOURCE_MEM;
  92         res[1].start    = pdev->irq;
  93         res[1].flags    = IORESOURCE_IRQ;
  94 
  95         ci->ci = ci_hdrc_add_device(&pdev->dev, res, nres, platdata);
  96         if (IS_ERR(ci->ci)) {
  97                 dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
  98                 usb_phy_generic_unregister(ci->phy);
  99                 return PTR_ERR(ci->ci);
 100         }
 101 
 102         pci_set_drvdata(pdev, ci);
 103 
 104         return 0;
 105 }
 106 
 107 /**
 108  * ci_hdrc_pci_remove: PCI remove
 109  * @pdev: USB Device Controller being removed
 110  *
 111  * Reverses the effect of ci_hdrc_pci_probe(),
 112  * first invoking the udc_remove() and then releases
 113  * all PCI resources allocated for this USB device controller
 114  */
 115 static void ci_hdrc_pci_remove(struct pci_dev *pdev)
 116 {
 117         struct ci_hdrc_pci *ci = pci_get_drvdata(pdev);
 118 
 119         ci_hdrc_remove_device(ci->ci);
 120         usb_phy_generic_unregister(ci->phy);
 121 }
 122 
 123 /**
 124  * PCI device table
 125  * PCI device structure
 126  *
 127  * Check "pci.h" for details
 128  *
 129  * Note: ehci-pci driver may try to probe the device first. You have to add an
 130  * ID to the bypass_pci_id_table in ehci-pci driver to prevent this.
 131  */
 132 static const struct pci_device_id ci_hdrc_pci_id_table[] = {
 133         {
 134                 PCI_DEVICE(0x153F, 0x1004),
 135                 .driver_data = (kernel_ulong_t)&pci_platdata,
 136         },
 137         {
 138                 PCI_DEVICE(0x153F, 0x1006),
 139                 .driver_data = (kernel_ulong_t)&pci_platdata,
 140         },
 141         {
 142                 PCI_VDEVICE(INTEL, 0x0811),
 143                 .driver_data = (kernel_ulong_t)&langwell_pci_platdata,
 144         },
 145         {
 146                 PCI_VDEVICE(INTEL, 0x0829),
 147                 .driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 148         },
 149         {
 150                 /* Intel Clovertrail */
 151                 PCI_VDEVICE(INTEL, 0xe006),
 152                 .driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 153         },
 154         { 0 } /* end: all zeroes */
 155 };
 156 MODULE_DEVICE_TABLE(pci, ci_hdrc_pci_id_table);
 157 
 158 static struct pci_driver ci_hdrc_pci_driver = {
 159         .name         = UDC_DRIVER_NAME,
 160         .id_table     = ci_hdrc_pci_id_table,
 161         .probe        = ci_hdrc_pci_probe,
 162         .remove       = ci_hdrc_pci_remove,
 163 };
 164 
 165 module_pci_driver(ci_hdrc_pci_driver);
 166 
 167 MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
 168 MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
 169 MODULE_LICENSE("GPL");
 170 MODULE_ALIAS("platform:ci13xxx_pci");

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