diff options
author | Alexander Shishkin <alexander.shishkin@linux.intel.com> | 2012-05-08 16:29:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-09 17:54:12 -0400 |
commit | 62bb84ed0e4d14b0a5070f44b2387a42f7f535d9 (patch) | |
tree | 157a76f428ecb7878a9d04e6ad3a26c298977e9c /drivers/usb/gadget/ci13xxx_pci.c | |
parent | ed6c6f419f02a6da444e26374f3510ac57b6faf4 (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.c | 124 |
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 | /** | 27 | struct 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 | */ | ||
32 | static 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 | ||
41 | static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = { | 32 | struct 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 = { | |||
54 | static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | 46 | static 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 | */ |
127 | static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) | 125 | static 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 | */ |
142 | static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { | 140 | static 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 | }; |
149 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); | 159 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); |