diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-13 13:23:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-13 13:23:03 -0400 |
commit | 51feb98d2547a389be2f666514f5bcd658f79eab (patch) | |
tree | bd3d3eb486a0008340afd5807d9d2db12ec3b7b3 /drivers/usb/musb | |
parent | 8f8f013478133eb98e35e1d669c98c5e39d769c7 (diff) | |
parent | dc7520c17982ca4232233d2781e5cde29e58fbad (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.c | 32 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 27 |
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) | |||
2235 | static int musb_bus_suspend(struct usb_hcd *hcd) | 2235 | static 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; |