diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Kconfig | 1 | ||||
-rw-r--r-- | drivers/usb/musb/cppi_dma.h | 1 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 32 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 3 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 1 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget_ep0.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 27 | ||||
-rw-r--r-- | drivers/usb/musb/musb_regs.h | 1 |
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); } |