diff options
Diffstat (limited to 'drivers/usb/musb/tusb6010.c')
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 181 |
1 files changed, 141 insertions, 40 deletions
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index bde40efc7046..2ba3b070ed0b 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -21,10 +21,16 @@ | |||
21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/dma-mapping.h> | ||
24 | 25 | ||
25 | #include "musb_core.h" | 26 | #include "musb_core.h" |
26 | 27 | ||
27 | static void tusb_source_power(struct musb *musb, int is_on); | 28 | struct tusb6010_glue { |
29 | struct device *dev; | ||
30 | struct platform_device *musb; | ||
31 | }; | ||
32 | |||
33 | static void tusb_musb_set_vbus(struct musb *musb, int is_on); | ||
28 | 34 | ||
29 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) | 35 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) |
30 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) | 36 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) |
@@ -50,7 +56,7 @@ u8 tusb_get_revision(struct musb *musb) | |||
50 | return rev; | 56 | return rev; |
51 | } | 57 | } |
52 | 58 | ||
53 | static int __init tusb_print_revision(struct musb *musb) | 59 | static int tusb_print_revision(struct musb *musb) |
54 | { | 60 | { |
55 | void __iomem *tbase = musb->ctrl_base; | 61 | void __iomem *tbase = musb->ctrl_base; |
56 | u8 rev; | 62 | u8 rev; |
@@ -275,17 +281,6 @@ static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) | |||
275 | void __iomem *tbase = musb->ctrl_base; | 281 | void __iomem *tbase = musb->ctrl_base; |
276 | u32 reg; | 282 | u32 reg; |
277 | 283 | ||
278 | /* | ||
279 | * Keep clock active when enabled. Note that this is not tied to | ||
280 | * drawing VBUS, as with OTG mA can be less than musb->min_power. | ||
281 | */ | ||
282 | if (musb->set_clock) { | ||
283 | if (mA) | ||
284 | musb->set_clock(musb->clock, 1); | ||
285 | else | ||
286 | musb->set_clock(musb->clock, 0); | ||
287 | } | ||
288 | |||
289 | /* tps65030 seems to consume max 100mA, with maybe 60mA available | 284 | /* tps65030 seems to consume max 100mA, with maybe 60mA available |
290 | * (measured on one board) for things other than tps and tusb. | 285 | * (measured on one board) for things other than tps and tusb. |
291 | * | 286 | * |
@@ -348,7 +343,7 @@ static void tusb_set_clock_source(struct musb *musb, unsigned mode) | |||
348 | * USB link is not suspended ... and tells us the relevant wakeup | 343 | * USB link is not suspended ... and tells us the relevant wakeup |
349 | * events. SW_EN for voltage is handled separately. | 344 | * events. SW_EN for voltage is handled separately. |
350 | */ | 345 | */ |
351 | void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) | 346 | static void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) |
352 | { | 347 | { |
353 | void __iomem *tbase = musb->ctrl_base; | 348 | void __iomem *tbase = musb->ctrl_base; |
354 | u32 reg; | 349 | u32 reg; |
@@ -385,7 +380,7 @@ void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) | |||
385 | /* | 380 | /* |
386 | * Updates cable VBUS status. Caller must take care of locking. | 381 | * Updates cable VBUS status. Caller must take care of locking. |
387 | */ | 382 | */ |
388 | int musb_platform_get_vbus_status(struct musb *musb) | 383 | static int tusb_musb_vbus_status(struct musb *musb) |
389 | { | 384 | { |
390 | void __iomem *tbase = musb->ctrl_base; | 385 | void __iomem *tbase = musb->ctrl_base; |
391 | u32 otg_stat, prcm_mngmt; | 386 | u32 otg_stat, prcm_mngmt; |
@@ -431,7 +426,7 @@ static void musb_do_idle(unsigned long _musb) | |||
431 | } | 426 | } |
432 | /* FALLTHROUGH */ | 427 | /* FALLTHROUGH */ |
433 | case OTG_STATE_A_IDLE: | 428 | case OTG_STATE_A_IDLE: |
434 | tusb_source_power(musb, 0); | 429 | tusb_musb_set_vbus(musb, 0); |
435 | default: | 430 | default: |
436 | break; | 431 | break; |
437 | } | 432 | } |
@@ -475,7 +470,7 @@ done: | |||
475 | * we don't want to treat that full speed J as a wakeup event. | 470 | * we don't want to treat that full speed J as a wakeup event. |
476 | * ... peripherals must draw only suspend current after 10 msec. | 471 | * ... peripherals must draw only suspend current after 10 msec. |
477 | */ | 472 | */ |
478 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 473 | static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) |
479 | { | 474 | { |
480 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); | 475 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); |
481 | static unsigned long last_timer; | 476 | static unsigned long last_timer; |
@@ -515,7 +510,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
515 | | TUSB_DEV_OTG_TIMER_ENABLE) \ | 510 | | TUSB_DEV_OTG_TIMER_ENABLE) \ |
516 | : 0) | 511 | : 0) |
517 | 512 | ||
518 | static void tusb_source_power(struct musb *musb, int is_on) | 513 | static void tusb_musb_set_vbus(struct musb *musb, int is_on) |
519 | { | 514 | { |
520 | void __iomem *tbase = musb->ctrl_base; | 515 | void __iomem *tbase = musb->ctrl_base; |
521 | u32 conf, prcm, timer; | 516 | u32 conf, prcm, timer; |
@@ -531,8 +526,6 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
531 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 526 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
532 | 527 | ||
533 | if (is_on) { | 528 | if (is_on) { |
534 | if (musb->set_clock) | ||
535 | musb->set_clock(musb->clock, 1); | ||
536 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); | 529 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); |
537 | musb->xceiv->default_a = 1; | 530 | musb->xceiv->default_a = 1; |
538 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 531 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
@@ -571,8 +564,6 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
571 | 564 | ||
572 | devctl &= ~MUSB_DEVCTL_SESSION; | 565 | devctl &= ~MUSB_DEVCTL_SESSION; |
573 | conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; | 566 | conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; |
574 | if (musb->set_clock) | ||
575 | musb->set_clock(musb->clock, 0); | ||
576 | } | 567 | } |
577 | prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN); | 568 | prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN); |
578 | 569 | ||
@@ -599,7 +590,7 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
599 | * and peripheral modes in non-OTG configurations by reconfiguring hardware | 590 | * and peripheral modes in non-OTG configurations by reconfiguring hardware |
600 | * and then setting musb->board_mode. For now, only support OTG mode. | 591 | * and then setting musb->board_mode. For now, only support OTG mode. |
601 | */ | 592 | */ |
602 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 593 | static int tusb_musb_set_mode(struct musb *musb, u8 musb_mode) |
603 | { | 594 | { |
604 | void __iomem *tbase = musb->ctrl_base; | 595 | void __iomem *tbase = musb->ctrl_base; |
605 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; | 596 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; |
@@ -677,7 +668,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
677 | default_a = is_host_enabled(musb); | 668 | default_a = is_host_enabled(musb); |
678 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); | 669 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); |
679 | musb->xceiv->default_a = default_a; | 670 | musb->xceiv->default_a = default_a; |
680 | tusb_source_power(musb, default_a); | 671 | tusb_musb_set_vbus(musb, default_a); |
681 | 672 | ||
682 | /* Don't allow idling immediately */ | 673 | /* Don't allow idling immediately */ |
683 | if (default_a) | 674 | if (default_a) |
@@ -722,7 +713,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
722 | switch (musb->xceiv->state) { | 713 | switch (musb->xceiv->state) { |
723 | case OTG_STATE_A_IDLE: | 714 | case OTG_STATE_A_IDLE: |
724 | DBG(2, "Got SRP, turning on VBUS\n"); | 715 | DBG(2, "Got SRP, turning on VBUS\n"); |
725 | musb_set_vbus(musb, 1); | 716 | musb_platform_set_vbus(musb, 1); |
726 | 717 | ||
727 | /* CONNECT can wake if a_wait_bcon is set */ | 718 | /* CONNECT can wake if a_wait_bcon is set */ |
728 | if (musb->a_wait_bcon != 0) | 719 | if (musb->a_wait_bcon != 0) |
@@ -748,11 +739,11 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
748 | */ | 739 | */ |
749 | if (musb->vbuserr_retry) { | 740 | if (musb->vbuserr_retry) { |
750 | musb->vbuserr_retry--; | 741 | musb->vbuserr_retry--; |
751 | tusb_source_power(musb, 1); | 742 | tusb_musb_set_vbus(musb, 1); |
752 | } else { | 743 | } else { |
753 | musb->vbuserr_retry | 744 | musb->vbuserr_retry |
754 | = VBUSERR_RETRY_COUNT; | 745 | = VBUSERR_RETRY_COUNT; |
755 | tusb_source_power(musb, 0); | 746 | tusb_musb_set_vbus(musb, 0); |
756 | } | 747 | } |
757 | break; | 748 | break; |
758 | default: | 749 | default: |
@@ -786,7 +777,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
786 | } else { | 777 | } else { |
787 | /* REVISIT report overcurrent to hub? */ | 778 | /* REVISIT report overcurrent to hub? */ |
788 | ERR("vbus too slow, devctl %02x\n", devctl); | 779 | ERR("vbus too slow, devctl %02x\n", devctl); |
789 | tusb_source_power(musb, 0); | 780 | tusb_musb_set_vbus(musb, 0); |
790 | } | 781 | } |
791 | break; | 782 | break; |
792 | case OTG_STATE_A_WAIT_BCON: | 783 | case OTG_STATE_A_WAIT_BCON: |
@@ -807,7 +798,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
807 | return idle_timeout; | 798 | return idle_timeout; |
808 | } | 799 | } |
809 | 800 | ||
810 | static irqreturn_t tusb_interrupt(int irq, void *__hci) | 801 | static irqreturn_t tusb_musb_interrupt(int irq, void *__hci) |
811 | { | 802 | { |
812 | struct musb *musb = __hci; | 803 | struct musb *musb = __hci; |
813 | void __iomem *tbase = musb->ctrl_base; | 804 | void __iomem *tbase = musb->ctrl_base; |
@@ -911,7 +902,7 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci) | |||
911 | musb_writel(tbase, TUSB_INT_SRC_CLEAR, | 902 | musb_writel(tbase, TUSB_INT_SRC_CLEAR, |
912 | int_src & ~TUSB_INT_MASK_RESERVED_BITS); | 903 | int_src & ~TUSB_INT_MASK_RESERVED_BITS); |
913 | 904 | ||
914 | musb_platform_try_idle(musb, idle_timeout); | 905 | tusb_musb_try_idle(musb, idle_timeout); |
915 | 906 | ||
916 | musb_writel(tbase, TUSB_INT_MASK, int_mask); | 907 | musb_writel(tbase, TUSB_INT_MASK, int_mask); |
917 | spin_unlock_irqrestore(&musb->lock, flags); | 908 | spin_unlock_irqrestore(&musb->lock, flags); |
@@ -926,7 +917,7 @@ static int dma_off; | |||
926 | * REVISIT: | 917 | * REVISIT: |
927 | * - Check what is unnecessary in MGC_HdrcStart() | 918 | * - Check what is unnecessary in MGC_HdrcStart() |
928 | */ | 919 | */ |
929 | void musb_platform_enable(struct musb *musb) | 920 | static void tusb_musb_enable(struct musb *musb) |
930 | { | 921 | { |
931 | void __iomem *tbase = musb->ctrl_base; | 922 | void __iomem *tbase = musb->ctrl_base; |
932 | 923 | ||
@@ -970,7 +961,7 @@ void musb_platform_enable(struct musb *musb) | |||
970 | /* | 961 | /* |
971 | * Disables TUSB6010. Caller must take care of locking. | 962 | * Disables TUSB6010. Caller must take care of locking. |
972 | */ | 963 | */ |
973 | void musb_platform_disable(struct musb *musb) | 964 | static void tusb_musb_disable(struct musb *musb) |
974 | { | 965 | { |
975 | void __iomem *tbase = musb->ctrl_base; | 966 | void __iomem *tbase = musb->ctrl_base; |
976 | 967 | ||
@@ -995,7 +986,7 @@ void musb_platform_disable(struct musb *musb) | |||
995 | * Sets up TUSB6010 CPU interface specific signals and registers | 986 | * Sets up TUSB6010 CPU interface specific signals and registers |
996 | * Note: Settings optimized for OMAP24xx | 987 | * Note: Settings optimized for OMAP24xx |
997 | */ | 988 | */ |
998 | static void __init tusb_setup_cpu_interface(struct musb *musb) | 989 | static void tusb_setup_cpu_interface(struct musb *musb) |
999 | { | 990 | { |
1000 | void __iomem *tbase = musb->ctrl_base; | 991 | void __iomem *tbase = musb->ctrl_base; |
1001 | 992 | ||
@@ -1022,7 +1013,7 @@ static void __init tusb_setup_cpu_interface(struct musb *musb) | |||
1022 | musb_writel(tbase, TUSB_WAIT_COUNT, 1); | 1013 | musb_writel(tbase, TUSB_WAIT_COUNT, 1); |
1023 | } | 1014 | } |
1024 | 1015 | ||
1025 | static int __init tusb_start(struct musb *musb) | 1016 | static int tusb_musb_start(struct musb *musb) |
1026 | { | 1017 | { |
1027 | void __iomem *tbase = musb->ctrl_base; | 1018 | void __iomem *tbase = musb->ctrl_base; |
1028 | int ret = 0; | 1019 | int ret = 0; |
@@ -1091,7 +1082,7 @@ err: | |||
1091 | return -ENODEV; | 1082 | return -ENODEV; |
1092 | } | 1083 | } |
1093 | 1084 | ||
1094 | int __init musb_platform_init(struct musb *musb, void *board_data) | 1085 | static int tusb_musb_init(struct musb *musb) |
1095 | { | 1086 | { |
1096 | struct platform_device *pdev; | 1087 | struct platform_device *pdev; |
1097 | struct resource *mem; | 1088 | struct resource *mem; |
@@ -1131,16 +1122,14 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
1131 | */ | 1122 | */ |
1132 | musb->mregs += TUSB_BASE_OFFSET; | 1123 | musb->mregs += TUSB_BASE_OFFSET; |
1133 | 1124 | ||
1134 | ret = tusb_start(musb); | 1125 | ret = tusb_musb_start(musb); |
1135 | if (ret) { | 1126 | if (ret) { |
1136 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", | 1127 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", |
1137 | ret); | 1128 | ret); |
1138 | goto done; | 1129 | goto done; |
1139 | } | 1130 | } |
1140 | musb->isr = tusb_interrupt; | 1131 | musb->isr = tusb_musb_interrupt; |
1141 | 1132 | ||
1142 | if (is_host_enabled(musb)) | ||
1143 | musb->board_set_vbus = tusb_source_power; | ||
1144 | if (is_peripheral_enabled(musb)) { | 1133 | if (is_peripheral_enabled(musb)) { |
1145 | musb->xceiv->set_power = tusb_draw_power; | 1134 | musb->xceiv->set_power = tusb_draw_power; |
1146 | the_musb = musb; | 1135 | the_musb = musb; |
@@ -1159,7 +1148,7 @@ done: | |||
1159 | return ret; | 1148 | return ret; |
1160 | } | 1149 | } |
1161 | 1150 | ||
1162 | int musb_platform_exit(struct musb *musb) | 1151 | static int tusb_musb_exit(struct musb *musb) |
1163 | { | 1152 | { |
1164 | del_timer_sync(&musb_idle_timer); | 1153 | del_timer_sync(&musb_idle_timer); |
1165 | the_musb = NULL; | 1154 | the_musb = NULL; |
@@ -1173,3 +1162,115 @@ int musb_platform_exit(struct musb *musb) | |||
1173 | usb_nop_xceiv_unregister(); | 1162 | usb_nop_xceiv_unregister(); |
1174 | return 0; | 1163 | return 0; |
1175 | } | 1164 | } |
1165 | |||
1166 | static const struct musb_platform_ops tusb_ops = { | ||
1167 | .init = tusb_musb_init, | ||
1168 | .exit = tusb_musb_exit, | ||
1169 | |||
1170 | .enable = tusb_musb_enable, | ||
1171 | .disable = tusb_musb_disable, | ||
1172 | |||
1173 | .set_mode = tusb_musb_set_mode, | ||
1174 | .try_idle = tusb_musb_try_idle, | ||
1175 | |||
1176 | .vbus_status = tusb_musb_vbus_status, | ||
1177 | .set_vbus = tusb_musb_set_vbus, | ||
1178 | }; | ||
1179 | |||
1180 | static u64 tusb_dmamask = DMA_BIT_MASK(32); | ||
1181 | |||
1182 | static int __init tusb_probe(struct platform_device *pdev) | ||
1183 | { | ||
1184 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
1185 | struct platform_device *musb; | ||
1186 | struct tusb6010_glue *glue; | ||
1187 | |||
1188 | int ret = -ENOMEM; | ||
1189 | |||
1190 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
1191 | if (!glue) { | ||
1192 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
1193 | goto err0; | ||
1194 | } | ||
1195 | |||
1196 | musb = platform_device_alloc("musb-hdrc", -1); | ||
1197 | if (!musb) { | ||
1198 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
1199 | goto err1; | ||
1200 | } | ||
1201 | |||
1202 | musb->dev.parent = &pdev->dev; | ||
1203 | musb->dev.dma_mask = &tusb_dmamask; | ||
1204 | musb->dev.coherent_dma_mask = tusb_dmamask; | ||
1205 | |||
1206 | glue->dev = &pdev->dev; | ||
1207 | glue->musb = musb; | ||
1208 | |||
1209 | pdata->platform_ops = &tusb_ops; | ||
1210 | |||
1211 | platform_set_drvdata(pdev, glue); | ||
1212 | |||
1213 | ret = platform_device_add_resources(musb, pdev->resource, | ||
1214 | pdev->num_resources); | ||
1215 | if (ret) { | ||
1216 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
1217 | goto err2; | ||
1218 | } | ||
1219 | |||
1220 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
1221 | if (ret) { | ||
1222 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
1223 | goto err2; | ||
1224 | } | ||
1225 | |||
1226 | ret = platform_device_add(musb); | ||
1227 | if (ret) { | ||
1228 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
1229 | goto err1; | ||
1230 | } | ||
1231 | |||
1232 | return 0; | ||
1233 | |||
1234 | err2: | ||
1235 | platform_device_put(musb); | ||
1236 | |||
1237 | err1: | ||
1238 | kfree(glue); | ||
1239 | |||
1240 | err0: | ||
1241 | return ret; | ||
1242 | } | ||
1243 | |||
1244 | static int __exit tusb_remove(struct platform_device *pdev) | ||
1245 | { | ||
1246 | struct tusb6010_glue *glue = platform_get_drvdata(pdev); | ||
1247 | |||
1248 | platform_device_del(glue->musb); | ||
1249 | platform_device_put(glue->musb); | ||
1250 | kfree(glue); | ||
1251 | |||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | static struct platform_driver tusb_driver = { | ||
1256 | .remove = __exit_p(tusb_remove), | ||
1257 | .driver = { | ||
1258 | .name = "musb-tusb", | ||
1259 | }, | ||
1260 | }; | ||
1261 | |||
1262 | MODULE_DESCRIPTION("TUSB6010 MUSB Glue Layer"); | ||
1263 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
1264 | MODULE_LICENSE("GPL v2"); | ||
1265 | |||
1266 | static int __init tusb_init(void) | ||
1267 | { | ||
1268 | return platform_driver_probe(&tusb_driver, tusb_probe); | ||
1269 | } | ||
1270 | subsys_initcall(tusb_init); | ||
1271 | |||
1272 | static void __exit tusb_exit(void) | ||
1273 | { | ||
1274 | platform_driver_unregister(&tusb_driver); | ||
1275 | } | ||
1276 | module_exit(tusb_exit); | ||