aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-11 20:22:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-11 20:22:01 -0500
commit0f89fc3fd861b8c50fc8c8db5b9a640959744ac7 (patch)
treecbfee24b2d11ecea5847f59c78afa63305b08b55
parent3a3f2e50951faaac1c67b5c6c0c70dec5b150e9b (diff)
parente32672f0bc7ec8421aa8e580e9f2216d3bec2505 (diff)
Merge tag 'dwc3-for-v3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB dwc3 patches from Felipe: "usb: dwc3: patches for v3.8 We can finaly drop HAVE_CLK dependency from exynos glue layer now that clk API provides no-op stubs when it's not linked into the kernel. We're also switching over event buffer allocation to devm_kzalloc() and moving the allocation out of dwc3_core_init() so that can be re-used when implementing PM support for v3.9. After the introduction of PLATFORM_DEVID_AUTO, we can also drop the homebrew platform device ID handling we had on dwc3 core and let driver core take care of that for us. Exynos glue layer learns about DeviceTree and drops platform_data support completely."
-rw-r--r--drivers/usb/dwc3/Makefile14
-rw-r--r--drivers/usb/dwc3/core.c77
-rw-r--r--drivers/usb/dwc3/core.h3
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c49
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c16
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c16
6 files changed, 43 insertions, 132 deletions
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4c180b..4502648b8171 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -27,19 +27,7 @@ endif
27## 27##
28 28
29obj-$(CONFIG_USB_DWC3) += dwc3-omap.o 29obj-$(CONFIG_USB_DWC3) += dwc3-omap.o
30 30obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
31##
32# REVISIT Samsung Exynos platform needs the clk API which isn't
33# defined on all architectures. If we allow dwc3-exynos.c compile
34# always we will fail the linking phase on those architectures
35# which don't provide clk api implementation and that's unnaceptable.
36#
37# When Samsung's platform start supporting pm_runtime, this check
38# for HAVE_CLK should be removed.
39##
40ifneq ($(CONFIG_HAVE_CLK),)
41 obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
42endif
43 31
44ifneq ($(CONFIG_PCI),) 32ifneq ($(CONFIG_PCI),)
45 obj-$(CONFIG_USB_DWC3) += dwc3-pci.o 33 obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c14ebc975ba4..e71a62a652d0 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -66,45 +66,6 @@ MODULE_PARM_DESC(maximum_speed, "Maximum supported speed.");
66 66
67/* -------------------------------------------------------------------------- */ 67/* -------------------------------------------------------------------------- */
68 68
69#define DWC3_DEVS_POSSIBLE 32
70
71static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE);
72
73int dwc3_get_device_id(void)
74{
75 int id;
76
77again:
78 id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE);
79 if (id < DWC3_DEVS_POSSIBLE) {
80 int old;
81
82 old = test_and_set_bit(id, dwc3_devs);
83 if (old)
84 goto again;
85 } else {
86 pr_err("dwc3: no space for new device\n");
87 id = -ENOMEM;
88 }
89
90 return id;
91}
92EXPORT_SYMBOL_GPL(dwc3_get_device_id);
93
94void dwc3_put_device_id(int id)
95{
96 int ret;
97
98 if (id < 0)
99 return;
100
101 ret = test_bit(id, dwc3_devs);
102 WARN(!ret, "dwc3: ID %d not in use\n", id);
103 smp_mb__before_clear_bit();
104 clear_bit(id, dwc3_devs);
105}
106EXPORT_SYMBOL_GPL(dwc3_put_device_id);
107
108void dwc3_set_mode(struct dwc3 *dwc, u32 mode) 69void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
109{ 70{
110 u32 reg; 71 u32 reg;
@@ -169,7 +130,6 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
169 struct dwc3_event_buffer *evt) 130 struct dwc3_event_buffer *evt)
170{ 131{
171 dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma); 132 dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
172 kfree(evt);
173} 133}
174 134
175/** 135/**
@@ -185,7 +145,7 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
185{ 145{
186 struct dwc3_event_buffer *evt; 146 struct dwc3_event_buffer *evt;
187 147
188 evt = kzalloc(sizeof(*evt), GFP_KERNEL); 148 evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
189 if (!evt) 149 if (!evt)
190 return ERR_PTR(-ENOMEM); 150 return ERR_PTR(-ENOMEM);
191 151
@@ -193,10 +153,8 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
193 evt->length = length; 153 evt->length = length;
194 evt->buf = dma_alloc_coherent(dwc->dev, length, 154 evt->buf = dma_alloc_coherent(dwc->dev, length,
195 &evt->dma, GFP_KERNEL); 155 &evt->dma, GFP_KERNEL);
196 if (!evt->buf) { 156 if (!evt->buf)
197 kfree(evt);
198 return ERR_PTR(-ENOMEM); 157 return ERR_PTR(-ENOMEM);
199 }
200 158
201 return evt; 159 return evt;
202} 160}
@@ -215,8 +173,6 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
215 if (evt) 173 if (evt)
216 dwc3_free_one_event_buffer(dwc, evt); 174 dwc3_free_one_event_buffer(dwc, evt);
217 } 175 }
218
219 kfree(dwc->ev_buffs);
220} 176}
221 177
222/** 178/**
@@ -235,7 +191,8 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
235 num = DWC3_NUM_INT(dwc->hwparams.hwparams1); 191 num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
236 dwc->num_event_buffers = num; 192 dwc->num_event_buffers = num;
237 193
238 dwc->ev_buffs = kzalloc(sizeof(*dwc->ev_buffs) * num, GFP_KERNEL); 194 dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
195 GFP_KERNEL);
239 if (!dwc->ev_buffs) { 196 if (!dwc->ev_buffs) {
240 dev_err(dwc->dev, "can't allocate event buffers array\n"); 197 dev_err(dwc->dev, "can't allocate event buffers array\n");
241 return -ENOMEM; 198 return -ENOMEM;
@@ -383,24 +340,14 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
383 340
384 dwc3_writel(dwc->regs, DWC3_GCTL, reg); 341 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
385 342
386 ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
387 if (ret) {
388 dev_err(dwc->dev, "failed to allocate event buffers\n");
389 ret = -ENOMEM;
390 goto err1;
391 }
392
393 ret = dwc3_event_buffers_setup(dwc); 343 ret = dwc3_event_buffers_setup(dwc);
394 if (ret) { 344 if (ret) {
395 dev_err(dwc->dev, "failed to setup event buffers\n"); 345 dev_err(dwc->dev, "failed to setup event buffers\n");
396 goto err1; 346 goto err0;
397 } 347 }
398 348
399 return 0; 349 return 0;
400 350
401err1:
402 dwc3_free_event_buffers(dwc);
403
404err0: 351err0:
405 return ret; 352 return ret;
406} 353}
@@ -408,11 +355,9 @@ err0:
408static void dwc3_core_exit(struct dwc3 *dwc) 355static void dwc3_core_exit(struct dwc3 *dwc)
409{ 356{
410 dwc3_event_buffers_cleanup(dwc); 357 dwc3_event_buffers_cleanup(dwc);
411 dwc3_free_event_buffers(dwc);
412 358
413 usb_phy_shutdown(dwc->usb2_phy); 359 usb_phy_shutdown(dwc->usb2_phy);
414 usb_phy_shutdown(dwc->usb3_phy); 360 usb_phy_shutdown(dwc->usb3_phy);
415
416} 361}
417 362
418#define DWC3_ALIGN_MASK (16 - 1) 363#define DWC3_ALIGN_MASK (16 - 1)
@@ -515,10 +460,17 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
515 pm_runtime_get_sync(dev); 460 pm_runtime_get_sync(dev);
516 pm_runtime_forbid(dev); 461 pm_runtime_forbid(dev);
517 462
463 ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
464 if (ret) {
465 dev_err(dwc->dev, "failed to allocate event buffers\n");
466 ret = -ENOMEM;
467 goto err0;
468 }
469
518 ret = dwc3_core_init(dwc); 470 ret = dwc3_core_init(dwc);
519 if (ret) { 471 if (ret) {
520 dev_err(dev, "failed to initialize core\n"); 472 dev_err(dev, "failed to initialize core\n");
521 return ret; 473 goto err0;
522 } 474 }
523 475
524 mode = DWC3_MODE(dwc->hwparams.hwparams0); 476 mode = DWC3_MODE(dwc->hwparams.hwparams0);
@@ -590,6 +542,9 @@ err2:
590err1: 542err1:
591 dwc3_core_exit(dwc); 543 dwc3_core_exit(dwc);
592 544
545err0:
546 dwc3_free_event_buffers(dwc);
547
593 return ret; 548 return ret;
594} 549}
595 550
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 243affc93431..499956344262 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -868,7 +868,4 @@ void dwc3_host_exit(struct dwc3 *dwc);
868int dwc3_gadget_init(struct dwc3 *dwc); 868int dwc3_gadget_init(struct dwc3 *dwc);
869void dwc3_gadget_exit(struct dwc3 *dwc); 869void dwc3_gadget_exit(struct dwc3 *dwc);
870 870
871extern int dwc3_get_device_id(void);
872extern void dwc3_put_device_id(int id);
873
874#endif /* __DRIVERS_USB_DWC3_CORE_H */ 871#endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index ca6597853f90..dc35c5476f37 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -21,6 +21,7 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/usb/otg.h> 22#include <linux/usb/otg.h>
23#include <linux/usb/nop-usb-xceiv.h> 23#include <linux/usb/nop-usb-xceiv.h>
24#include <linux/of.h>
24 25
25#include "core.h" 26#include "core.h"
26 27
@@ -87,14 +88,14 @@ err1:
87 return ret; 88 return ret;
88} 89}
89 90
91static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
92
90static int __devinit dwc3_exynos_probe(struct platform_device *pdev) 93static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
91{ 94{
92 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
93 struct platform_device *dwc3; 95 struct platform_device *dwc3;
94 struct dwc3_exynos *exynos; 96 struct dwc3_exynos *exynos;
95 struct clk *clk; 97 struct clk *clk;
96 98
97 int devid;
98 int ret = -ENOMEM; 99 int ret = -ENOMEM;
99 100
100 exynos = kzalloc(sizeof(*exynos), GFP_KERNEL); 101 exynos = kzalloc(sizeof(*exynos), GFP_KERNEL);
@@ -103,11 +104,15 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
103 goto err0; 104 goto err0;
104 } 105 }
105 106
106 platform_set_drvdata(pdev, exynos); 107 /*
108 * Right now device-tree probed devices don't get dma_mask set.
109 * Since shared usb code relies on it, set it here for now.
110 * Once we move to full device tree support this will vanish off.
111 */
112 if (!pdev->dev.dma_mask)
113 pdev->dev.dma_mask = &dwc3_exynos_dma_mask;
107 114
108 devid = dwc3_get_device_id(); 115 platform_set_drvdata(pdev, exynos);
109 if (devid < 0)
110 goto err1;
111 116
112 ret = dwc3_exynos_register_phys(exynos); 117 ret = dwc3_exynos_register_phys(exynos);
113 if (ret) { 118 if (ret) {
@@ -115,10 +120,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
115 goto err1; 120 goto err1;
116 } 121 }
117 122
118 dwc3 = platform_device_alloc("dwc3", devid); 123 dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
119 if (!dwc3) { 124 if (!dwc3) {
120 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); 125 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
121 goto err2; 126 goto err1;
122 } 127 }
123 128
124 clk = clk_get(&pdev->dev, "usbdrd30"); 129 clk = clk_get(&pdev->dev, "usbdrd30");
@@ -139,14 +144,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
139 144
140 clk_enable(exynos->clk); 145 clk_enable(exynos->clk);
141 146
142 /* PHY initialization */
143 if (!pdata) {
144 dev_dbg(&pdev->dev, "missing platform data\n");
145 } else {
146 if (pdata->phy_init)
147 pdata->phy_init(pdev, pdata->phy_type);
148 }
149
150 ret = platform_device_add_resources(dwc3, pdev->resource, 147 ret = platform_device_add_resources(dwc3, pdev->resource,
151 pdev->num_resources); 148 pdev->num_resources);
152 if (ret) { 149 if (ret) {
@@ -163,15 +160,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
163 return 0; 160 return 0;
164 161
165err4: 162err4:
166 if (pdata && pdata->phy_exit)
167 pdata->phy_exit(pdev, pdata->phy_type);
168
169 clk_disable(clk); 163 clk_disable(clk);
170 clk_put(clk); 164 clk_put(clk);
171err3: 165err3:
172 platform_device_put(dwc3); 166 platform_device_put(dwc3);
173err2:
174 dwc3_put_device_id(devid);
175err1: 167err1:
176 kfree(exynos); 168 kfree(exynos);
177err0: 169err0:
@@ -181,17 +173,11 @@ err0:
181static int __devexit dwc3_exynos_remove(struct platform_device *pdev) 173static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
182{ 174{
183 struct dwc3_exynos *exynos = platform_get_drvdata(pdev); 175 struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
184 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
185 176
186 platform_device_unregister(exynos->dwc3); 177 platform_device_unregister(exynos->dwc3);
187 platform_device_unregister(exynos->usb2_phy); 178 platform_device_unregister(exynos->usb2_phy);
188 platform_device_unregister(exynos->usb3_phy); 179 platform_device_unregister(exynos->usb3_phy);
189 180
190 dwc3_put_device_id(exynos->dwc3->id);
191
192 if (pdata && pdata->phy_exit)
193 pdata->phy_exit(pdev, pdata->phy_type);
194
195 clk_disable(exynos->clk); 181 clk_disable(exynos->clk);
196 clk_put(exynos->clk); 182 clk_put(exynos->clk);
197 183
@@ -200,11 +186,20 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
200 return 0; 186 return 0;
201} 187}
202 188
189#ifdef CONFIG_OF
190static const struct of_device_id exynos_dwc3_match[] = {
191 { .compatible = "samsung,exynos-dwc3" },
192 {},
193};
194MODULE_DEVICE_TABLE(of, exynos_dwc3_match);
195#endif
196
203static struct platform_driver dwc3_exynos_driver = { 197static struct platform_driver dwc3_exynos_driver = {
204 .probe = dwc3_exynos_probe, 198 .probe = dwc3_exynos_probe,
205 .remove = __devexit_p(dwc3_exynos_remove), 199 .remove = __devexit_p(dwc3_exynos_remove),
206 .driver = { 200 .driver = {
207 .name = "exynos-dwc3", 201 .name = "exynos-dwc3",
202 .of_match_table = of_match_ptr(exynos_dwc3_match),
208 }, 203 },
209}; 204};
210 205
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index ee57a10d90d0..900d435f41d1 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -272,7 +272,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
272 struct resource *res; 272 struct resource *res;
273 struct device *dev = &pdev->dev; 273 struct device *dev = &pdev->dev;
274 274
275 int devid;
276 int size; 275 int size;
277 int ret = -ENOMEM; 276 int ret = -ENOMEM;
278 int irq; 277 int irq;
@@ -315,14 +314,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
315 return ret; 314 return ret;
316 } 315 }
317 316
318 devid = dwc3_get_device_id(); 317 dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
319 if (devid < 0)
320 return -ENODEV;
321
322 dwc3 = platform_device_alloc("dwc3", devid);
323 if (!dwc3) { 318 if (!dwc3) {
324 dev_err(dev, "couldn't allocate dwc3 device\n"); 319 dev_err(dev, "couldn't allocate dwc3 device\n");
325 goto err1; 320 return -ENOMEM;
326 } 321 }
327 322
328 context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); 323 context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL);
@@ -423,10 +418,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
423 418
424err2: 419err2:
425 platform_device_put(dwc3); 420 platform_device_put(dwc3);
426
427err1:
428 dwc3_put_device_id(devid);
429
430 return ret; 421 return ret;
431} 422}
432 423
@@ -437,9 +428,6 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev)
437 platform_device_unregister(omap->dwc3); 428 platform_device_unregister(omap->dwc3);
438 platform_device_unregister(omap->usb2_phy); 429 platform_device_unregister(omap->usb2_phy);
439 platform_device_unregister(omap->usb3_phy); 430 platform_device_unregister(omap->usb3_phy);
440
441 dwc3_put_device_id(omap->dwc3->id);
442
443 return 0; 431 return 0;
444} 432}
445 433
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 94f550e37f98..13962597f3fe 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -119,7 +119,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
119 struct platform_device *dwc3; 119 struct platform_device *dwc3;
120 struct dwc3_pci *glue; 120 struct dwc3_pci *glue;
121 int ret = -ENOMEM; 121 int ret = -ENOMEM;
122 int devid;
123 struct device *dev = &pci->dev; 122 struct device *dev = &pci->dev;
124 123
125 glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); 124 glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
@@ -145,13 +144,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
145 return ret; 144 return ret;
146 } 145 }
147 146
148 devid = dwc3_get_device_id(); 147 dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
149 if (devid < 0) {
150 ret = -ENOMEM;
151 goto err1;
152 }
153
154 dwc3 = platform_device_alloc("dwc3", devid);
155 if (!dwc3) { 148 if (!dwc3) {
156 dev_err(dev, "couldn't allocate dwc3 device\n"); 149 dev_err(dev, "couldn't allocate dwc3 device\n");
157 ret = -ENOMEM; 150 ret = -ENOMEM;
@@ -172,7 +165,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
172 ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); 165 ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
173 if (ret) { 166 if (ret) {
174 dev_err(dev, "couldn't add resources to dwc3 device\n"); 167 dev_err(dev, "couldn't add resources to dwc3 device\n");
175 goto err2; 168 goto err1;
176 } 169 }
177 170
178 pci_set_drvdata(pci, glue); 171 pci_set_drvdata(pci, glue);
@@ -195,10 +188,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
195err3: 188err3:
196 pci_set_drvdata(pci, NULL); 189 pci_set_drvdata(pci, NULL);
197 platform_device_put(dwc3); 190 platform_device_put(dwc3);
198
199err2:
200 dwc3_put_device_id(devid);
201
202err1: 191err1:
203 pci_disable_device(pci); 192 pci_disable_device(pci);
204 193
@@ -211,7 +200,6 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci)
211 200
212 platform_device_unregister(glue->usb2_phy); 201 platform_device_unregister(glue->usb2_phy);
213 platform_device_unregister(glue->usb3_phy); 202 platform_device_unregister(glue->usb3_phy);
214 dwc3_put_device_id(glue->dwc3->id);
215 platform_device_unregister(glue->dwc3); 203 platform_device_unregister(glue->dwc3);
216 pci_set_drvdata(pci, NULL); 204 pci_set_drvdata(pci, NULL);
217 pci_disable_device(pci); 205 pci_disable_device(pci);