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 | |
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')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 18 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_msm.c | 58 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_pci.c | 124 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 78 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.h | 3 |
6 files changed, 180 insertions, 102 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 55aad9278f77..47e086a0b7f2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -378,16 +378,28 @@ config USB_FSL_QE | |||
378 | Set CONFIG_USB_GADGET to "m" to build this driver as a | 378 | Set CONFIG_USB_GADGET to "m" to build this driver as a |
379 | dynamically linked module called "fsl_qe_udc". | 379 | dynamically linked module called "fsl_qe_udc". |
380 | 380 | ||
381 | config USB_CHIPIDEA_UDC | ||
382 | tristate "ChipIdea UDC driver" | ||
383 | select USB_GADGET_DUALSPEED | ||
384 | help | ||
385 | This module contains the ChipIdea USB device controller driver; | ||
386 | you will also need platform driver like ci13xxx_pci or ci13xxx_msm | ||
387 | to use it. | ||
388 | |||
389 | Say "y" to link the driver statically, or "m" to build a | ||
390 | dynamically linked module called "ci13xxx_udc", which will serve | ||
391 | as a driver for ChipIdea udc on different platforms. | ||
392 | |||
381 | config USB_CI13XXX_PCI | 393 | config USB_CI13XXX_PCI |
382 | tristate "MIPS USB CI13xxx PCI UDC" | 394 | tristate "MIPS USB CI13xxx PCI UDC" |
383 | depends on PCI | 395 | depends on PCI && USB_CHIPIDEA_UDC |
384 | select USB_GADGET_DUALSPEED | 396 | select USB_GADGET_DUALSPEED |
385 | help | 397 | help |
386 | MIPS USB IP core family device controller | 398 | MIPS USB IP core family device controller |
387 | Currently it only supports IP part number CI13412 | 399 | Currently it only supports IP part number CI13412 |
388 | 400 | ||
389 | Say "y" to link the driver statically, or "m" to build a | 401 | Say "y" to link the driver statically, or "m" to build a |
390 | dynamically linked module called "ci13xxx_udc" and force all | 402 | dynamically linked module called "ci13xxx_pci" and force all |
391 | gadget drivers to also be dynamically linked. | 403 | gadget drivers to also be dynamically linked. |
392 | 404 | ||
393 | config USB_NET2272 | 405 | config USB_NET2272 |
@@ -484,7 +496,7 @@ config USB_EG20T | |||
484 | 496 | ||
485 | config USB_CI13XXX_MSM | 497 | config USB_CI13XXX_MSM |
486 | tristate "MIPS USB CI13xxx for MSM" | 498 | tristate "MIPS USB CI13xxx for MSM" |
487 | depends on ARCH_MSM | 499 | depends on ARCH_MSM && USB_CHIPIDEA_UDC |
488 | select USB_GADGET_DUALSPEED | 500 | select USB_GADGET_DUALSPEED |
489 | select USB_MSM_OTG | 501 | select USB_MSM_OTG |
490 | help | 502 | help |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1565253bfdd2..3786c7cdd807 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -22,6 +22,7 @@ fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | |||
22 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 22 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
23 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | 23 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o |
24 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | 24 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o |
25 | obj-$(CONFIG_USB_CHIPIDEA_UDC) += ci13xxx_udc.o | ||
25 | obj-$(CONFIG_USB_CI13XXX_PCI) += ci13xxx_pci.o | 26 | obj-$(CONFIG_USB_CI13XXX_PCI) += ci13xxx_pci.o |
26 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o | 27 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o |
27 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | 28 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o |
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c index 6e77446ef52a..418de0e61c5a 100644 --- a/drivers/usb/gadget/ci13xxx_msm.c +++ b/drivers/usb/gadget/ci13xxx_msm.c | |||
@@ -10,16 +10,12 @@ | |||
10 | #include <linux/pm_runtime.h> | 10 | #include <linux/pm_runtime.h> |
11 | #include <linux/usb/msm_hsusb_hw.h> | 11 | #include <linux/usb/msm_hsusb_hw.h> |
12 | #include <linux/usb/ulpi.h> | 12 | #include <linux/usb/ulpi.h> |
13 | #include <linux/usb/gadget.h> | ||
13 | 14 | ||
14 | #include "ci13xxx_udc.c" | 15 | #include "ci13xxx_udc.h" |
15 | 16 | ||
16 | #define MSM_USB_BASE (udc->regs) | 17 | #define MSM_USB_BASE (udc->regs) |
17 | 18 | ||
18 | static irqreturn_t msm_udc_irq(int irq, void *data) | ||
19 | { | ||
20 | return udc_irq(); | ||
21 | } | ||
22 | |||
23 | static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) | 19 | static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) |
24 | { | 20 | { |
25 | struct device *dev = udc->gadget.dev.parent; | 21 | struct device *dev = udc->gadget.dev.parent; |
@@ -60,54 +56,40 @@ static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { | |||
60 | 56 | ||
61 | static int ci13xxx_msm_probe(struct platform_device *pdev) | 57 | static int ci13xxx_msm_probe(struct platform_device *pdev) |
62 | { | 58 | { |
63 | struct resource *res; | 59 | struct platform_device *plat_ci; |
64 | void __iomem *regs; | ||
65 | int irq; | ||
66 | int ret; | 60 | int ret; |
67 | 61 | ||
68 | dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n"); | 62 | dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n"); |
69 | 63 | ||
70 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 64 | plat_ci = platform_device_alloc("ci_udc", -1); |
71 | if (!res) { | 65 | if (!plat_ci) { |
72 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | 66 | dev_err(&pdev->dev, "can't allocate ci_udc platform device\n"); |
73 | return -ENXIO; | ||
74 | } | ||
75 | |||
76 | regs = ioremap(res->start, resource_size(res)); | ||
77 | if (!regs) { | ||
78 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
79 | return -ENOMEM; | 67 | return -ENOMEM; |
80 | } | 68 | } |
81 | 69 | ||
82 | ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs, | 70 | ret = platform_device_add_resources(plat_ci, pdev->resource, |
83 | DEF_CAPOFFSET); | 71 | pdev->num_resources); |
84 | if (ret < 0) { | 72 | if (ret) { |
85 | dev_err(&pdev->dev, "udc_probe failed\n"); | 73 | dev_err(&pdev->dev, "can't add resources to platform device\n"); |
86 | goto iounmap; | 74 | goto put_platform; |
87 | } | 75 | } |
88 | 76 | ||
89 | irq = platform_get_irq(pdev, 0); | 77 | ret = platform_device_add_data(plat_ci, &ci13xxx_msm_udc_driver, |
90 | if (irq < 0) { | 78 | sizeof(ci13xxx_msm_udc_driver)); |
91 | dev_err(&pdev->dev, "IRQ not found\n"); | 79 | if (ret) |
92 | ret = -ENXIO; | 80 | goto put_platform; |
93 | goto udc_remove; | ||
94 | } | ||
95 | 81 | ||
96 | ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev); | 82 | ret = platform_device_add(plat_ci); |
97 | if (ret < 0) { | 83 | if (ret) |
98 | dev_err(&pdev->dev, "request_irq failed\n"); | 84 | goto put_platform; |
99 | goto udc_remove; | ||
100 | } | ||
101 | 85 | ||
102 | pm_runtime_no_callbacks(&pdev->dev); | 86 | pm_runtime_no_callbacks(&pdev->dev); |
103 | pm_runtime_enable(&pdev->dev); | 87 | pm_runtime_enable(&pdev->dev); |
104 | 88 | ||
105 | return 0; | 89 | return 0; |
106 | 90 | ||
107 | udc_remove: | 91 | put_platform: |
108 | udc_remove(); | 92 | platform_device_put(plat_ci); |
109 | iounmap: | ||
110 | iounmap(regs); | ||
111 | 93 | ||
112 | return ret; | 94 | return ret; |
113 | } | 95 | } |
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); |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 3b47ca1b64ee..009a3cd5895d 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -55,6 +55,8 @@ | |||
55 | #include <linux/dmapool.h> | 55 | #include <linux/dmapool.h> |
56 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
58 | #include <linux/platform_device.h> | ||
59 | #include <linux/module.h> | ||
58 | #include <linux/interrupt.h> | 60 | #include <linux/interrupt.h> |
59 | #include <linux/io.h> | 61 | #include <linux/io.h> |
60 | #include <linux/irq.h> | 62 | #include <linux/irq.h> |
@@ -67,7 +69,6 @@ | |||
67 | 69 | ||
68 | #include "ci13xxx_udc.h" | 70 | #include "ci13xxx_udc.h" |
69 | 71 | ||
70 | |||
71 | /****************************************************************************** | 72 | /****************************************************************************** |
72 | * DEFINE | 73 | * DEFINE |
73 | *****************************************************************************/ | 74 | *****************************************************************************/ |
@@ -2806,7 +2807,7 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2806 | * This function returns IRQ_HANDLED if the IRQ has been handled | 2807 | * This function returns IRQ_HANDLED if the IRQ has been handled |
2807 | * It locks access to registers | 2808 | * It locks access to registers |
2808 | */ | 2809 | */ |
2809 | static irqreturn_t udc_irq(void) | 2810 | static irqreturn_t udc_irq(int irq, void *data) |
2810 | { | 2811 | { |
2811 | struct ci13xxx *udc = _udc; | 2812 | struct ci13xxx *udc = _udc; |
2812 | irqreturn_t retval; | 2813 | irqreturn_t retval; |
@@ -2901,7 +2902,7 @@ static void udc_release(struct device *dev) | |||
2901 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | 2902 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask |
2902 | */ | 2903 | */ |
2903 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | 2904 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, |
2904 | void __iomem *regs, uintptr_t capoffset) | 2905 | void __iomem *regs) |
2905 | { | 2906 | { |
2906 | struct ci13xxx *udc; | 2907 | struct ci13xxx *udc; |
2907 | int retval = 0; | 2908 | int retval = 0; |
@@ -2935,7 +2936,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2935 | udc->gadget.dev.parent = dev; | 2936 | udc->gadget.dev.parent = dev; |
2936 | udc->gadget.dev.release = udc_release; | 2937 | udc->gadget.dev.release = udc_release; |
2937 | 2938 | ||
2938 | retval = hw_device_init(udc, regs, capoffset); | 2939 | retval = hw_device_init(udc, regs, driver->capoffset); |
2939 | if (retval < 0) | 2940 | if (retval < 0) |
2940 | goto free_udc; | 2941 | goto free_udc; |
2941 | 2942 | ||
@@ -3033,3 +3034,72 @@ static void udc_remove(void) | |||
3033 | kfree(udc); | 3034 | kfree(udc); |
3034 | _udc = NULL; | 3035 | _udc = NULL; |
3035 | } | 3036 | } |
3037 | |||
3038 | static int __devinit ci_udc_probe(struct platform_device *pdev) | ||
3039 | { | ||
3040 | struct device *dev = &pdev->dev; | ||
3041 | struct ci13xxx_udc_driver *driver = dev->platform_data; | ||
3042 | struct resource *res; | ||
3043 | void __iomem *base; | ||
3044 | int ret; | ||
3045 | |||
3046 | if (!driver) { | ||
3047 | dev_err(dev, "platform data missing\n"); | ||
3048 | return -ENODEV; | ||
3049 | } | ||
3050 | |||
3051 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
3052 | if (!res) { | ||
3053 | dev_err(dev, "missing resource\n"); | ||
3054 | return -ENODEV; | ||
3055 | } | ||
3056 | |||
3057 | base = devm_request_and_ioremap(dev, res); | ||
3058 | if (!res) { | ||
3059 | dev_err(dev, "can't request and ioremap resource\n"); | ||
3060 | return -ENOMEM; | ||
3061 | } | ||
3062 | |||
3063 | ret = udc_probe(driver, dev, base); | ||
3064 | if (ret) | ||
3065 | return ret; | ||
3066 | |||
3067 | _udc->irq = platform_get_irq(pdev, 0); | ||
3068 | if (_udc->irq < 0) { | ||
3069 | dev_err(dev, "missing IRQ\n"); | ||
3070 | ret = -ENODEV; | ||
3071 | goto out; | ||
3072 | } | ||
3073 | |||
3074 | ret = request_irq(_udc->irq, udc_irq, IRQF_SHARED, driver->name, _udc); | ||
3075 | |||
3076 | out: | ||
3077 | if (ret) | ||
3078 | udc_remove(); | ||
3079 | |||
3080 | return ret; | ||
3081 | } | ||
3082 | |||
3083 | static int __devexit ci_udc_remove(struct platform_device *pdev) | ||
3084 | { | ||
3085 | free_irq(_udc->irq, _udc); | ||
3086 | udc_remove(); | ||
3087 | |||
3088 | return 0; | ||
3089 | } | ||
3090 | |||
3091 | static struct platform_driver ci_udc_driver = { | ||
3092 | .probe = ci_udc_probe, | ||
3093 | .remove = __devexit_p(ci_udc_remove), | ||
3094 | .driver = { | ||
3095 | .name = "ci_udc", | ||
3096 | }, | ||
3097 | }; | ||
3098 | |||
3099 | module_platform_driver(ci_udc_driver); | ||
3100 | |||
3101 | MODULE_ALIAS("platform:ci_udc"); | ||
3102 | MODULE_ALIAS("platform:ci13xxx"); | ||
3103 | MODULE_LICENSE("GPL v2"); | ||
3104 | MODULE_AUTHOR("David Lopo <dlopo@chipidea.mips.com>"); | ||
3105 | MODULE_DESCRIPTION("ChipIdea UDC Driver"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index f17ffecc36c2..f605090777ce 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -103,6 +103,8 @@ struct ci13xxx_ep { | |||
103 | struct ci13xxx; | 103 | struct ci13xxx; |
104 | struct ci13xxx_udc_driver { | 104 | struct ci13xxx_udc_driver { |
105 | const char *name; | 105 | const char *name; |
106 | /* offset of the capability registers */ | ||
107 | uintptr_t capoffset; | ||
106 | unsigned long flags; | 108 | unsigned long flags; |
107 | #define CI13XXX_REGS_SHARED BIT(0) | 109 | #define CI13XXX_REGS_SHARED BIT(0) |
108 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) | 110 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) |
@@ -144,6 +146,7 @@ struct ci13xxx { | |||
144 | u8 test_mode; /* the selected test mode */ | 146 | u8 test_mode; /* the selected test mode */ |
145 | 147 | ||
146 | struct hw_bank hw_bank; | 148 | struct hw_bank hw_bank; |
149 | int irq; | ||
147 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | 150 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
148 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ | 151 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ |
149 | int vbus_active; /* is VBUS active */ | 152 | int vbus_active; /* is VBUS active */ |