aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_dsps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musb_dsps.c')
-rw-r--r--drivers/usb/musb/musb_dsps.c141
1 files changed, 83 insertions, 58 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index ff5f112053d2..9a975aa0dee2 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -124,8 +124,44 @@ struct dsps_glue {
124 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ 124 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
125 struct timer_list timer[2]; /* otg_workaround timer */ 125 struct timer_list timer[2]; /* otg_workaround timer */
126 unsigned long last_timer[2]; /* last timer data for each instance */ 126 unsigned long last_timer[2]; /* last timer data for each instance */
127 u32 __iomem *usb_ctrl[2];
127}; 128};
128 129
130#define DSPS_AM33XX_CONTROL_MODULE_PHYS_0 0x44e10620
131#define DSPS_AM33XX_CONTROL_MODULE_PHYS_1 0x44e10628
132
133static const resource_size_t dsps_control_module_phys[] = {
134 DSPS_AM33XX_CONTROL_MODULE_PHYS_0,
135 DSPS_AM33XX_CONTROL_MODULE_PHYS_1,
136};
137
138/**
139 * musb_dsps_phy_control - phy on/off
140 * @glue: struct dsps_glue *
141 * @id: musb instance
142 * @on: flag for phy to be switched on or off
143 *
144 * This is to enable the PHY using usb_ctrl register in system control
145 * module space.
146 *
147 * XXX: This function will be removed once we have a seperate driver for
148 * control module
149 */
150static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on)
151{
152 u32 usbphycfg;
153
154 usbphycfg = readl(glue->usb_ctrl[id]);
155
156 if (on) {
157 usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
158 usbphycfg |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
159 } else {
160 usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
161 }
162
163 writel(usbphycfg, glue->usb_ctrl[id]);
164}
129/** 165/**
130 * dsps_musb_enable - enable interrupts 166 * dsps_musb_enable - enable interrupts
131 */ 167 */
@@ -296,7 +332,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
296 * Also, DRVVBUS pulses for SRP (but not at 5V) ... 332 * Also, DRVVBUS pulses for SRP (but not at 5V) ...
297 */ 333 */
298 if (usbintr & MUSB_INTR_BABBLE) 334 if (usbintr & MUSB_INTR_BABBLE)
299 pr_info("CAUTION: musb: Babble Interrupt Occured\n"); 335 pr_info("CAUTION: musb: Babble Interrupt Occurred\n");
300 336
301 if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { 337 if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
302 int drvvbus = dsps_readl(reg_base, wrp->status); 338 int drvvbus = dsps_readl(reg_base, wrp->status);
@@ -365,11 +401,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
365static int dsps_musb_init(struct musb *musb) 401static int dsps_musb_init(struct musb *musb)
366{ 402{
367 struct device *dev = musb->controller; 403 struct device *dev = musb->controller;
368 struct musb_hdrc_platform_data *plat = dev->platform_data;
369 struct platform_device *pdev = to_platform_device(dev); 404 struct platform_device *pdev = to_platform_device(dev);
370 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 405 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
371 const struct dsps_musb_wrapper *wrp = glue->wrp; 406 const struct dsps_musb_wrapper *wrp = glue->wrp;
372 struct omap_musb_board_data *data = plat->board_data;
373 void __iomem *reg_base = musb->ctrl_base; 407 void __iomem *reg_base = musb->ctrl_base;
374 u32 rev, val; 408 u32 rev, val;
375 int status; 409 int status;
@@ -377,7 +411,8 @@ static int dsps_musb_init(struct musb *musb)
377 /* mentor core register starts at offset of 0x400 from musb base */ 411 /* mentor core register starts at offset of 0x400 from musb base */
378 musb->mregs += wrp->musb_core_offset; 412 musb->mregs += wrp->musb_core_offset;
379 413
380 /* Get the NOP PHY */ 414 /* NOP driver needs change if supporting dual instance */
415 usb_nop_xceiv_register();
381 musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); 416 musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
382 if (IS_ERR_OR_NULL(musb->xceiv)) 417 if (IS_ERR_OR_NULL(musb->xceiv))
383 return -ENODEV; 418 return -ENODEV;
@@ -395,8 +430,7 @@ static int dsps_musb_init(struct musb *musb)
395 dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); 430 dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
396 431
397 /* Start the on-chip PHY and its PLL. */ 432 /* Start the on-chip PHY and its PLL. */
398 if (data->set_phy_power) 433 musb_dsps_phy_control(glue, pdev->id, 1);
399 data->set_phy_power(1);
400 434
401 musb->isr = dsps_interrupt; 435 musb->isr = dsps_interrupt;
402 436
@@ -418,16 +452,13 @@ err0:
418static int dsps_musb_exit(struct musb *musb) 452static int dsps_musb_exit(struct musb *musb)
419{ 453{
420 struct device *dev = musb->controller; 454 struct device *dev = musb->controller;
421 struct musb_hdrc_platform_data *plat = dev->platform_data;
422 struct omap_musb_board_data *data = plat->board_data;
423 struct platform_device *pdev = to_platform_device(dev); 455 struct platform_device *pdev = to_platform_device(dev);
424 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 456 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
425 457
426 del_timer_sync(&glue->timer[pdev->id]); 458 del_timer_sync(&glue->timer[pdev->id]);
427 459
428 /* Shutdown the on-chip PHY and its PLL. */ 460 /* Shutdown the on-chip PHY and its PLL. */
429 if (data->set_phy_power) 461 musb_dsps_phy_control(glue, pdev->id, 0);
430 data->set_phy_power(0);
431 462
432 /* NOP driver needs change if supporting dual instance */ 463 /* NOP driver needs change if supporting dual instance */
433 usb_put_phy(musb->xceiv); 464 usb_put_phy(musb->xceiv);
@@ -448,7 +479,7 @@ static struct musb_platform_ops dsps_ops = {
448 479
449static u64 musb_dmamask = DMA_BIT_MASK(32); 480static u64 musb_dmamask = DMA_BIT_MASK(32);
450 481
451static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) 482static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
452{ 483{
453 struct device *dev = glue->dev; 484 struct device *dev = glue->dev;
454 struct platform_device *pdev = to_platform_device(dev); 485 struct platform_device *pdev = to_platform_device(dev);
@@ -459,24 +490,33 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
459 struct resource *res; 490 struct resource *res;
460 struct resource resources[2]; 491 struct resource resources[2];
461 char res_name[11]; 492 char res_name[11];
462 int ret, musbid; 493 int ret;
463 494
464 /* get memory resource */ 495 resources[0].start = dsps_control_module_phys[id];
465 snprintf(res_name, sizeof(res_name), "musb%d", id); 496 resources[0].end = resources[0].start + SZ_4 - 1;
466 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); 497 resources[0].flags = IORESOURCE_MEM;
498
499 glue->usb_ctrl[id] = devm_request_and_ioremap(&pdev->dev, resources);
500 if (glue->usb_ctrl[id] == NULL) {
501 dev_err(dev, "Failed to obtain usb_ctrl%d memory\n", id);
502 ret = -ENODEV;
503 goto err0;
504 }
505
506 /* first resource is for usbss, so start index from 1 */
507 res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
467 if (!res) { 508 if (!res) {
468 dev_err(dev, "%s get mem resource failed\n", res_name); 509 dev_err(dev, "failed to get memory for instance %d\n", id);
469 ret = -ENODEV; 510 ret = -ENODEV;
470 goto err0; 511 goto err0;
471 } 512 }
472 res->parent = NULL; 513 res->parent = NULL;
473 resources[0] = *res; 514 resources[0] = *res;
474 515
475 /* get irq resource */ 516 /* first resource is for usbss, so start index from 1 */
476 snprintf(res_name, sizeof(res_name), "musb%d-irq", id); 517 res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1);
477 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
478 if (!res) { 518 if (!res) {
479 dev_err(dev, "%s get irq resource failed\n", res_name); 519 dev_err(dev, "failed to get irq for instance %d\n", id);
480 ret = -ENODEV; 520 ret = -ENODEV;
481 goto err0; 521 goto err0;
482 } 522 }
@@ -484,22 +524,14 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
484 resources[1] = *res; 524 resources[1] = *res;
485 resources[1].name = "mc"; 525 resources[1].name = "mc";
486 526
487 /* get the musb id */
488 musbid = musb_get_id(dev, GFP_KERNEL);
489 if (musbid < 0) {
490 dev_err(dev, "failed to allocate musb id\n");
491 ret = -ENOMEM;
492 goto err0;
493 }
494 /* allocate the child platform device */ 527 /* allocate the child platform device */
495 musb = platform_device_alloc("musb-hdrc", musbid); 528 musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
496 if (!musb) { 529 if (!musb) {
497 dev_err(dev, "failed to allocate musb device\n"); 530 dev_err(dev, "failed to allocate musb device\n");
498 ret = -ENOMEM; 531 ret = -ENOMEM;
499 goto err1; 532 goto err0;
500 } 533 }
501 534
502 musb->id = musbid;
503 musb->dev.parent = dev; 535 musb->dev.parent = dev;
504 musb->dev.dma_mask = &musb_dmamask; 536 musb->dev.dma_mask = &musb_dmamask;
505 musb->dev.coherent_dma_mask = musb_dmamask; 537 musb->dev.coherent_dma_mask = musb_dmamask;
@@ -556,20 +588,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
556 588
557err2: 589err2:
558 platform_device_put(musb); 590 platform_device_put(musb);
559err1:
560 musb_put_id(dev, musbid);
561err0: 591err0:
562 return ret; 592 return ret;
563} 593}
564 594
565static void dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id) 595static int dsps_probe(struct platform_device *pdev)
566{
567 musb_put_id(glue->dev, glue->musb[id]->id);
568 platform_device_del(glue->musb[id]);
569 platform_device_put(glue->musb[id]);
570}
571
572static int __devinit dsps_probe(struct platform_device *pdev)
573{ 596{
574 struct device_node *np = pdev->dev.of_node; 597 struct device_node *np = pdev->dev.of_node;
575 const struct of_device_id *match; 598 const struct of_device_id *match;
@@ -628,7 +651,7 @@ static int __devinit dsps_probe(struct platform_device *pdev)
628 dev_err(&pdev->dev, "failed to create child pdev\n"); 651 dev_err(&pdev->dev, "failed to create child pdev\n");
629 /* release resources of previously created instances */ 652 /* release resources of previously created instances */
630 for (i--; i >= 0 ; i--) 653 for (i--; i >= 0 ; i--)
631 dsps_delete_musb_pdev(glue, i); 654 platform_device_unregister(glue->musb[i]);
632 goto err3; 655 goto err3;
633 } 656 }
634 } 657 }
@@ -645,7 +668,7 @@ err1:
645err0: 668err0:
646 return ret; 669 return ret;
647} 670}
648static int __devexit dsps_remove(struct platform_device *pdev) 671static int dsps_remove(struct platform_device *pdev)
649{ 672{
650 struct dsps_glue *glue = platform_get_drvdata(pdev); 673 struct dsps_glue *glue = platform_get_drvdata(pdev);
651 const struct dsps_musb_wrapper *wrp = glue->wrp; 674 const struct dsps_musb_wrapper *wrp = glue->wrp;
@@ -653,7 +676,7 @@ static int __devexit dsps_remove(struct platform_device *pdev)
653 676
654 /* delete the child platform device */ 677 /* delete the child platform device */
655 for (i = 0; i < wrp->instances ; i++) 678 for (i = 0; i < wrp->instances ; i++)
656 dsps_delete_musb_pdev(glue, i); 679 platform_device_unregister(glue->musb[i]);
657 680
658 /* disable usbss clocks */ 681 /* disable usbss clocks */
659 pm_runtime_put(&pdev->dev); 682 pm_runtime_put(&pdev->dev);
@@ -666,24 +689,26 @@ static int __devexit dsps_remove(struct platform_device *pdev)
666#ifdef CONFIG_PM_SLEEP 689#ifdef CONFIG_PM_SLEEP
667static int dsps_suspend(struct device *dev) 690static int dsps_suspend(struct device *dev)
668{ 691{
669 struct musb_hdrc_platform_data *plat = dev->platform_data; 692 struct platform_device *pdev = to_platform_device(dev->parent);
670 struct omap_musb_board_data *data = plat->board_data; 693 struct dsps_glue *glue = platform_get_drvdata(pdev);
694 const struct dsps_musb_wrapper *wrp = glue->wrp;
695 int i;
671 696
672 /* Shutdown the on-chip PHY and its PLL. */ 697 for (i = 0; i < wrp->instances; i++)
673 if (data->set_phy_power) 698 musb_dsps_phy_control(glue, i, 0);
674 data->set_phy_power(0);
675 699
676 return 0; 700 return 0;
677} 701}
678 702
679static int dsps_resume(struct device *dev) 703static int dsps_resume(struct device *dev)
680{ 704{
681 struct musb_hdrc_platform_data *plat = dev->platform_data; 705 struct platform_device *pdev = to_platform_device(dev->parent);
682 struct omap_musb_board_data *data = plat->board_data; 706 struct dsps_glue *glue = platform_get_drvdata(pdev);
707 const struct dsps_musb_wrapper *wrp = glue->wrp;
708 int i;
683 709
684 /* Start the on-chip PHY and its PLL. */ 710 for (i = 0; i < wrp->instances; i++)
685 if (data->set_phy_power) 711 musb_dsps_phy_control(glue, i, 1);
686 data->set_phy_power(1);
687 712
688 return 0; 713 return 0;
689} 714}
@@ -691,7 +716,7 @@ static int dsps_resume(struct device *dev)
691 716
692static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); 717static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
693 718
694static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = { 719static const struct dsps_musb_wrapper ti81xx_driver_data = {
695 .revision = 0x00, 720 .revision = 0x00,
696 .control = 0x14, 721 .control = 0x14,
697 .status = 0x18, 722 .status = 0x18,
@@ -719,10 +744,10 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
719 .rxep_bitmap = (0xfffe << 16), 744 .rxep_bitmap = (0xfffe << 16),
720 .musb_core_offset = 0x400, 745 .musb_core_offset = 0x400,
721 .poll_seconds = 2, 746 .poll_seconds = 2,
722 .instances = 2, 747 .instances = 1,
723}; 748};
724 749
725static const struct platform_device_id musb_dsps_id_table[] __devinitconst = { 750static const struct platform_device_id musb_dsps_id_table[] = {
726 { 751 {
727 .name = "musb-ti81xx", 752 .name = "musb-ti81xx",
728 .driver_data = (kernel_ulong_t) &ti81xx_driver_data, 753 .driver_data = (kernel_ulong_t) &ti81xx_driver_data,
@@ -732,7 +757,7 @@ static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
732MODULE_DEVICE_TABLE(platform, musb_dsps_id_table); 757MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
733 758
734#ifdef CONFIG_OF 759#ifdef CONFIG_OF
735static const struct of_device_id musb_dsps_of_match[] __devinitconst = { 760static const struct of_device_id musb_dsps_of_match[] = {
736 { .compatible = "ti,musb-am33xx", 761 { .compatible = "ti,musb-am33xx",
737 .data = (void *) &ti81xx_driver_data, }, 762 .data = (void *) &ti81xx_driver_data, },
738 { }, 763 { },
@@ -742,7 +767,7 @@ MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
742 767
743static struct platform_driver dsps_usbss_driver = { 768static struct platform_driver dsps_usbss_driver = {
744 .probe = dsps_probe, 769 .probe = dsps_probe,
745 .remove = __devexit_p(dsps_remove), 770 .remove = dsps_remove,
746 .driver = { 771 .driver = {
747 .name = "musb-dsps", 772 .name = "musb-dsps",
748 .pm = &dsps_pm_ops, 773 .pm = &dsps_pm_ops,