aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-07-13 13:23:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-07-13 13:23:03 -0400
commit51feb98d2547a389be2f666514f5bcd658f79eab (patch)
treebd3d3eb486a0008340afd5807d9d2db12ec3b7b3 /drivers/usb/musb
parent8f8f013478133eb98e35e1d669c98c5e39d769c7 (diff)
parentdc7520c17982ca4232233d2781e5cde29e58fbad (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (48 commits) USB: otg: fix module reinsert issue USB: handle zero-length usbfs submissions correctly USB: EHCI: report actual_length for iso transfers USB: option: remove unnecessary and erroneous code USB: cypress_m8: remove invalid Clear-Halt USB: musb_host: undo incorrect change in musb_advance_schedule() USB: fix LANGID=0 regression USB: serial: sierra driver id_table additions USB serial: Add ID for Turtelizer, an FT2232L-based JTAG/RS-232 adapter. USB: fix race leading to a write after kfree in usbfs USB: Sierra: fix oops upon device close USB: option.c: add A-Link 3GU device id USB: Serial: Add support for Arkham Technology adapters USB: Fix option_ms regression in 2.6.31-rc2 USB: gadget audio: select SND_PCM USB: ftdi: support NDI devices Revert USB: usbfs: deprecate and hide option for !embedded USB: usb.h: fix kernel-doc notation USB: RNDIS gadget, fix issues talking from PXA USB: serial: FTDI with product code FB80 and vendor id 0403 ...
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/davinci.c32
-rw-r--r--drivers/usb/musb/musb_host.c27
2 files changed, 51 insertions, 8 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 180d7daa4099..e16ff605c458 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -35,13 +35,14 @@
35#include <mach/hardware.h> 35#include <mach/hardware.h>
36#include <mach/memory.h> 36#include <mach/memory.h>
37#include <mach/gpio.h> 37#include <mach/gpio.h>
38#include <mach/cputype.h>
38 39
39#include <asm/mach-types.h> 40#include <asm/mach-types.h>
40 41
41#include "musb_core.h" 42#include "musb_core.h"
42 43
43#ifdef CONFIG_MACH_DAVINCI_EVM 44#ifdef CONFIG_MACH_DAVINCI_EVM
44#define GPIO_nVBUS_DRV 87 45#define GPIO_nVBUS_DRV 144
45#endif 46#endif
46 47
47#include "davinci.h" 48#include "davinci.h"
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
329 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 330 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
330 WARNING("VBUS error workaround (delay coming)\n"); 331 WARNING("VBUS error workaround (delay coming)\n");
331 } else if (is_host_enabled(musb) && drvvbus) { 332 } else if (is_host_enabled(musb) && drvvbus) {
332 musb->is_active = 1;
333 MUSB_HST_MODE(musb); 333 MUSB_HST_MODE(musb);
334 musb->xceiv->default_a = 1; 334 musb->xceiv->default_a = 1;
335 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 335 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
343 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); 343 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
344 } 344 }
345 345
346 /* NOTE: this must complete poweron within 100 msec */ 346 /* NOTE: this must complete poweron within 100 msec
347 * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
348 */
347 davinci_source_power(musb, drvvbus, 0); 349 davinci_source_power(musb, drvvbus, 0);
348 DBG(2, "VBUS %s (%s)%s, devctl %02x\n", 350 DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
349 drvvbus ? "on" : "off", 351 drvvbus ? "on" : "off",
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
411 __raw_writel(phy_ctrl, USB_PHY_CTRL); 413 __raw_writel(phy_ctrl, USB_PHY_CTRL);
412 } 414 }
413 415
416 /* On dm355, the default-A state machine needs DRVVBUS control.
417 * If we won't be a host, there's no need to turn it on.
418 */
419 if (cpu_is_davinci_dm355()) {
420 u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
421
422 if (is_host_enabled(musb)) {
423 deepsleep &= ~DRVVBUS_OVERRIDE;
424 } else {
425 deepsleep &= ~DRVVBUS_FORCE;
426 deepsleep |= DRVVBUS_OVERRIDE;
427 }
428 __raw_writel(deepsleep, DM355_DEEPSLEEP);
429 }
430
414 /* reset the controller */ 431 /* reset the controller */
415 musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); 432 musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
416 433
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
437 if (is_host_enabled(musb)) 454 if (is_host_enabled(musb))
438 del_timer_sync(&otg_workaround); 455 del_timer_sync(&otg_workaround);
439 456
457 /* force VBUS off */
458 if (cpu_is_davinci_dm355()) {
459 u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
460
461 deepsleep &= ~DRVVBUS_FORCE;
462 deepsleep |= DRVVBUS_OVERRIDE;
463 __raw_writel(deepsleep, DM355_DEEPSLEEP);
464 }
465
440 davinci_source_power(musb, 0 /*off*/, 1); 466 davinci_source_power(musb, 0 /*off*/, 1);
441 467
442 /* delay, to avoid problems with module reload */ 468 /* delay, to avoid problems with module reload */
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 94a2a350a414..cf94511485f2 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,
373 musb_save_toggle(qh, is_in, urb); 373 musb_save_toggle(qh, is_in, urb);
374 break; 374 break;
375 case USB_ENDPOINT_XFER_ISOC: 375 case USB_ENDPOINT_XFER_ISOC:
376 if (urb->error_count) 376 if (status == 0 && urb->error_count)
377 status = -EXDEV; 377 status = -EXDEV;
378 break; 378 break;
379 } 379 }
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
2235static int musb_bus_suspend(struct usb_hcd *hcd) 2235static int musb_bus_suspend(struct usb_hcd *hcd)
2236{ 2236{
2237 struct musb *musb = hcd_to_musb(hcd); 2237 struct musb *musb = hcd_to_musb(hcd);
2238 u8 devctl;
2238 2239
2239 if (musb->xceiv->state == OTG_STATE_A_SUSPEND) 2240 if (!is_host_active(musb))
2240 return 0; 2241 return 0;
2241 2242
2242 if (is_host_active(musb) && musb->is_active) { 2243 switch (musb->xceiv->state) {
2243 WARNING("trying to suspend as %s is_active=%i\n", 2244 case OTG_STATE_A_SUSPEND:
2244 otg_state_string(musb), musb->is_active); 2245 return 0;
2246 case OTG_STATE_A_WAIT_VRISE:
2247 /* ID could be grounded even if there's no device
2248 * on the other end of the cable. NOTE that the
2249 * A_WAIT_VRISE timers are messy with MUSB...
2250 */
2251 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
2252 if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
2253 musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
2254 break;
2255 default:
2256 break;
2257 }
2258
2259 if (musb->is_active) {
2260 WARNING("trying to suspend as %s while active\n",
2261 otg_state_string(musb));
2245 return -EBUSY; 2262 return -EBUSY;
2246 } else 2263 } else
2247 return 0; 2264 return 0;