diff options
Diffstat (limited to 'drivers/usb/musb/tusb6010.c')
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 4ac1477d3569..88b587c703e9 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -259,6 +259,8 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) | |||
259 | tusb_fifo_read_unaligned(fifo, buf, len); | 259 | tusb_fifo_read_unaligned(fifo, buf, len); |
260 | } | 260 | } |
261 | 261 | ||
262 | static struct musb *the_musb; | ||
263 | |||
262 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 264 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
263 | 265 | ||
264 | /* This is used by gadget drivers, and OTG transceiver logic, allowing | 266 | /* This is used by gadget drivers, and OTG transceiver logic, allowing |
@@ -269,7 +271,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) | |||
269 | */ | 271 | */ |
270 | static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) | 272 | static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) |
271 | { | 273 | { |
272 | struct musb *musb = container_of(x, struct musb, xceiv); | 274 | struct musb *musb = the_musb; |
273 | void __iomem *tbase = musb->ctrl_base; | 275 | void __iomem *tbase = musb->ctrl_base; |
274 | u32 reg; | 276 | u32 reg; |
275 | 277 | ||
@@ -419,7 +421,7 @@ static void musb_do_idle(unsigned long _musb) | |||
419 | 421 | ||
420 | spin_lock_irqsave(&musb->lock, flags); | 422 | spin_lock_irqsave(&musb->lock, flags); |
421 | 423 | ||
422 | switch (musb->xceiv.state) { | 424 | switch (musb->xceiv->state) { |
423 | case OTG_STATE_A_WAIT_BCON: | 425 | case OTG_STATE_A_WAIT_BCON: |
424 | if ((musb->a_wait_bcon != 0) | 426 | if ((musb->a_wait_bcon != 0) |
425 | && (musb->idle_timeout == 0 | 427 | && (musb->idle_timeout == 0 |
@@ -483,7 +485,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
483 | 485 | ||
484 | /* Never idle if active, or when VBUS timeout is not set as host */ | 486 | /* Never idle if active, or when VBUS timeout is not set as host */ |
485 | if (musb->is_active || ((musb->a_wait_bcon == 0) | 487 | if (musb->is_active || ((musb->a_wait_bcon == 0) |
486 | && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { | 488 | && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { |
487 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); | 489 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); |
488 | del_timer(&musb_idle_timer); | 490 | del_timer(&musb_idle_timer); |
489 | last_timer = jiffies; | 491 | last_timer = jiffies; |
@@ -532,8 +534,8 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
532 | if (musb->set_clock) | 534 | if (musb->set_clock) |
533 | musb->set_clock(musb->clock, 1); | 535 | musb->set_clock(musb->clock, 1); |
534 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); | 536 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); |
535 | musb->xceiv.default_a = 1; | 537 | musb->xceiv->default_a = 1; |
536 | musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | 538 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
537 | devctl |= MUSB_DEVCTL_SESSION; | 539 | devctl |= MUSB_DEVCTL_SESSION; |
538 | 540 | ||
539 | conf |= TUSB_DEV_CONF_USB_HOST_MODE; | 541 | conf |= TUSB_DEV_CONF_USB_HOST_MODE; |
@@ -546,24 +548,24 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
546 | /* If ID pin is grounded, we want to be a_idle */ | 548 | /* If ID pin is grounded, we want to be a_idle */ |
547 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); | 549 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); |
548 | if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { | 550 | if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { |
549 | switch (musb->xceiv.state) { | 551 | switch (musb->xceiv->state) { |
550 | case OTG_STATE_A_WAIT_VRISE: | 552 | case OTG_STATE_A_WAIT_VRISE: |
551 | case OTG_STATE_A_WAIT_BCON: | 553 | case OTG_STATE_A_WAIT_BCON: |
552 | musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; | 554 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; |
553 | break; | 555 | break; |
554 | case OTG_STATE_A_WAIT_VFALL: | 556 | case OTG_STATE_A_WAIT_VFALL: |
555 | musb->xceiv.state = OTG_STATE_A_IDLE; | 557 | musb->xceiv->state = OTG_STATE_A_IDLE; |
556 | break; | 558 | break; |
557 | default: | 559 | default: |
558 | musb->xceiv.state = OTG_STATE_A_IDLE; | 560 | musb->xceiv->state = OTG_STATE_A_IDLE; |
559 | } | 561 | } |
560 | musb->is_active = 0; | 562 | musb->is_active = 0; |
561 | musb->xceiv.default_a = 1; | 563 | musb->xceiv->default_a = 1; |
562 | MUSB_HST_MODE(musb); | 564 | MUSB_HST_MODE(musb); |
563 | } else { | 565 | } else { |
564 | musb->is_active = 0; | 566 | musb->is_active = 0; |
565 | musb->xceiv.default_a = 0; | 567 | musb->xceiv->default_a = 0; |
566 | musb->xceiv.state = OTG_STATE_B_IDLE; | 568 | musb->xceiv->state = OTG_STATE_B_IDLE; |
567 | MUSB_DEV_MODE(musb); | 569 | MUSB_DEV_MODE(musb); |
568 | } | 570 | } |
569 | 571 | ||
@@ -674,7 +676,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
674 | else | 676 | else |
675 | default_a = is_host_enabled(musb); | 677 | default_a = is_host_enabled(musb); |
676 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); | 678 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); |
677 | musb->xceiv.default_a = default_a; | 679 | musb->xceiv->default_a = default_a; |
678 | tusb_source_power(musb, default_a); | 680 | tusb_source_power(musb, default_a); |
679 | 681 | ||
680 | /* Don't allow idling immediately */ | 682 | /* Don't allow idling immediately */ |
@@ -686,7 +688,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
686 | if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) { | 688 | if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) { |
687 | 689 | ||
688 | /* B-dev state machine: no vbus ~= disconnect */ | 690 | /* B-dev state machine: no vbus ~= disconnect */ |
689 | if ((is_otg_enabled(musb) && !musb->xceiv.default_a) | 691 | if ((is_otg_enabled(musb) && !musb->xceiv->default_a) |
690 | || !is_host_enabled(musb)) { | 692 | || !is_host_enabled(musb)) { |
691 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 693 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
692 | /* ? musb_root_disconnect(musb); */ | 694 | /* ? musb_root_disconnect(musb); */ |
@@ -701,9 +703,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
701 | 703 | ||
702 | if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { | 704 | if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { |
703 | DBG(1, "Forcing disconnect (no interrupt)\n"); | 705 | DBG(1, "Forcing disconnect (no interrupt)\n"); |
704 | if (musb->xceiv.state != OTG_STATE_B_IDLE) { | 706 | if (musb->xceiv->state != OTG_STATE_B_IDLE) { |
705 | /* INTR_DISCONNECT can hide... */ | 707 | /* INTR_DISCONNECT can hide... */ |
706 | musb->xceiv.state = OTG_STATE_B_IDLE; | 708 | musb->xceiv->state = OTG_STATE_B_IDLE; |
707 | musb->int_usb |= MUSB_INTR_DISCONNECT; | 709 | musb->int_usb |= MUSB_INTR_DISCONNECT; |
708 | } | 710 | } |
709 | musb->is_active = 0; | 711 | musb->is_active = 0; |
@@ -717,7 +719,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
717 | DBG(2, "vbus change, %s, otg %03x\n", | 719 | DBG(2, "vbus change, %s, otg %03x\n", |
718 | otg_state_string(musb), otg_stat); | 720 | otg_state_string(musb), otg_stat); |
719 | 721 | ||
720 | switch (musb->xceiv.state) { | 722 | switch (musb->xceiv->state) { |
721 | case OTG_STATE_A_IDLE: | 723 | case OTG_STATE_A_IDLE: |
722 | DBG(2, "Got SRP, turning on VBUS\n"); | 724 | DBG(2, "Got SRP, turning on VBUS\n"); |
723 | musb_set_vbus(musb, 1); | 725 | musb_set_vbus(musb, 1); |
@@ -765,7 +767,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
765 | 767 | ||
766 | DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat); | 768 | DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat); |
767 | 769 | ||
768 | switch (musb->xceiv.state) { | 770 | switch (musb->xceiv->state) { |
769 | case OTG_STATE_A_WAIT_VRISE: | 771 | case OTG_STATE_A_WAIT_VRISE: |
770 | /* VBUS has probably been valid for a while now, | 772 | /* VBUS has probably been valid for a while now, |
771 | * but may well have bounced out of range a bit | 773 | * but may well have bounced out of range a bit |
@@ -777,7 +779,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
777 | DBG(2, "devctl %02x\n", devctl); | 779 | DBG(2, "devctl %02x\n", devctl); |
778 | break; | 780 | break; |
779 | } | 781 | } |
780 | musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | 782 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; |
781 | musb->is_active = 0; | 783 | musb->is_active = 0; |
782 | idle_timeout = jiffies | 784 | idle_timeout = jiffies |
783 | + msecs_to_jiffies(musb->a_wait_bcon); | 785 | + msecs_to_jiffies(musb->a_wait_bcon); |
@@ -1093,9 +1095,14 @@ int __init musb_platform_init(struct musb *musb) | |||
1093 | { | 1095 | { |
1094 | struct platform_device *pdev; | 1096 | struct platform_device *pdev; |
1095 | struct resource *mem; | 1097 | struct resource *mem; |
1096 | void __iomem *sync; | 1098 | void __iomem *sync = NULL; |
1097 | int ret; | 1099 | int ret; |
1098 | 1100 | ||
1101 | usb_nop_xceiv_register(); | ||
1102 | musb->xceiv = otg_get_transceiver(); | ||
1103 | if (!musb->xceiv) | ||
1104 | return -ENODEV; | ||
1105 | |||
1099 | pdev = to_platform_device(musb->controller); | 1106 | pdev = to_platform_device(musb->controller); |
1100 | 1107 | ||
1101 | /* dma address for async dma */ | 1108 | /* dma address for async dma */ |
@@ -1106,14 +1113,16 @@ int __init musb_platform_init(struct musb *musb) | |||
1106 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1113 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1107 | if (!mem) { | 1114 | if (!mem) { |
1108 | pr_debug("no sync dma resource?\n"); | 1115 | pr_debug("no sync dma resource?\n"); |
1109 | return -ENODEV; | 1116 | ret = -ENODEV; |
1117 | goto done; | ||
1110 | } | 1118 | } |
1111 | musb->sync = mem->start; | 1119 | musb->sync = mem->start; |
1112 | 1120 | ||
1113 | sync = ioremap(mem->start, mem->end - mem->start + 1); | 1121 | sync = ioremap(mem->start, mem->end - mem->start + 1); |
1114 | if (!sync) { | 1122 | if (!sync) { |
1115 | pr_debug("ioremap for sync failed\n"); | 1123 | pr_debug("ioremap for sync failed\n"); |
1116 | return -ENOMEM; | 1124 | ret = -ENOMEM; |
1125 | goto done; | ||
1117 | } | 1126 | } |
1118 | musb->sync_va = sync; | 1127 | musb->sync_va = sync; |
1119 | 1128 | ||
@@ -1126,28 +1135,37 @@ int __init musb_platform_init(struct musb *musb) | |||
1126 | if (ret) { | 1135 | if (ret) { |
1127 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", | 1136 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", |
1128 | ret); | 1137 | ret); |
1129 | return -ENODEV; | 1138 | goto done; |
1130 | } | 1139 | } |
1131 | musb->isr = tusb_interrupt; | 1140 | musb->isr = tusb_interrupt; |
1132 | 1141 | ||
1133 | if (is_host_enabled(musb)) | 1142 | if (is_host_enabled(musb)) |
1134 | musb->board_set_vbus = tusb_source_power; | 1143 | musb->board_set_vbus = tusb_source_power; |
1135 | if (is_peripheral_enabled(musb)) | 1144 | if (is_peripheral_enabled(musb)) { |
1136 | musb->xceiv.set_power = tusb_draw_power; | 1145 | musb->xceiv->set_power = tusb_draw_power; |
1146 | the_musb = musb; | ||
1147 | } | ||
1137 | 1148 | ||
1138 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | 1149 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); |
1139 | 1150 | ||
1151 | done: | ||
1152 | if (ret < 0) { | ||
1153 | if (sync) | ||
1154 | iounmap(sync); | ||
1155 | usb_nop_xceiv_unregister(); | ||
1156 | } | ||
1140 | return ret; | 1157 | return ret; |
1141 | } | 1158 | } |
1142 | 1159 | ||
1143 | int musb_platform_exit(struct musb *musb) | 1160 | int musb_platform_exit(struct musb *musb) |
1144 | { | 1161 | { |
1145 | del_timer_sync(&musb_idle_timer); | 1162 | del_timer_sync(&musb_idle_timer); |
1163 | the_musb = NULL; | ||
1146 | 1164 | ||
1147 | if (musb->board_set_power) | 1165 | if (musb->board_set_power) |
1148 | musb->board_set_power(0); | 1166 | musb->board_set_power(0); |
1149 | 1167 | ||
1150 | iounmap(musb->sync_va); | 1168 | iounmap(musb->sync_va); |
1151 | 1169 | usb_nop_xceiv_unregister(); | |
1152 | return 0; | 1170 | return 0; |
1153 | } | 1171 | } |