summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/Kconfig1
-rw-r--r--drivers/usb/musb/cppi_dma.h1
-rw-r--r--drivers/usb/musb/davinci.c32
-rw-r--r--drivers/usb/musb/musb_core.c3
-rw-r--r--drivers/usb/musb/musb_core.h1
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c2
-rw-r--r--drivers/usb/musb/musb_host.c27
-rw-r--r--drivers/usb/musb/musb_regs.h1
8 files changed, 55 insertions, 13 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 70073b157f0..803adcb5ac1 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -12,6 +12,7 @@ config USB_MUSB_HDRC
depends on !SUPERH
select NOP_USB_XCEIV if ARCH_DAVINCI
select TWL4030_USB if MACH_OMAP_3430SDP
+ select NOP_USB_XCEIV if MACH_OMAP3EVM
select USB_OTG_UTILS
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
help
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h
index 8a39de3e6e4..59bf949e589 100644
--- a/drivers/usb/musb/cppi_dma.h
+++ b/drivers/usb/musb/cppi_dma.h
@@ -5,7 +5,6 @@
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/dmapool.h>
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 180d7daa409..e16ff605c45 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -35,13 +35,14 @@
#include <mach/hardware.h>
#include <mach/memory.h>
#include <mach/gpio.h>
+#include <mach/cputype.h>
#include <asm/mach-types.h>
#include "musb_core.h"
#ifdef CONFIG_MACH_DAVINCI_EVM
-#define GPIO_nVBUS_DRV 87
+#define GPIO_nVBUS_DRV 144
#endif
#include "davinci.h"
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
WARNING("VBUS error workaround (delay coming)\n");
} else if (is_host_enabled(musb) && drvvbus) {
- musb->is_active = 1;
MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
- /* NOTE: this must complete poweron within 100 msec */
+ /* NOTE: this must complete poweron within 100 msec
+ * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
+ */
davinci_source_power(musb, drvvbus, 0);
DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
drvvbus ? "on" : "off",
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
__raw_writel(phy_ctrl, USB_PHY_CTRL);
}
+ /* On dm355, the default-A state machine needs DRVVBUS control.
+ * If we won't be a host, there's no need to turn it on.
+ */
+ if (cpu_is_davinci_dm355()) {
+ u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+ if (is_host_enabled(musb)) {
+ deepsleep &= ~DRVVBUS_OVERRIDE;
+ } else {
+ deepsleep &= ~DRVVBUS_FORCE;
+ deepsleep |= DRVVBUS_OVERRIDE;
+ }
+ __raw_writel(deepsleep, DM355_DEEPSLEEP);
+ }
+
/* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
if (is_host_enabled(musb))
del_timer_sync(&otg_workaround);
+ /* force VBUS off */
+ if (cpu_is_davinci_dm355()) {
+ u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+ deepsleep &= ~DRVVBUS_FORCE;
+ deepsleep |= DRVVBUS_OVERRIDE;
+ __raw_writel(deepsleep, DM355_DEEPSLEEP);
+ }
+
davinci_source_power(musb, 0 /*off*/, 1);
/* delay, to avoid problems with module reload */
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 554a414f65d..c7c1ca0494c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1326,7 +1326,6 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
int i;
/* log core options (read using indexed model) */
- musb_ep_select(mbase, 0);
reg = musb_read_configdata(mbase);
strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
@@ -1990,7 +1989,7 @@ bad_config:
if (status < 0)
goto fail2;
-#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_MUSB_OTG
setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
#endif
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f3772ca3b2c..381d648a36b 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -38,7 +38,6 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/clk.h>
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 40ed50ecedf..7a6778675ad 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -407,7 +407,7 @@ stall:
csr |= MUSB_RXCSR_P_SENDSTALL
| MUSB_RXCSR_FLUSHFIFO
| MUSB_RXCSR_CLRDATATOG
- | MUSB_TXCSR_P_WZC_BITS;
+ | MUSB_RXCSR_P_WZC_BITS;
musb_writew(regs, MUSB_RXCSR,
csr);
}
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 94a2a350a41..cf94511485f 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
musb_save_toggle(qh, is_in, urb);
break;
case USB_ENDPOINT_XFER_ISOC:
- if (urb->error_count)
+ if (status == 0 && urb->error_count)
status = -EXDEV;
break;
}
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
static int musb_bus_suspend(struct usb_hcd *hcd)
{
struct musb *musb = hcd_to_musb(hcd);
+ u8 devctl;
- if (musb->xceiv->state == OTG_STATE_A_SUSPEND)
+ if (!is_host_active(musb))
return 0;
- if (is_host_active(musb) && musb->is_active) {
- WARNING("trying to suspend as %s is_active=%i\n",
- otg_state_string(musb), musb->is_active);
+ switch (musb->xceiv->state) {
+ case OTG_STATE_A_SUSPEND:
+ return 0;
+ case OTG_STATE_A_WAIT_VRISE:
+ /* ID could be grounded even if there's no device
+ * on the other end of the cable. NOTE that the
+ * A_WAIT_VRISE timers are messy with MUSB...
+ */
+ devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+ if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+ break;
+ default:
+ break;
+ }
+
+ if (musb->is_active) {
+ WARNING("trying to suspend as %s while active\n",
+ otg_state_string(musb));
return -EBUSY;
} else
return 0;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index de3b2f18db4..fbfd3fd9ce1 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -323,6 +323,7 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
static inline u8 musb_read_configdata(void __iomem *mbase)
{
+ musb_writeb(mbase, MUSB_INDEX, 0);
return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
}