aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorB, Ravi <ravibabu@ti.com>2012-08-31 07:09:51 -0400
committerFelipe Balbi <balbi@ti.com>2012-09-11 10:35:44 -0400
commitdb4a93202e086dbdb5789149666dbbff48f708bf (patch)
treeb4608556b3c7aff82bad75bc94219fa7ba377241 /drivers/usb/musb
parent8d2421e68cb8a159963641eab72f8f8ba1c7f7b0 (diff)
usb: musb: am335x: add support for dual instance
AM335x and TI81xx platform has dual musb controller so updating the musb_dspc.c to support the same. Changes: - Moved otg_workaround timer to glue structure - Moved static local variable last_timer to glue structure - PHY on/off related cleanups Signed-off-by: Ravi Babu <ravibabu@ti.com> Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> Signed-off-by: Santhapuri, Damodar <damodar.santhapuri@ti.com> [afzal@ti.com: remove control module related modifications] Signed-off-by: Afzal Mohammed <afzal@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/musb_dsps.c81
1 files changed, 49 insertions, 32 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 5351e960d650..796fc6085fce 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -105,6 +105,8 @@ struct dsps_musb_wrapper {
105 /* miscellaneous stuff */ 105 /* miscellaneous stuff */
106 u32 musb_core_offset; 106 u32 musb_core_offset;
107 u8 poll_seconds; 107 u8 poll_seconds;
108 /* number of musb instances */
109 u8 instances;
108}; 110};
109 111
110/** 112/**
@@ -112,9 +114,10 @@ struct dsps_musb_wrapper {
112 */ 114 */
113struct dsps_glue { 115struct dsps_glue {
114 struct device *dev; 116 struct device *dev;
115 struct platform_device *musb; /* child musb pdev */ 117 struct platform_device *musb[2]; /* child musb pdev */
116 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ 118 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
117 struct timer_list timer; /* otg_workaround timer */ 119 struct timer_list timer[2]; /* otg_workaround timer */
120 unsigned long last_timer[2]; /* last timer data for each instance */
118}; 121};
119 122
120/** 123/**
@@ -164,8 +167,8 @@ static void otg_timer(unsigned long _musb)
164 struct musb *musb = (void *)_musb; 167 struct musb *musb = (void *)_musb;
165 void __iomem *mregs = musb->mregs; 168 void __iomem *mregs = musb->mregs;
166 struct device *dev = musb->controller; 169 struct device *dev = musb->controller;
167 struct platform_device *pdev = to_platform_device(dev->parent); 170 struct platform_device *pdev = to_platform_device(dev);
168 struct dsps_glue *glue = platform_get_drvdata(pdev); 171 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
169 const struct dsps_musb_wrapper *wrp = glue->wrp; 172 const struct dsps_musb_wrapper *wrp = glue->wrp;
170 u8 devctl; 173 u8 devctl;
171 unsigned long flags; 174 unsigned long flags;
@@ -201,7 +204,7 @@ static void otg_timer(unsigned long _musb)
201 case OTG_STATE_B_IDLE: 204 case OTG_STATE_B_IDLE:
202 devctl = dsps_readb(mregs, MUSB_DEVCTL); 205 devctl = dsps_readb(mregs, MUSB_DEVCTL);
203 if (devctl & MUSB_DEVCTL_BDEVICE) 206 if (devctl & MUSB_DEVCTL_BDEVICE)
204 mod_timer(&glue->timer, 207 mod_timer(&glue->timer[pdev->id],
205 jiffies + wrp->poll_seconds * HZ); 208 jiffies + wrp->poll_seconds * HZ);
206 else 209 else
207 musb->xceiv->state = OTG_STATE_A_IDLE; 210 musb->xceiv->state = OTG_STATE_A_IDLE;
@@ -215,9 +218,8 @@ static void otg_timer(unsigned long _musb)
215static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) 218static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
216{ 219{
217 struct device *dev = musb->controller; 220 struct device *dev = musb->controller;
218 struct platform_device *pdev = to_platform_device(dev->parent); 221 struct platform_device *pdev = to_platform_device(dev);
219 struct dsps_glue *glue = platform_get_drvdata(pdev); 222 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
220 static unsigned long last_timer;
221 223
222 if (timeout == 0) 224 if (timeout == 0)
223 timeout = jiffies + msecs_to_jiffies(3); 225 timeout = jiffies + msecs_to_jiffies(3);
@@ -227,22 +229,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
227 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { 229 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
228 dev_dbg(musb->controller, "%s active, deleting timer\n", 230 dev_dbg(musb->controller, "%s active, deleting timer\n",
229 otg_state_string(musb->xceiv->state)); 231 otg_state_string(musb->xceiv->state));
230 del_timer(&glue->timer); 232 del_timer(&glue->timer[pdev->id]);
231 last_timer = jiffies; 233 glue->last_timer[pdev->id] = jiffies;
232 return; 234 return;
233 } 235 }
234 236
235 if (time_after(last_timer, timeout) && timer_pending(&glue->timer)) { 237 if (time_after(glue->last_timer[pdev->id], timeout) &&
238 timer_pending(&glue->timer[pdev->id])) {
236 dev_dbg(musb->controller, 239 dev_dbg(musb->controller,
237 "Longer idle timer already pending, ignoring...\n"); 240 "Longer idle timer already pending, ignoring...\n");
238 return; 241 return;
239 } 242 }
240 last_timer = timeout; 243 glue->last_timer[pdev->id] = timeout;
241 244
242 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", 245 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
243 otg_state_string(musb->xceiv->state), 246 otg_state_string(musb->xceiv->state),
244 jiffies_to_msecs(timeout - jiffies)); 247 jiffies_to_msecs(timeout - jiffies));
245 mod_timer(&glue->timer, timeout); 248 mod_timer(&glue->timer[pdev->id], timeout);
246} 249}
247 250
248static irqreturn_t dsps_interrupt(int irq, void *hci) 251static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -250,8 +253,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
250 struct musb *musb = hci; 253 struct musb *musb = hci;
251 void __iomem *reg_base = musb->ctrl_base; 254 void __iomem *reg_base = musb->ctrl_base;
252 struct device *dev = musb->controller; 255 struct device *dev = musb->controller;
253 struct platform_device *pdev = to_platform_device(dev->parent); 256 struct platform_device *pdev = to_platform_device(dev);
254 struct dsps_glue *glue = platform_get_drvdata(pdev); 257 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
255 const struct dsps_musb_wrapper *wrp = glue->wrp; 258 const struct dsps_musb_wrapper *wrp = glue->wrp;
256 unsigned long flags; 259 unsigned long flags;
257 irqreturn_t ret = IRQ_NONE; 260 irqreturn_t ret = IRQ_NONE;
@@ -310,7 +313,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
310 */ 313 */
311 musb->int_usb &= ~MUSB_INTR_VBUSERROR; 314 musb->int_usb &= ~MUSB_INTR_VBUSERROR;
312 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; 315 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
313 mod_timer(&glue->timer, 316 mod_timer(&glue->timer[pdev->id],
314 jiffies + wrp->poll_seconds * HZ); 317 jiffies + wrp->poll_seconds * HZ);
315 WARNING("VBUS error workaround (delay coming)\n"); 318 WARNING("VBUS error workaround (delay coming)\n");
316 } else if (drvvbus) { 319 } else if (drvvbus) {
@@ -318,7 +321,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
318 MUSB_HST_MODE(musb); 321 MUSB_HST_MODE(musb);
319 musb->xceiv->otg->default_a = 1; 322 musb->xceiv->otg->default_a = 1;
320 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 323 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
321 del_timer(&glue->timer); 324 del_timer(&glue->timer[pdev->id]);
322 } else { 325 } else {
323 musb->is_active = 0; 326 musb->is_active = 0;
324 MUSB_DEV_MODE(musb); 327 MUSB_DEV_MODE(musb);
@@ -345,7 +348,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
345 348
346 /* Poll for ID change */ 349 /* Poll for ID change */
347 if (musb->xceiv->state == OTG_STATE_B_IDLE) 350 if (musb->xceiv->state == OTG_STATE_B_IDLE)
348 mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); 351 mod_timer(&glue->timer[pdev->id],
352 jiffies + wrp->poll_seconds * HZ);
349 353
350 spin_unlock_irqrestore(&musb->lock, flags); 354 spin_unlock_irqrestore(&musb->lock, flags);
351 355
@@ -356,8 +360,8 @@ static int dsps_musb_init(struct musb *musb)
356{ 360{
357 struct device *dev = musb->controller; 361 struct device *dev = musb->controller;
358 struct musb_hdrc_platform_data *plat = dev->platform_data; 362 struct musb_hdrc_platform_data *plat = dev->platform_data;
359 struct platform_device *pdev = to_platform_device(dev->parent); 363 struct platform_device *pdev = to_platform_device(dev);
360 struct dsps_glue *glue = platform_get_drvdata(pdev); 364 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
361 const struct dsps_musb_wrapper *wrp = glue->wrp; 365 const struct dsps_musb_wrapper *wrp = glue->wrp;
362 struct omap_musb_board_data *data = plat->board_data; 366 struct omap_musb_board_data *data = plat->board_data;
363 void __iomem *reg_base = musb->ctrl_base; 367 void __iomem *reg_base = musb->ctrl_base;
@@ -380,7 +384,7 @@ static int dsps_musb_init(struct musb *musb)
380 goto err0; 384 goto err0;
381 } 385 }
382 386
383 setup_timer(&glue->timer, otg_timer, (unsigned long) musb); 387 setup_timer(&glue->timer[pdev->id], otg_timer, (unsigned long) musb);
384 388
385 /* Reset the musb */ 389 /* Reset the musb */
386 dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); 390 dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
@@ -411,10 +415,10 @@ static int dsps_musb_exit(struct musb *musb)
411 struct device *dev = musb->controller; 415 struct device *dev = musb->controller;
412 struct musb_hdrc_platform_data *plat = dev->platform_data; 416 struct musb_hdrc_platform_data *plat = dev->platform_data;
413 struct omap_musb_board_data *data = plat->board_data; 417 struct omap_musb_board_data *data = plat->board_data;
414 struct platform_device *pdev = to_platform_device(dev->parent); 418 struct platform_device *pdev = to_platform_device(dev);
415 struct dsps_glue *glue = platform_get_drvdata(pdev); 419 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
416 420
417 del_timer_sync(&glue->timer); 421 del_timer_sync(&glue->timer[pdev->id]);
418 422
419 /* Shutdown the on-chip PHY and its PLL. */ 423 /* Shutdown the on-chip PHY and its PLL. */
420 if (data->set_phy_power) 424 if (data->set_phy_power)
@@ -493,7 +497,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
493 musb->dev.dma_mask = &musb_dmamask; 497 musb->dev.dma_mask = &musb_dmamask;
494 musb->dev.coherent_dma_mask = musb_dmamask; 498 musb->dev.coherent_dma_mask = musb_dmamask;
495 499
496 glue->musb = musb; 500 glue->musb[id] = musb;
497 501
498 pdata->platform_ops = &dsps_ops; 502 pdata->platform_ops = &dsps_ops;
499 503
@@ -525,11 +529,11 @@ err0:
525 return ret; 529 return ret;
526} 530}
527 531
528static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue) 532static void dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id)
529{ 533{
530 musb_put_id(glue->dev, glue->musb->id); 534 musb_put_id(glue->dev, glue->musb[id]->id);
531 platform_device_del(glue->musb); 535 platform_device_del(glue->musb[id]);
532 platform_device_put(glue->musb); 536 platform_device_put(glue->musb[id]);
533} 537}
534 538
535static int __devinit dsps_probe(struct platform_device *pdev) 539static int __devinit dsps_probe(struct platform_device *pdev)
@@ -539,7 +543,7 @@ static int __devinit dsps_probe(struct platform_device *pdev)
539 (struct dsps_musb_wrapper *)id->driver_data; 543 (struct dsps_musb_wrapper *)id->driver_data;
540 struct dsps_glue *glue; 544 struct dsps_glue *glue;
541 struct resource *iomem; 545 struct resource *iomem;
542 int ret; 546 int ret, i;
543 547
544 /* allocate glue */ 548 /* allocate glue */
545 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 549 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
@@ -580,7 +584,16 @@ static int __devinit dsps_probe(struct platform_device *pdev)
580 ret = pm_runtime_get_sync(&pdev->dev); 584 ret = pm_runtime_get_sync(&pdev->dev);
581 if (ret < 0) { 585 if (ret < 0) {
582 dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); 586 dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
583 goto err3; 587 /* create the child platform device for all instances of musb */
588 for (i = 0; i < wrp->instances ; i++) {
589 ret = dsps_create_musb_pdev(glue, i);
590 if (ret != 0) {
591 dev_err(&pdev->dev, "failed to create child pdev\n");
592 /* release resources of previously created instances */
593 for (i--; i >= 0 ; i--)
594 dsps_delete_musb_pdev(glue, i);
595 goto err3;
596 }
584 } 597 }
585 598
586 return 0; 599 return 0;
@@ -597,9 +610,12 @@ err0:
597static int __devexit dsps_remove(struct platform_device *pdev) 610static int __devexit dsps_remove(struct platform_device *pdev)
598{ 611{
599 struct dsps_glue *glue = platform_get_drvdata(pdev); 612 struct dsps_glue *glue = platform_get_drvdata(pdev);
613 const struct dsps_musb_wrapper *wrp = glue->wrp;
614 int i;
600 615
601 /* delete the child platform device */ 616 /* delete the child platform device */
602 dsps_delete_musb_pdev(glue); 617 for (i = 0; i < wrp->instances ; i++)
618 dsps_delete_musb_pdev(glue, i);
603 619
604 /* disable usbss clocks */ 620 /* disable usbss clocks */
605 pm_runtime_put(&pdev->dev); 621 pm_runtime_put(&pdev->dev);
@@ -665,6 +681,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
665 .rxep_bitmap = (0xfffe << 16), 681 .rxep_bitmap = (0xfffe << 16),
666 .musb_core_offset = 0x400, 682 .musb_core_offset = 0x400,
667 .poll_seconds = 2, 683 .poll_seconds = 2,
684 .instances = 2,
668}; 685};
669 686
670static const struct platform_device_id musb_dsps_id_table[] __devinitconst = { 687static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {