aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/ci13xxx_pci.c
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2012-05-08 16:29:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-09 17:54:12 -0400
commit62bb84ed0e4d14b0a5070f44b2387a42f7f535d9 (patch)
tree157a76f428ecb7878a9d04e6ad3a26c298977e9c /drivers/usb/gadget/ci13xxx_pci.c
parented6c6f419f02a6da444e26374f3510ac57b6faf4 (diff)
usb: gadget: ci13xxx: convert to platform device
Let's break ci13xxx driver into a separate udc driver and platform drivers _pci and _msm, which will create a platform device for each pci (or msm) device found. The approach was introduced by Felipe in dwc3 driver and there seems to be no reason not to use it. msm related code is only compile-tested. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/ci13xxx_pci.c')
-rw-r--r--drivers/usb/gadget/ci13xxx_pci.c124
1 files changed, 67 insertions, 57 deletions
diff --git a/drivers/usb/gadget/ci13xxx_pci.c b/drivers/usb/gadget/ci13xxx_pci.c
index ef5da49eb809..ea03fabd4d97 100644
--- a/drivers/usb/gadget/ci13xxx_pci.c
+++ b/drivers/usb/gadget/ci13xxx_pci.c
@@ -10,10 +10,13 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/platform_device.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/interrupt.h>
17#include <linux/usb/gadget.h>
15 18
16#include "ci13xxx_udc.c" 19#include "ci13xxx_udc.h"
17 20
18/* driver name */ 21/* driver name */
19#define UDC_DRIVER_NAME "ci13xxx_pci" 22#define UDC_DRIVER_NAME "ci13xxx_pci"
@@ -21,25 +24,14 @@
21/****************************************************************************** 24/******************************************************************************
22 * PCI block 25 * PCI block
23 *****************************************************************************/ 26 *****************************************************************************/
24/** 27struct ci13xxx_udc_driver pci_driver = {
25 * ci13xxx_pci_irq: interrut handler 28 .name = UDC_DRIVER_NAME,
26 * @irq: irq number 29 .capoffset = DEF_CAPOFFSET,
27 * @pdev: USB Device Controller interrupt source 30};
28 *
29 * This function returns IRQ_HANDLED if the IRQ has been handled
30 * This is an ISR don't trace, use attribute interface instead
31 */
32static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev)
33{
34 if (irq == 0) {
35 dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!");
36 return IRQ_HANDLED;
37 }
38 return udc_irq();
39}
40 31
41static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = { 32struct ci13xxx_udc_driver langwell_pci_driver = {
42 .name = UDC_DRIVER_NAME, 33 .name = UDC_DRIVER_NAME,
34 .capoffset = 0,
43}; 35};
44 36
45/** 37/**
@@ -54,9 +46,10 @@ static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = {
54static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, 46static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
55 const struct pci_device_id *id) 47 const struct pci_device_id *id)
56{ 48{
57 void __iomem *regs = NULL; 49 struct ci13xxx_udc_driver *driver = (void *)id->driver_data;
58 uintptr_t capoffset = DEF_CAPOFFSET; 50 struct platform_device *plat_ci;
59 int retval = 0; 51 struct resource res[3];
52 int retval = 0, nres = 2;
60 53
61 if (id == NULL) 54 if (id == NULL)
62 return -EINVAL; 55 return -EINVAL;
@@ -71,45 +64,50 @@ static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
71 goto disable_device; 64 goto disable_device;
72 } 65 }
73 66
74 retval = pci_request_regions(pdev, UDC_DRIVER_NAME); 67 pci_set_power_state(pdev, PCI_D0);
75 if (retval)
76 goto disable_device;
77
78 /* BAR 0 holds all the registers */
79 regs = pci_iomap(pdev, 0, 0);
80 if (!regs) {
81 dev_err(&pdev->dev, "Error mapping memory!");
82 retval = -EFAULT;
83 goto release_regions;
84 }
85 pci_set_drvdata(pdev, (__force void *)regs);
86
87 pci_set_master(pdev); 68 pci_set_master(pdev);
88 pci_try_set_mwi(pdev); 69 pci_try_set_mwi(pdev);
89 70
90 if (pdev->vendor == PCI_VENDOR_ID_INTEL) 71 plat_ci = platform_device_alloc("ci_udc", -1);
91 capoffset = 0; 72 if (!plat_ci) {
73 dev_err(&pdev->dev, "can't allocate ci_udc platform device\n");
74 retval = -ENOMEM;
75 goto disable_device;
76 }
92 77
93 retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs, 78 memset(res, 0, sizeof(res));
94 capoffset); 79 res[0].start = pci_resource_start(pdev, 0);
80 res[0].end = pci_resource_end(pdev, 0);
81 res[0].flags = IORESOURCE_MEM;
82 res[1].start = pdev->irq;
83 res[1].flags = IORESOURCE_IRQ;
84
85 retval = platform_device_add_resources(plat_ci, res, nres);
86 if (retval) {
87 dev_err(&pdev->dev, "can't add resources to platform device\n");
88 goto put_platform;
89 }
90
91 retval = platform_device_add_data(plat_ci, driver, sizeof(*driver));
95 if (retval) 92 if (retval)
96 goto iounmap; 93 goto put_platform;
97 94
98 /* our device does not have MSI capability */ 95 dma_set_coherent_mask(&plat_ci->dev, pdev->dev.coherent_dma_mask);
96 plat_ci->dev.dma_mask = pdev->dev.dma_mask;
97 plat_ci->dev.dma_parms = pdev->dev.dma_parms;
98 plat_ci->dev.parent = &pdev->dev;
99 99
100 retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED, 100 pci_set_drvdata(pdev, plat_ci);
101 UDC_DRIVER_NAME, pdev); 101
102 retval = platform_device_add(plat_ci);
102 if (retval) 103 if (retval)
103 goto gadget_remove; 104 goto put_platform;
104 105
105 return 0; 106 return 0;
106 107
107 gadget_remove: 108 put_platform:
108 udc_remove(); 109 pci_set_drvdata(pdev, NULL);
109 iounmap: 110 platform_device_put(plat_ci);
110 pci_iounmap(pdev, regs);
111 release_regions:
112 pci_release_regions(pdev);
113 disable_device: 111 disable_device:
114 pci_disable_device(pdev); 112 pci_disable_device(pdev);
115 done: 113 done:
@@ -126,10 +124,10 @@ static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
126 */ 124 */
127static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) 125static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
128{ 126{
129 free_irq(pdev->irq, pdev); 127 struct platform_device *plat_ci = pci_get_drvdata(pdev);
130 udc_remove(); 128
131 pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev)); 129 platform_device_unregister(plat_ci);
132 pci_release_regions(pdev); 130 pci_set_drvdata(pdev, NULL);
133 pci_disable_device(pdev); 131 pci_disable_device(pdev);
134} 132}
135 133
@@ -140,10 +138,22 @@ static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
140 * Check "pci.h" for details 138 * Check "pci.h" for details
141 */ 139 */
142static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { 140static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
143 { PCI_DEVICE(0x153F, 0x1004) }, 141 {
144 { PCI_DEVICE(0x153F, 0x1006) }, 142 PCI_DEVICE(0x153F, 0x1004),
145 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811) }, 143 .driver_data = (kernel_ulong_t)&pci_driver,
146 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829) }, 144 },
145 {
146 PCI_DEVICE(0x153F, 0x1006),
147 .driver_data = (kernel_ulong_t)&pci_driver,
148 },
149 {
150 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811),
151 .driver_data = (kernel_ulong_t)&langwell_pci_driver,
152 },
153 {
154 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829),
155 .driver_data = (kernel_ulong_t)&langwell_pci_driver,
156 },
147 { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } 157 { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
148}; 158};
149MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); 159MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);