aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-07-05 08:51:33 -0400
committerFelipe Balbi <balbi@ti.com>2013-08-09 10:35:44 -0400
commit97238b35d5bbb5d5312d83c30a429824b777619f (patch)
tree0c2940aa58416bda0139de29f822b4eefd0cdecc /drivers/usb
parente96bdc3dafe471375e2e780e319e3ead2d9ad4a7 (diff)
usb: musb: dsps: use proper child nodes
This moves the two instances from the big node into two child nodes. The glue layer ontop does almost nothing. There is one devices containing the control module for USB (2) phy, (2) usb and later the dma engine. The usb device is the "glue device" which contains the musb device as a child. This is what we do ever since. The new file musb_am335x is just here to prob the new bus and populate child devices. There are a lot of changes to the dsps file as a result of the changes: - musb_core_offset This is gone. The device tree provides memory ressources information for the device there is no need to "fix" things - instances This is gone as well. If we have two instances then we have have two child enabled nodes in the device tree. For instance the SoC in beagle bone has two USB instances but only one has been wired up so there is no need to load and init the second instance since it won't be used. - dsps_glue is now per glue device In the past there was one of this structs but with an array of two and each instance accessed its variable depending on the platform device id. - no unneeded copy of structs I do not know why struct dsps_musb_wrapper is copied but it is not necessary. The same goes for musb_hdrc_platform_data which allocated on demand and then again by platform_device_add_data(). One copy is enough. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/Kconfig4
-rw-r--r--drivers/usb/musb/Makefile3
-rw-r--r--drivers/usb/musb/musb_am335x.c55
-rw-r--r--drivers/usb/musb/musb_dsps.c255
4 files changed, 160 insertions, 157 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 797e3fd45510..b7257ae038fd 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -83,6 +83,7 @@ config USB_MUSB_AM35X
83 83
84config USB_MUSB_DSPS 84config USB_MUSB_DSPS
85 tristate "TI DSPS platforms" 85 tristate "TI DSPS platforms"
86 select USB_MUSB_AM335X_CHILD
86 87
87config USB_MUSB_BLACKFIN 88config USB_MUSB_BLACKFIN
88 tristate "Blackfin" 89 tristate "Blackfin"
@@ -93,6 +94,9 @@ config USB_MUSB_UX500
93 94
94endchoice 95endchoice
95 96
97config USB_MUSB_AM335X_CHILD
98 tristate
99
96choice 100choice
97 prompt 'MUSB DMA mode' 101 prompt 'MUSB DMA mode'
98 default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM 102 default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 2b82ed7c85ca..52f552c1ba2b 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o
20obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o 20obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o
21obj-$(CONFIG_USB_MUSB_UX500) += ux500.o 21obj-$(CONFIG_USB_MUSB_UX500) += ux500.o
22 22
23
24obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o
25
23# the kconfig must guarantee that only one of the 26# the kconfig must guarantee that only one of the
24# possible I/O schemes will be enabled at a time ... 27# possible I/O schemes will be enabled at a time ...
25# PIO only, or DMA (several potential schemes). 28# PIO only, or DMA (several potential schemes).
diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c
new file mode 100644
index 000000000000..41ac5b5b57ce
--- /dev/null
+++ b/drivers/usb/musb/musb_am335x.c
@@ -0,0 +1,55 @@
1#include <linux/init.h>
2#include <linux/platform_device.h>
3#include <linux/pm_runtime.h>
4#include <linux/module.h>
5#include <linux/of_platform.h>
6
7static int am335x_child_probe(struct platform_device *pdev)
8{
9 int ret;
10
11 pm_runtime_enable(&pdev->dev);
12
13 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
14 if (ret)
15 goto err;
16
17 return 0;
18err:
19 pm_runtime_disable(&pdev->dev);
20 return ret;
21}
22
23static int of_remove_populated_child(struct device *dev, void *d)
24{
25 struct platform_device *pdev = to_platform_device(dev);
26
27 of_device_unregister(pdev);
28 return 0;
29}
30
31static int am335x_child_remove(struct platform_device *pdev)
32{
33 device_for_each_child(&pdev->dev, NULL, of_remove_populated_child);
34 pm_runtime_disable(&pdev->dev);
35 return 0;
36}
37
38static const struct of_device_id am335x_child_of_match[] = {
39 { .compatible = "ti,am33xx-usb" },
40 { },
41};
42MODULE_DEVICE_TABLE(of, am335x_child_of_match);
43
44static struct platform_driver am335x_child_driver = {
45 .probe = am335x_child_probe,
46 .remove = am335x_child_remove,
47 .driver = {
48 .name = "am335x-usb-childs",
49 .of_match_table = of_match_ptr(am335x_child_of_match),
50 },
51};
52
53module_platform_driver(am335x_child_driver);
54MODULE_DESCRIPTION("AM33xx child devices");
55MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 74333321cb62..4ffbaace7913 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -43,6 +43,7 @@
43#include <linux/of.h> 43#include <linux/of.h>
44#include <linux/of_device.h> 44#include <linux/of_device.h>
45#include <linux/of_address.h> 45#include <linux/of_address.h>
46#include <linux/of_irq.h>
46 47
47#include "musb_core.h" 48#include "musb_core.h"
48 49
@@ -105,10 +106,7 @@ struct dsps_musb_wrapper {
105 /* bit positions for mode */ 106 /* bit positions for mode */
106 unsigned iddig:5; 107 unsigned iddig:5;
107 /* miscellaneous stuff */ 108 /* miscellaneous stuff */
108 u32 musb_core_offset;
109 u8 poll_seconds; 109 u8 poll_seconds;
110 /* number of musb instances */
111 u8 instances;
112}; 110};
113 111
114/** 112/**
@@ -116,10 +114,10 @@ struct dsps_musb_wrapper {
116 */ 114 */
117struct dsps_glue { 115struct dsps_glue {
118 struct device *dev; 116 struct device *dev;
119 struct platform_device *musb[2]; /* child musb pdev */ 117 struct platform_device *musb; /* child musb pdev */
120 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ 118 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
121 struct timer_list timer[2]; /* otg_workaround timer */ 119 struct timer_list timer; /* otg_workaround timer */
122 unsigned long last_timer[2]; /* last timer data for each instance */ 120 unsigned long last_timer; /* last timer data for each instance */
123}; 121};
124 122
125/** 123/**
@@ -168,7 +166,6 @@ static void otg_timer(unsigned long _musb)
168 struct musb *musb = (void *)_musb; 166 struct musb *musb = (void *)_musb;
169 void __iomem *mregs = musb->mregs; 167 void __iomem *mregs = musb->mregs;
170 struct device *dev = musb->controller; 168 struct device *dev = musb->controller;
171 struct platform_device *pdev = to_platform_device(dev);
172 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 169 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
173 const struct dsps_musb_wrapper *wrp = glue->wrp; 170 const struct dsps_musb_wrapper *wrp = glue->wrp;
174 u8 devctl; 171 u8 devctl;
@@ -205,7 +202,7 @@ static void otg_timer(unsigned long _musb)
205 case OTG_STATE_B_IDLE: 202 case OTG_STATE_B_IDLE:
206 devctl = dsps_readb(mregs, MUSB_DEVCTL); 203 devctl = dsps_readb(mregs, MUSB_DEVCTL);
207 if (devctl & MUSB_DEVCTL_BDEVICE) 204 if (devctl & MUSB_DEVCTL_BDEVICE)
208 mod_timer(&glue->timer[pdev->id], 205 mod_timer(&glue->timer,
209 jiffies + wrp->poll_seconds * HZ); 206 jiffies + wrp->poll_seconds * HZ);
210 else 207 else
211 musb->xceiv->state = OTG_STATE_A_IDLE; 208 musb->xceiv->state = OTG_STATE_A_IDLE;
@@ -219,7 +216,6 @@ static void otg_timer(unsigned long _musb)
219static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) 216static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
220{ 217{
221 struct device *dev = musb->controller; 218 struct device *dev = musb->controller;
222 struct platform_device *pdev = to_platform_device(dev);
223 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 219 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
224 220
225 if (timeout == 0) 221 if (timeout == 0)
@@ -230,23 +226,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
230 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { 226 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
231 dev_dbg(musb->controller, "%s active, deleting timer\n", 227 dev_dbg(musb->controller, "%s active, deleting timer\n",
232 usb_otg_state_string(musb->xceiv->state)); 228 usb_otg_state_string(musb->xceiv->state));
233 del_timer(&glue->timer[pdev->id]); 229 del_timer(&glue->timer);
234 glue->last_timer[pdev->id] = jiffies; 230 glue->last_timer = jiffies;
235 return; 231 return;
236 } 232 }
237 233
238 if (time_after(glue->last_timer[pdev->id], timeout) && 234 if (time_after(glue->last_timer, timeout) &&
239 timer_pending(&glue->timer[pdev->id])) { 235 timer_pending(&glue->timer)) {
240 dev_dbg(musb->controller, 236 dev_dbg(musb->controller,
241 "Longer idle timer already pending, ignoring...\n"); 237 "Longer idle timer already pending, ignoring...\n");
242 return; 238 return;
243 } 239 }
244 glue->last_timer[pdev->id] = timeout; 240 glue->last_timer = timeout;
245 241
246 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", 242 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
247 usb_otg_state_string(musb->xceiv->state), 243 usb_otg_state_string(musb->xceiv->state),
248 jiffies_to_msecs(timeout - jiffies)); 244 jiffies_to_msecs(timeout - jiffies));
249 mod_timer(&glue->timer[pdev->id], timeout); 245 mod_timer(&glue->timer, timeout);
250} 246}
251 247
252static irqreturn_t dsps_interrupt(int irq, void *hci) 248static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -254,7 +250,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
254 struct musb *musb = hci; 250 struct musb *musb = hci;
255 void __iomem *reg_base = musb->ctrl_base; 251 void __iomem *reg_base = musb->ctrl_base;
256 struct device *dev = musb->controller; 252 struct device *dev = musb->controller;
257 struct platform_device *pdev = to_platform_device(dev);
258 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 253 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
259 const struct dsps_musb_wrapper *wrp = glue->wrp; 254 const struct dsps_musb_wrapper *wrp = glue->wrp;
260 unsigned long flags; 255 unsigned long flags;
@@ -314,7 +309,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
314 */ 309 */
315 musb->int_usb &= ~MUSB_INTR_VBUSERROR; 310 musb->int_usb &= ~MUSB_INTR_VBUSERROR;
316 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; 311 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
317 mod_timer(&glue->timer[pdev->id], 312 mod_timer(&glue->timer,
318 jiffies + wrp->poll_seconds * HZ); 313 jiffies + wrp->poll_seconds * HZ);
319 WARNING("VBUS error workaround (delay coming)\n"); 314 WARNING("VBUS error workaround (delay coming)\n");
320 } else if (drvvbus) { 315 } else if (drvvbus) {
@@ -322,7 +317,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
322 MUSB_HST_MODE(musb); 317 MUSB_HST_MODE(musb);
323 musb->xceiv->otg->default_a = 1; 318 musb->xceiv->otg->default_a = 1;
324 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 319 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
325 del_timer(&glue->timer[pdev->id]); 320 del_timer(&glue->timer);
326 } else { 321 } else {
327 musb->is_active = 0; 322 musb->is_active = 0;
328 MUSB_DEV_MODE(musb); 323 MUSB_DEV_MODE(musb);
@@ -344,8 +339,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
344 339
345 /* Poll for ID change */ 340 /* Poll for ID change */
346 if (musb->xceiv->state == OTG_STATE_B_IDLE) 341 if (musb->xceiv->state == OTG_STATE_B_IDLE)
347 mod_timer(&glue->timer[pdev->id], 342 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
348 jiffies + wrp->poll_seconds * HZ);
349out: 343out:
350 spin_unlock_irqrestore(&musb->lock, flags); 344 spin_unlock_irqrestore(&musb->lock, flags);
351 345
@@ -355,31 +349,34 @@ out:
355static int dsps_musb_init(struct musb *musb) 349static int dsps_musb_init(struct musb *musb)
356{ 350{
357 struct device *dev = musb->controller; 351 struct device *dev = musb->controller;
358 struct platform_device *pdev = to_platform_device(dev);
359 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 352 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
353 struct platform_device *parent = to_platform_device(dev->parent);
360 const struct dsps_musb_wrapper *wrp = glue->wrp; 354 const struct dsps_musb_wrapper *wrp = glue->wrp;
361 void __iomem *reg_base = musb->ctrl_base; 355 void __iomem *reg_base;
356 struct resource *r;
362 u32 rev, val; 357 u32 rev, val;
363 int status;
364 358
365 /* mentor core register starts at offset of 0x400 from musb base */ 359 r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control");
366 musb->mregs += wrp->musb_core_offset; 360 if (!r)
361 return -EINVAL;
362
363 reg_base = devm_ioremap_resource(dev, r);
364 if (!musb->ctrl_base)
365 return -EINVAL;
366 musb->ctrl_base = reg_base;
367 367
368 /* NOP driver needs change if supporting dual instance */ 368 /* NOP driver needs change if supporting dual instance */
369 musb->xceiv = devm_usb_get_phy_by_phandle(glue->dev, "phys", 0); 369 musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
370 if (IS_ERR_OR_NULL(musb->xceiv)) 370 if (IS_ERR(musb->xceiv))
371 return -EPROBE_DEFER; 371 return PTR_ERR(musb->xceiv);
372 372
373 /* Returns zero if e.g. not clocked */ 373 /* Returns zero if e.g. not clocked */
374 rev = dsps_readl(reg_base, wrp->revision); 374 rev = dsps_readl(reg_base, wrp->revision);
375 if (!rev) { 375 if (!rev)
376 status = -ENODEV; 376 return -ENODEV;
377 goto err0;
378 }
379 377
380 usb_phy_init(musb->xceiv); 378 usb_phy_init(musb->xceiv);
381 379 setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
382 setup_timer(&glue->timer[pdev->id], otg_timer, (unsigned long) musb);
383 380
384 /* Reset the musb */ 381 /* Reset the musb */
385 dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); 382 dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
@@ -392,17 +389,14 @@ static int dsps_musb_init(struct musb *musb)
392 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); 389 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
393 390
394 return 0; 391 return 0;
395err0:
396 return status;
397} 392}
398 393
399static int dsps_musb_exit(struct musb *musb) 394static int dsps_musb_exit(struct musb *musb)
400{ 395{
401 struct device *dev = musb->controller; 396 struct device *dev = musb->controller;
402 struct platform_device *pdev = to_platform_device(dev);
403 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 397 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
404 398
405 del_timer_sync(&glue->timer[pdev->id]); 399 del_timer_sync(&glue->timer);
406 400
407 usb_phy_shutdown(musb->xceiv); 401 usb_phy_shutdown(musb->xceiv);
408 return 0; 402 return 0;
@@ -420,106 +414,98 @@ static struct musb_platform_ops dsps_ops = {
420 414
421static u64 musb_dmamask = DMA_BIT_MASK(32); 415static u64 musb_dmamask = DMA_BIT_MASK(32);
422 416
423static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) 417static int get_int_prop(struct device_node *dn, const char *s)
424{ 418{
425 struct device *dev = glue->dev; 419 int ret;
426 struct platform_device *pdev = to_platform_device(dev); 420 u32 val;
427 struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); 421
428 struct device_node *np = pdev->dev.of_node; 422 ret = of_property_read_u32(dn, s, &val);
429 struct musb_hdrc_config *config; 423 if (ret)
430 struct platform_device *musb; 424 return 0;
431 struct resource *res; 425 return val;
426}
427
428static int dsps_create_musb_pdev(struct dsps_glue *glue,
429 struct platform_device *parent)
430{
431 struct musb_hdrc_platform_data pdata;
432 struct resource resources[2]; 432 struct resource resources[2];
433 char res_name[11]; 433 struct device *dev = &parent->dev;
434 struct musb_hdrc_config *config;
435 struct platform_device *musb;
436 struct device_node *dn = parent->dev.of_node;
437 struct device_node *child_node;
434 int ret; 438 int ret;
435 439
436 /* first resource is for usbss, so start index from 1 */ 440 child_node = of_get_child_by_name(dn, "usb");
437 res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1); 441 if (!child_node)
438 if (!res) { 442 return -EINVAL;
439 dev_err(dev, "failed to get memory for instance %d\n", id); 443
440 ret = -ENODEV; 444 memset(resources, 0, sizeof(resources));
441 goto err0; 445 ret = of_address_to_resource(child_node, 0, &resources[0]);
446 if (ret) {
447 dev_err(dev, "failed to get memory.\n");
448 return ret;
442 } 449 }
443 res->parent = NULL; 450
444 resources[0] = *res; 451 ret = of_irq_to_resource(child_node, 0, &resources[1]);
445 452 if (ret == 0) {
446 /* first resource is for usbss, so start index from 1 */ 453 dev_err(dev, "failed to get irq.\n");
447 res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1); 454 ret = -EINVAL;
448 if (!res) { 455 return ret;
449 dev_err(dev, "failed to get irq for instance %d\n", id);
450 ret = -ENODEV;
451 goto err0;
452 } 456 }
453 res->parent = NULL;
454 resources[1] = *res;
455 resources[1].name = "mc";
456 457
457 /* allocate the child platform device */ 458 /* allocate the child platform device */
458 musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); 459 musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
459 if (!musb) { 460 if (!musb) {
460 dev_err(dev, "failed to allocate musb device\n"); 461 dev_err(dev, "failed to allocate musb device\n");
461 ret = -ENOMEM; 462 return -ENOMEM;
462 goto err0;
463 } 463 }
464 464
465 musb->dev.parent = dev; 465 musb->dev.parent = dev;
466 musb->dev.dma_mask = &musb_dmamask; 466 musb->dev.dma_mask = &musb_dmamask;
467 musb->dev.coherent_dma_mask = musb_dmamask; 467 musb->dev.coherent_dma_mask = musb_dmamask;
468 musb->dev.of_node = of_node_get(child_node);
468 469
469 glue->musb[id] = musb; 470 glue->musb = musb;
470 471
471 ret = platform_device_add_resources(musb, resources, 2); 472 ret = platform_device_add_resources(musb, resources,
473 ARRAY_SIZE(resources));
472 if (ret) { 474 if (ret) {
473 dev_err(dev, "failed to add resources\n"); 475 dev_err(dev, "failed to add resources\n");
474 goto err2; 476 goto err;
475 } 477 }
476 478
477 if (np) { 479 config = devm_kzalloc(&parent->dev, sizeof(*config), GFP_KERNEL);
478 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 480 if (!config) {
479 if (!pdata) { 481 dev_err(dev, "failed to allocate musb hdrc config\n");
480 dev_err(&pdev->dev, 482 ret = -ENOMEM;
481 "failed to allocate musb platform data\n"); 483 goto err;
482 ret = -ENOMEM;
483 goto err2;
484 }
485
486 config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
487 if (!config) {
488 dev_err(&pdev->dev,
489 "failed to allocate musb hdrc config\n");
490 ret = -ENOMEM;
491 goto err2;
492 }
493
494 of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
495 of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
496 snprintf(res_name, sizeof(res_name), "port%d-mode", id);
497 of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
498 of_property_read_u32(np, "power", (u32 *)&pdata->power);
499 config->multipoint = of_property_read_bool(np, "multipoint");
500
501 pdata->config = config;
502 } 484 }
485 pdata.config = config;
486 pdata.platform_ops = &dsps_ops;
503 487
504 pdata->platform_ops = &dsps_ops; 488 config->num_eps = get_int_prop(child_node, "num-eps");
489 config->ram_bits = get_int_prop(child_node, "ram-bits");
490 pdata.mode = get_int_prop(child_node, "port-mode");
491 pdata.power = get_int_prop(child_node, "power");
492 config->multipoint = of_property_read_bool(child_node, "multipoint");
505 493
506 ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); 494 ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
507 if (ret) { 495 if (ret) {
508 dev_err(dev, "failed to add platform_data\n"); 496 dev_err(dev, "failed to add platform_data\n");
509 goto err2; 497 goto err;
510 } 498 }
511 499
512 ret = platform_device_add(musb); 500 ret = platform_device_add(musb);
513 if (ret) { 501 if (ret) {
514 dev_err(dev, "failed to register musb device\n"); 502 dev_err(dev, "failed to register musb device\n");
515 goto err2; 503 goto err;
516 } 504 }
517
518 return 0; 505 return 0;
519 506
520err2: 507err:
521 platform_device_put(musb); 508 platform_device_put(musb);
522err0:
523 return ret; 509 return ret;
524} 510}
525 511
@@ -528,14 +514,12 @@ static int dsps_probe(struct platform_device *pdev)
528 const struct of_device_id *match; 514 const struct of_device_id *match;
529 const struct dsps_musb_wrapper *wrp; 515 const struct dsps_musb_wrapper *wrp;
530 struct dsps_glue *glue; 516 struct dsps_glue *glue;
531 struct resource *iomem; 517 int ret;
532 int ret, i;
533 518
534 match = of_match_node(musb_dsps_of_match, pdev->dev.of_node); 519 match = of_match_node(musb_dsps_of_match, pdev->dev.of_node);
535 if (!match) { 520 if (!match) {
536 dev_err(&pdev->dev, "fail to get matching of_match struct\n"); 521 dev_err(&pdev->dev, "fail to get matching of_match struct\n");
537 ret = -EINVAL; 522 return -EINVAL;
538 goto err0;
539 } 523 }
540 wrp = match->data; 524 wrp = match->data;
541 525
@@ -543,29 +527,13 @@ static int dsps_probe(struct platform_device *pdev)
543 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 527 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
544 if (!glue) { 528 if (!glue) {
545 dev_err(&pdev->dev, "unable to allocate glue memory\n"); 529 dev_err(&pdev->dev, "unable to allocate glue memory\n");
546 ret = -ENOMEM; 530 return -ENOMEM;
547 goto err0;
548 }
549
550 /* get memory resource */
551 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
552 if (!iomem) {
553 dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
554 ret = -ENODEV;
555 goto err1;
556 } 531 }
557 532
558 glue->dev = &pdev->dev; 533 glue->dev = &pdev->dev;
534 glue->wrp = wrp;
559 535
560 glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
561 if (!glue->wrp) {
562 dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
563 ret = -ENOMEM;
564 goto err1;
565 }
566 platform_set_drvdata(pdev, glue); 536 platform_set_drvdata(pdev, glue);
567
568 /* enable the usbss clocks */
569 pm_runtime_enable(&pdev->dev); 537 pm_runtime_enable(&pdev->dev);
570 538
571 ret = pm_runtime_get_sync(&pdev->dev); 539 ret = pm_runtime_get_sync(&pdev->dev);
@@ -574,17 +542,9 @@ static int dsps_probe(struct platform_device *pdev)
574 goto err2; 542 goto err2;
575 } 543 }
576 544
577 /* create the child platform device for all instances of musb */ 545 ret = dsps_create_musb_pdev(glue, pdev);
578 for (i = 0; i < wrp->instances ; i++) { 546 if (ret)
579 ret = dsps_create_musb_pdev(glue, i); 547 goto err3;
580 if (ret != 0) {
581 dev_err(&pdev->dev, "failed to create child pdev\n");
582 /* release resources of previously created instances */
583 for (i--; i >= 0 ; i--)
584 platform_device_unregister(glue->musb[i]);
585 goto err3;
586 }
587 }
588 548
589 return 0; 549 return 0;
590 550
@@ -592,26 +552,19 @@ err3:
592 pm_runtime_put(&pdev->dev); 552 pm_runtime_put(&pdev->dev);
593err2: 553err2:
594 pm_runtime_disable(&pdev->dev); 554 pm_runtime_disable(&pdev->dev);
595 kfree(glue->wrp);
596err1:
597 kfree(glue); 555 kfree(glue);
598err0:
599 return ret; 556 return ret;
600} 557}
558
601static int dsps_remove(struct platform_device *pdev) 559static int dsps_remove(struct platform_device *pdev)
602{ 560{
603 struct dsps_glue *glue = platform_get_drvdata(pdev); 561 struct dsps_glue *glue = platform_get_drvdata(pdev);
604 const struct dsps_musb_wrapper *wrp = glue->wrp;
605 int i;
606 562
607 /* delete the child platform device */ 563 platform_device_unregister(glue->musb);
608 for (i = 0; i < wrp->instances ; i++)
609 platform_device_unregister(glue->musb[i]);
610 564
611 /* disable usbss clocks */ 565 /* disable usbss clocks */
612 pm_runtime_put(&pdev->dev); 566 pm_runtime_put(&pdev->dev);
613 pm_runtime_disable(&pdev->dev); 567 pm_runtime_disable(&pdev->dev);
614 kfree(glue->wrp);
615 kfree(glue); 568 kfree(glue);
616 return 0; 569 return 0;
617} 570}
@@ -641,9 +594,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = {
641 .rxep_shift = 16, 594 .rxep_shift = 16,
642 .rxep_mask = 0xfffe, 595 .rxep_mask = 0xfffe,
643 .rxep_bitmap = (0xfffe << 16), 596 .rxep_bitmap = (0xfffe << 16),
644 .musb_core_offset = 0x400,
645 .poll_seconds = 2, 597 .poll_seconds = 2,
646 .instances = 1,
647}; 598};
648 599
649static const struct of_device_id musb_dsps_of_match[] = { 600static const struct of_device_id musb_dsps_of_match[] = {
@@ -667,14 +618,4 @@ MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
667MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>"); 618MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
668MODULE_LICENSE("GPL v2"); 619MODULE_LICENSE("GPL v2");
669 620
670static int __init dsps_init(void) 621module_platform_driver(dsps_usbss_driver);
671{
672 return platform_driver_register(&dsps_usbss_driver);
673}
674subsys_initcall(dsps_init);
675
676static void __exit dsps_exit(void)
677{
678 platform_driver_unregister(&dsps_usbss_driver);
679}
680module_exit(dsps_exit);