aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-add-uas-driver.patch2
-rw-r--r--usb/usb-musb-change-to-direct-addr-in-context-save-restore.patch139
-rw-r--r--usb/usb-musb-gadget-fix-zlp-sending-in-musb_g_tx-v1.patch109
-rw-r--r--usb/usb-musb-gadget-kill-duplicate-code-in-musb_gadget_queue.patch34
-rw-r--r--usb/usb-musb-gadget-kill-unreachable-code-in-musb_g_rx.patch52
-rw-r--r--usb/usb-musb-gadget-only-enable-autoclear-in-double-buffered-case.patch40
-rw-r--r--usb/usb-musb-gadget-unmapping-the-dma-buffer-when-switching-to-pio-mode.patch190
-rw-r--r--usb/usb-musb-host-support-dma-transfers-greater-than-max-channel-length.patch57
-rw-r--r--usb/usb-musb-host-unmap-the-buffer-for-pio-data-transfers.patch86
-rw-r--r--usb/usb-musb-ignore-spurious-sessreq-interrupts.patch34
-rw-r--r--usb/usb-musb-introduce-da8xx-omap-l1x-glue-layer.patch544
-rw-r--r--usb/usb-musb-make-dbg-calls-actually-depend-on-config_usb_musb_debug.patch56
-rw-r--r--usb/usb-musb-musbhsdma-increase-max_len-to-1mb.patch32
-rw-r--r--usb/usb-musb-support-iso-high-bandwidth-for-gadget-mode.patch146
-rw-r--r--usb/usb-musb-suppress-warning-about-unused-flags.patch35
-rw-r--r--usb/usb-yurex-fix-memory-leak-and-corrupted-messages.patch100
16 files changed, 1655 insertions, 1 deletions
diff --git a/usb/usb-add-uas-driver.patch b/usb/usb-add-uas-driver.patch
index 978327b2463586..77c6313c870283 100644
--- a/usb/usb-add-uas-driver.patch
+++ b/usb/usb-add-uas-driver.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -5898,6 +5898,14 @@ S: Maintained
+@@ -5908,6 +5908,14 @@ S: Maintained
F: Documentation/usb/acm.txt
F: drivers/usb/class/cdc-acm.*
diff --git a/usb/usb-musb-change-to-direct-addr-in-context-save-restore.patch b/usb/usb-musb-change-to-direct-addr-in-context-save-restore.patch
new file mode 100644
index 00000000000000..6e26717c59cdc9
--- /dev/null
+++ b/usb/usb-musb-change-to-direct-addr-in-context-save-restore.patch
@@ -0,0 +1,139 @@
+From balbi@ti.com Tue Oct 5 13:29:35 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Bob Liu <lliubbo@gmail.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: Change to direct addr in context save/restore
+Date: Fri, 24 Sep 2010 13:44:07 +0300
+Message-Id: <1285325055-1247-7-git-send-email-balbi@ti.com>
+
+From: Bob Liu <lliubbo@gmail.com>
+
+Since not all platforms are using the same offset 0x10 in
+musb_save/restore_context() eg Blackfin the offset is 0x40,
+Change the indexed address to direct.
+
+Signed-off-by: Bob Liu <lliubbo@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_core.c | 46 ++++++++++++++++++++-----------------------
+ 1 file changed, 22 insertions(+), 24 deletions(-)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2266,6 +2266,7 @@ void musb_save_context(struct musb *musb
+ {
+ int i;
+ void __iomem *musb_base = musb->mregs;
++ void __iomem *epio;
+
+ if (is_host_enabled(musb)) {
+ musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
+@@ -2279,16 +2280,16 @@ void musb_save_context(struct musb *musb
+ musb_context.index = musb_readb(musb_base, MUSB_INDEX);
+ musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
+
+- for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+- musb_writeb(musb_base, MUSB_INDEX, i);
++ for (i = 0; i < musb->config->num_eps; ++i) {
++ epio = musb->endpoints[i].regs;
+ musb_context.index_regs[i].txmaxp =
+- musb_readw(musb_base, 0x10 + MUSB_TXMAXP);
++ musb_readw(epio, MUSB_TXMAXP);
+ musb_context.index_regs[i].txcsr =
+- musb_readw(musb_base, 0x10 + MUSB_TXCSR);
++ musb_readw(epio, MUSB_TXCSR);
+ musb_context.index_regs[i].rxmaxp =
+- musb_readw(musb_base, 0x10 + MUSB_RXMAXP);
++ musb_readw(epio, MUSB_RXMAXP);
+ musb_context.index_regs[i].rxcsr =
+- musb_readw(musb_base, 0x10 + MUSB_RXCSR);
++ musb_readw(epio, MUSB_RXCSR);
+
+ if (musb->dyn_fifo) {
+ musb_context.index_regs[i].txfifoadd =
+@@ -2302,13 +2303,13 @@ void musb_save_context(struct musb *musb
+ }
+ if (is_host_enabled(musb)) {
+ musb_context.index_regs[i].txtype =
+- musb_readb(musb_base, 0x10 + MUSB_TXTYPE);
++ musb_readb(epio, MUSB_TXTYPE);
+ musb_context.index_regs[i].txinterval =
+- musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL);
++ musb_readb(epio, MUSB_TXINTERVAL);
+ musb_context.index_regs[i].rxtype =
+- musb_readb(musb_base, 0x10 + MUSB_RXTYPE);
++ musb_readb(epio, MUSB_RXTYPE);
+ musb_context.index_regs[i].rxinterval =
+- musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL);
++ musb_readb(epio, MUSB_RXINTERVAL);
+
+ musb_context.index_regs[i].txfunaddr =
+ musb_read_txfunaddr(musb_base, i);
+@@ -2326,8 +2327,6 @@ void musb_save_context(struct musb *musb
+ }
+ }
+
+- musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+-
+ musb_platform_save_context(musb, &musb_context);
+ }
+
+@@ -2336,6 +2335,7 @@ void musb_restore_context(struct musb *m
+ int i;
+ void __iomem *musb_base = musb->mregs;
+ void __iomem *ep_target_regs;
++ void __iomem *epio;
+
+ musb_platform_restore_context(musb, &musb_context);
+
+@@ -2350,15 +2350,15 @@ void musb_restore_context(struct musb *m
+ musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe);
+ musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl);
+
+- for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+- musb_writeb(musb_base, MUSB_INDEX, i);
+- musb_writew(musb_base, 0x10 + MUSB_TXMAXP,
++ for (i = 0; i < musb->config->num_eps; ++i) {
++ epio = musb->endpoints[i].regs;
++ musb_writew(epio, MUSB_TXMAXP,
+ musb_context.index_regs[i].txmaxp);
+- musb_writew(musb_base, 0x10 + MUSB_TXCSR,
++ musb_writew(epio, MUSB_TXCSR,
+ musb_context.index_regs[i].txcsr);
+- musb_writew(musb_base, 0x10 + MUSB_RXMAXP,
++ musb_writew(epio, MUSB_RXMAXP,
+ musb_context.index_regs[i].rxmaxp);
+- musb_writew(musb_base, 0x10 + MUSB_RXCSR,
++ musb_writew(epio, MUSB_RXCSR,
+ musb_context.index_regs[i].rxcsr);
+
+ if (musb->dyn_fifo) {
+@@ -2373,13 +2373,13 @@ void musb_restore_context(struct musb *m
+ }
+
+ if (is_host_enabled(musb)) {
+- musb_writeb(musb_base, 0x10 + MUSB_TXTYPE,
++ musb_writeb(epio, MUSB_TXTYPE,
+ musb_context.index_regs[i].txtype);
+- musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL,
++ musb_writeb(epio, MUSB_TXINTERVAL,
+ musb_context.index_regs[i].txinterval);
+- musb_writeb(musb_base, 0x10 + MUSB_RXTYPE,
++ musb_writeb(epio, MUSB_RXTYPE,
+ musb_context.index_regs[i].rxtype);
+- musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL,
++ musb_writeb(epio, MUSB_RXINTERVAL,
+
+ musb_context.index_regs[i].rxinterval);
+ musb_write_txfunaddr(musb_base, i,
+@@ -2400,8 +2400,6 @@ void musb_restore_context(struct musb *m
+ musb_context.index_regs[i].rxhubport);
+ }
+ }
+-
+- musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+ }
+
+ static int musb_suspend(struct device *dev)
diff --git a/usb/usb-musb-gadget-fix-zlp-sending-in-musb_g_tx-v1.patch b/usb/usb-musb-gadget-fix-zlp-sending-in-musb_g_tx-v1.patch
new file mode 100644
index 00000000000000..712e90c8a2c824
--- /dev/null
+++ b/usb/usb-musb-gadget-fix-zlp-sending-in-musb_g_tx-v1.patch
@@ -0,0 +1,109 @@
+From balbi@ti.com Tue Oct 5 13:30:59 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: fix ZLP sending in musb_g_tx(v1)
+Date: Fri, 24 Sep 2010 13:44:14 +0300
+Message-Id: <1285325055-1247-14-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+This patch fixes the problem reported by Sergei:
+
+>how come? we need to send ZLP before giving back the request.
+>Well, look at the code ionce again. We need to send ZLP *after*
+>request->actual == request->length, but as the check is inserted
+>after the ZLP send, ZLP *may* be sent once the first DMA completes,
+>not the last.
+
+The patch also has been discussed on the link below:
+
+ http://marc.info/?t=128454814900001&r=1&w=2
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Reported-by: Sergei Shtylyov <sshtylyov@mvista.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_gadget.c | 59 ++++++++++++++++++++---------------------
+ 1 file changed, 29 insertions(+), 30 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -522,40 +522,39 @@ void musb_g_tx(struct musb *musb, u8 epn
+ epnum, csr, musb_ep->dma->actual_len, request);
+ }
+
+- if (is_dma || request->actual == request->length) {
+- /*
+- * First, maybe a terminating short packet. Some DMA
+- * engines might handle this by themselves.
+- */
+- if ((request->zero && request->length
+- && request->length % musb_ep->packet_sz == 0)
++ /*
++ * First, maybe a terminating short packet. Some DMA
++ * engines might handle this by themselves.
++ */
++ if ((request->zero && request->length
++ && (request->length % musb_ep->packet_sz == 0)
++ && (request->actual == request->length))
+ #ifdef CONFIG_USB_INVENTRA_DMA
+- || (is_dma && (!dma->desired_mode ||
+- (request->actual &
+- (musb_ep->packet_sz - 1))))
++ || (is_dma && (!dma->desired_mode ||
++ (request->actual &
++ (musb_ep->packet_sz - 1))))
+ #endif
+- ) {
+- /*
+- * On DMA completion, FIFO may not be
+- * available yet...
+- */
+- if (csr & MUSB_TXCSR_TXPKTRDY)
+- return;
++ ) {
++ /*
++ * On DMA completion, FIFO may not be
++ * available yet...
++ */
++ if (csr & MUSB_TXCSR_TXPKTRDY)
++ return;
+
+- DBG(4, "sending zero pkt\n");
+- musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
+- | MUSB_TXCSR_TXPKTRDY);
+- request->zero = 0;
+- }
++ DBG(4, "sending zero pkt\n");
++ musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
++ | MUSB_TXCSR_TXPKTRDY);
++ request->zero = 0;
++ }
+
+- if (request->actual == request->length) {
+- musb_g_giveback(musb_ep, request, 0);
+- request = musb_ep->desc ? next_request(musb_ep) : NULL;
+- if (!request) {
+- DBG(4, "%s idle now\n",
+- musb_ep->end_point.name);
+- return;
+- }
++ if (request->actual == request->length) {
++ musb_g_giveback(musb_ep, request, 0);
++ request = musb_ep->desc ? next_request(musb_ep) : NULL;
++ if (!request) {
++ DBG(4, "%s idle now\n",
++ musb_ep->end_point.name);
++ return;
+ }
+ }
+
diff --git a/usb/usb-musb-gadget-kill-duplicate-code-in-musb_gadget_queue.patch b/usb/usb-musb-gadget-kill-duplicate-code-in-musb_gadget_queue.patch
new file mode 100644
index 00000000000000..58719014989f62
--- /dev/null
+++ b/usb/usb-musb-gadget-kill-duplicate-code-in-musb_gadget_queue.patch
@@ -0,0 +1,34 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:30:26 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: kill duplicate code in musb_gadget_queue()
+Date: Fri, 24 Sep 2010 13:44:11 +0300
+Message-Id: <1285325055-1247-11-git-send-email-balbi@ti.com>
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+I've noticed that musb_gadget_queue() checks for '!req->buf' condition twice:
+in the second case the code is both duplicate and unreachable as the first
+check returns early.
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_gadget.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1214,8 +1214,6 @@ static int musb_gadget_queue(struct usb_
+
+ if (is_dma_capable() && musb_ep->dma)
+ map_dma_buffer(request, musb);
+- else if (!req->buf)
+- return -ENODATA;
+ else
+ request->mapped = 0;
+
diff --git a/usb/usb-musb-gadget-kill-unreachable-code-in-musb_g_rx.patch b/usb/usb-musb-gadget-kill-unreachable-code-in-musb_g_rx.patch
new file mode 100644
index 00000000000000..685cd9b5d7ca55
--- /dev/null
+++ b/usb/usb-musb-gadget-kill-unreachable-code-in-musb_g_rx.patch
@@ -0,0 +1,52 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:30:37 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: kill unreachable code in musb_g_rx()
+Date: Fri, 24 Sep 2010 13:44:12 +0300
+Message-Id: <1285325055-1247-12-git-send-email-balbi@ti.com>
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+musb_g_rx() always returns if next_request() call yields NULL, so the DBG()
+near the function's end can never be invoked. Remove it along with unneeded
+'return'; also remove the duplicate 'request' check...
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -834,7 +834,7 @@ void musb_g_rx(struct musb *musb, u8 epn
+ musb_writew(epio, MUSB_RXCSR, csr);
+
+ DBG(3, "%s iso overrun on %p\n", musb_ep->name, request);
+- if (request && request->status == -EINPROGRESS)
++ if (request->status == -EINPROGRESS)
+ request->status = -EOVERFLOW;
+ }
+ if (csr & MUSB_RXCSR_INCOMPRX) {
+@@ -887,14 +887,8 @@ void musb_g_rx(struct musb *musb, u8 epn
+ return;
+ }
+
+- /* analyze request if the ep is hot */
+- if (request)
+- rxstate(musb, to_musb_request(request));
+- else
+- DBG(3, "packet waiting for %s%s request\n",
+- musb_ep->desc ? "" : "inactive ",
+- musb_ep->end_point.name);
+- return;
++ /* Analyze request */
++ rxstate(musb, to_musb_request(request));
+ }
+
+ /* ------------------------------------------------------------ */
diff --git a/usb/usb-musb-gadget-only-enable-autoclear-in-double-buffered-case.patch b/usb/usb-musb-gadget-only-enable-autoclear-in-double-buffered-case.patch
new file mode 100644
index 00000000000000..4376a184cdc118
--- /dev/null
+++ b/usb/usb-musb-gadget-only-enable-autoclear-in-double-buffered-case.patch
@@ -0,0 +1,40 @@
+From balbi@ti.com Tue Oct 5 13:31:10 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: only enable AUTOCLEAR in double buffered case
+Date: Fri, 24 Sep 2010 13:44:15 +0300
+Message-Id: <1285325055-1247-15-git-send-email-balbi@ti.com>
+
+commit 633ba7876b96ec339ef685357e2f7c60b5a8ce85 broke
+g_file_storage functionality by enabling AUTOCLEAR on
+all cases without caring for all gadget drivers.
+
+This patch will only enable AUTOCLEAR if our endpoint's
+FIFO was configured with double buffering support. Note
+this is not a complete fix, double buffered case still
+doesn't work always, but that hasn't been working for
+quite some time. Other than reverting the entire commit
+and breaking testusb with double buffered case again,
+I decided it was better to fix the single buffered case
+and spend more time fixing double buffered case properly.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_gadget.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -689,7 +689,8 @@ static void rxstate(struct musb *musb, s
+ */
+
+ csr |= MUSB_RXCSR_DMAENAB;
+- if (!musb_ep->hb_mult)
++ if (!musb_ep->hb_mult &&
++ musb_ep->hw_ep->rx_double_buffered)
+ csr |= MUSB_RXCSR_AUTOCLEAR;
+ #ifdef USE_MODE1
+ /* csr |= MUSB_RXCSR_DMAMODE; */
diff --git a/usb/usb-musb-gadget-unmapping-the-dma-buffer-when-switching-to-pio-mode.patch b/usb/usb-musb-gadget-unmapping-the-dma-buffer-when-switching-to-pio-mode.patch
new file mode 100644
index 00000000000000..2b44fc1afdcb62
--- /dev/null
+++ b/usb/usb-musb-gadget-unmapping-the-dma-buffer-when-switching-to-pio-mode.patch
@@ -0,0 +1,190 @@
+From balbi@ti.com Tue Oct 5 13:29:53 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Hema HK <hemahk@ti.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: Unmapping the dma buffer when switching to PIO mode
+Date: Fri, 24 Sep 2010 13:44:08 +0300
+Message-Id: <1285325055-1247-8-git-send-email-balbi@ti.com>
+
+From: Hema HK <hemahk@ti.com>
+
+Buffer is mapped to dma when dma channel is allocated. buffer needs
+to be unmapped when fallback to PIO mode if dma channel_program
+fails.
+
+Signed-off-by: Hema HK <hemahk@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Reviewed-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_gadget.c | 122 +++++++++++++++++++++++++++--------------
+ 1 file changed, 82 insertions(+), 40 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -92,6 +92,60 @@
+
+ /* ----------------------------------------------------------------------- */
+
++/* Maps the buffer to dma */
++
++static inline void map_dma_buffer(struct musb_request *request,
++ struct musb *musb)
++{
++ if (request->request.dma == DMA_ADDR_INVALID) {
++ request->request.dma = dma_map_single(
++ musb->controller,
++ request->request.buf,
++ request->request.length,
++ request->tx
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++ request->mapped = 1;
++ } else {
++ dma_sync_single_for_device(musb->controller,
++ request->request.dma,
++ request->request.length,
++ request->tx
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++ request->mapped = 0;
++ }
++}
++
++/* Unmap the buffer from dma and maps it back to cpu */
++static inline void unmap_dma_buffer(struct musb_request *request,
++ struct musb *musb)
++{
++ if (request->request.dma == DMA_ADDR_INVALID) {
++ DBG(20, "not unmapping a never mapped buffer\n");
++ return;
++ }
++
++ if (request->mapped) {
++ dma_unmap_single(musb->controller,
++ request->request.dma,
++ request->request.length,
++ request->tx
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++ request->request.dma = DMA_ADDR_INVALID;
++ request->mapped = 0;
++ } else {
++ dma_sync_single_for_cpu(musb->controller,
++ request->request.dma,
++ request->request.length,
++ request->tx
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++
++ }
++}
++
+ /*
+ * Immediately complete a request.
+ *
+@@ -119,24 +173,8 @@ __acquires(ep->musb->lock)
+
+ ep->busy = 1;
+ spin_unlock(&musb->lock);
+- if (is_dma_capable()) {
+- if (req->mapped) {
+- dma_unmap_single(musb->controller,
+- req->request.dma,
+- req->request.length,
+- req->tx
+- ? DMA_TO_DEVICE
+- : DMA_FROM_DEVICE);
+- req->request.dma = DMA_ADDR_INVALID;
+- req->mapped = 0;
+- } else if (req->request.dma != DMA_ADDR_INVALID)
+- dma_sync_single_for_cpu(musb->controller,
+- req->request.dma,
+- req->request.length,
+- req->tx
+- ? DMA_TO_DEVICE
+- : DMA_FROM_DEVICE);
+- }
++ if (is_dma_capable() && ep->dma)
++ unmap_dma_buffer(req, musb);
+ if (request->status == 0)
+ DBG(5, "%s done request %p, %d/%d\n",
+ ep->end_point.name, request,
+@@ -298,7 +336,7 @@ static void txstate(struct musb *musb, s
+ csr);
+
+ #ifndef CONFIG_MUSB_PIO_ONLY
+- if (is_dma_capable() && musb_ep->dma) {
++ if (is_dma_capable() && !musb_ep->dma && musb->dma_controller) {
+ struct dma_controller *c = musb->dma_controller;
+ size_t request_size;
+
+@@ -395,6 +433,13 @@ static void txstate(struct musb *musb, s
+ #endif
+
+ if (!use_dma) {
++ /*
++ * Unmap the dma buffer back to cpu if dma channel
++ * programming fails
++ */
++ if (is_dma_capable() && musb_ep->dma)
++ unmap_dma_buffer(req, musb);
++
+ musb_write_fifo(musb_ep->hw_ep, fifo_count,
+ (u8 *) (request->buf + request->actual));
+ request->actual += fifo_count;
+@@ -711,6 +756,20 @@ static void rxstate(struct musb *musb, s
+ return;
+ }
+ #endif
++ /*
++ * Unmap the dma buffer back to cpu if dma channel
++ * programming fails. This buffer is mapped if the
++ * channel allocation is successful
++ */
++ if (is_dma_capable() && musb_ep->dma) {
++ unmap_dma_buffer(req, musb);
++
++ /* Clear DMAENAB for the
++ * PIO mode transfer
++ */
++ csr &= ~MUSB_RXCSR_DMAENAB;
++ musb_writew(epio, MUSB_RXCSR, csr);
++ }
+
+ musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
+ (request->buf + request->actual));
+@@ -1153,28 +1212,11 @@ static int musb_gadget_queue(struct usb_
+ request->epnum = musb_ep->current_epnum;
+ request->tx = musb_ep->is_in;
+
+- if (is_dma_capable() && musb_ep->dma) {
+- if (request->request.dma == DMA_ADDR_INVALID) {
+- request->request.dma = dma_map_single(
+- musb->controller,
+- request->request.buf,
+- request->request.length,
+- request->tx
+- ? DMA_TO_DEVICE
+- : DMA_FROM_DEVICE);
+- request->mapped = 1;
+- } else {
+- dma_sync_single_for_device(musb->controller,
+- request->request.dma,
+- request->request.length,
+- request->tx
+- ? DMA_TO_DEVICE
+- : DMA_FROM_DEVICE);
+- request->mapped = 0;
+- }
+- } else if (!req->buf) {
++ if (is_dma_capable() && musb_ep->dma)
++ map_dma_buffer(request, musb);
++ else if (!req->buf)
+ return -ENODATA;
+- } else
++ else
+ request->mapped = 0;
+
+ spin_lock_irqsave(&musb->lock, lockflags);
diff --git a/usb/usb-musb-host-support-dma-transfers-greater-than-max-channel-length.patch b/usb/usb-musb-host-support-dma-transfers-greater-than-max-channel-length.patch
new file mode 100644
index 00000000000000..edfd0d195ddd66
--- /dev/null
+++ b/usb/usb-musb-host-support-dma-transfers-greater-than-max-channel-length.patch
@@ -0,0 +1,57 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:30:06 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ "T. S., Anil Kumar" <anil@ti.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: host: support DMA transfers greater than max channel length
+Date: Fri, 24 Sep 2010 13:44:09 +0300
+Message-Id: <1285325055-1247-9-git-send-email-balbi@ti.com>
+
+From: T. S., Anil Kumar <anil@ti.com>
+
+Add support for MUSB Host DMA transfers greater than max
+channel length, so that such transfers won't be truncated.
+
+Signed-off-by: Anil Shetty <anil@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_host.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -1120,6 +1120,7 @@ void musb_host_tx(struct musb *musb, u8
+ u32 status = 0;
+ void __iomem *mbase = musb->mregs;
+ struct dma_channel *dma;
++ bool transfer_pending = false;
+
+ musb_ep_select(mbase, epnum);
+ tx_csr = musb_readw(epio, MUSB_TXCSR);
+@@ -1280,7 +1281,7 @@ void musb_host_tx(struct musb *musb, u8
+ offset = d->offset;
+ length = d->length;
+ }
+- } else if (dma) {
++ } else if (dma && urb->transfer_buffer_length == qh->offset) {
+ done = true;
+ } else {
+ /* see if we need to send more data, or ZLP */
+@@ -1293,6 +1294,7 @@ void musb_host_tx(struct musb *musb, u8
+ if (!done) {
+ offset = qh->offset;
+ length = urb->transfer_buffer_length - offset;
++ transfer_pending = true;
+ }
+ }
+ }
+@@ -1312,7 +1314,7 @@ void musb_host_tx(struct musb *musb, u8
+ urb->actual_length = qh->offset;
+ musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
+ return;
+- } else if (usb_pipeisoc(pipe) && dma) {
++ } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) {
+ if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
+ offset, length)) {
+ if (is_cppi_enabled() || tusb_dma_omap())
diff --git a/usb/usb-musb-host-unmap-the-buffer-for-pio-data-transfers.patch b/usb/usb-musb-host-unmap-the-buffer-for-pio-data-transfers.patch
new file mode 100644
index 00000000000000..63b0315a556298
--- /dev/null
+++ b/usb/usb-musb-host-unmap-the-buffer-for-pio-data-transfers.patch
@@ -0,0 +1,86 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:29:25 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Maulik Mankad <x0082077@ti.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: host: unmap the buffer for PIO data transfers
+Date: Fri, 24 Sep 2010 13:44:06 +0300
+Message-Id: <1285325055-1247-6-git-send-email-balbi@ti.com>
+
+From: Maulik Mankad <x0082077@ti.com>
+
+The USB stack maps the buffer for DMA if the controller supports DMA.
+MUSB controller can perform DMA as well as PIO transfers.
+The buffer needs to be unmapped before CPU can perform
+PIO data transfers.
+
+Export unmap_urb_for_dma() so that drivers can perform
+the DMA unmapping in a sane way.
+
+Signed-off-by: Maulik Mankad <x0082077@ti.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/core/hcd.c | 3 ++-
+ drivers/usb/musb/musb_host.c | 5 +++++
+ include/linux/usb/hcd.h | 1 +
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1263,7 +1263,7 @@ static void hcd_free_coherent(struct usb
+ *dma_handle = 0;
+ }
+
+-static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
++void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+ {
+ enum dma_data_direction dir;
+
+@@ -1307,6 +1307,7 @@ static void unmap_urb_for_dma(struct usb
+ URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |
+ URB_DMA_MAP_SINGLE | URB_MAP_LOCAL);
+ }
++EXPORT_SYMBOL_GPL(unmap_urb_for_dma);
+
+ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -41,6 +41,7 @@
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/list.h>
++#include <linux/dma-mapping.h>
+
+ #include "musb_core.h"
+ #include "musb_host.h"
+@@ -1332,6 +1333,8 @@ void musb_host_tx(struct musb *musb, u8
+ */
+ if (length > qh->maxpacket)
+ length = qh->maxpacket;
++ /* Unmap the buffer so that CPU can use it */
++ unmap_urb_for_dma(musb_to_hcd(musb), urb);
+ musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset);
+ qh->segsize = length;
+
+@@ -1752,6 +1755,8 @@ void musb_host_rx(struct musb *musb, u8
+ #endif /* Mentor DMA */
+
+ if (!dma) {
++ /* Unmap the buffer so that CPU can use it */
++ unmap_urb_for_dma(musb_to_hcd(musb), urb);
+ done = musb_host_packet_rx(musb, urb,
+ epnum, iso_err);
+ DBG(6, "read %spacket\n", done ? "last " : "");
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -329,6 +329,7 @@ extern int usb_hcd_submit_urb(struct urb
+ extern int usb_hcd_unlink_urb(struct urb *urb, int status);
+ extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
+ int status);
++extern void unmap_urb_for_dma(struct usb_hcd *, struct urb *);
+ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
+ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
diff --git a/usb/usb-musb-ignore-spurious-sessreq-interrupts.patch b/usb/usb-musb-ignore-spurious-sessreq-interrupts.patch
new file mode 100644
index 00000000000000..d2e5ef52bdf7d3
--- /dev/null
+++ b/usb/usb-musb-ignore-spurious-sessreq-interrupts.patch
@@ -0,0 +1,34 @@
+From balbi@ti.com Tue Oct 5 13:30:50 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Heikki Krogerus <ext-heikki.krogerus@nokia.com>
+Subject: usb: musb: ignore spurious SESSREQ interrupts
+Date: Fri, 24 Sep 2010 13:44:13 +0300
+Message-Id: <1285325055-1247-13-git-send-email-balbi@ti.com>
+
+From: Heikki Krogerus <ext-heikki.krogerus@nokia.com>
+
+This will ignore any SESSREQ interrupt if musb is B state.
+Charger detection may cause spurious SESSREQ interrupts.
+
+Signed-off-by: Heikki Krogerus <ext-heikki.krogerus@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -550,6 +550,11 @@ static irqreturn_t musb_stage0_irq(struc
+ if (int_usb & MUSB_INTR_SESSREQ) {
+ void __iomem *mbase = musb->mregs;
+
++ if (devctl & MUSB_DEVCTL_BDEVICE) {
++ DBG(3, "SessReq while on B state\n");
++ return IRQ_HANDLED;
++ }
++
+ DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
+
+ /* IRQ arrives from ID pin sense or (later, if VBUS power
diff --git a/usb/usb-musb-introduce-da8xx-omap-l1x-glue-layer.patch b/usb/usb-musb-introduce-da8xx-omap-l1x-glue-layer.patch
new file mode 100644
index 00000000000000..2d331bb0723f70
--- /dev/null
+++ b/usb/usb-musb-introduce-da8xx-omap-l1x-glue-layer.patch
@@ -0,0 +1,544 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:28:43 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>,
+ Yadviga Grigorieva <yadviga@ru.mvista.com>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: introduce DA8xx/OMAP-L1x glue layer
+Date: Fri, 24 Sep 2010 13:44:03 +0300
+Message-Id: <1285325055-1247-3-git-send-email-balbi@ti.com>
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+Texas Instruments DA8xx/OMAP-L1x glue layer for the
+MUSBMHRDC driver.
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Yadviga Grigorieva <yadviga@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/Kconfig | 5
+ drivers/usb/musb/Makefile | 4
+ drivers/usb/musb/da8xx.c | 469 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/musb/musb_core.h | 1
+ 4 files changed, 478 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/Kconfig
++++ b/drivers/usb/musb/Kconfig
+@@ -45,6 +45,9 @@ config USB_MUSB_SOC
+ comment "DaVinci 35x and 644x USB support"
+ depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
+
++comment "DA8xx/OMAP-L1x USB support"
++ depends on USB_MUSB_HDRC && ARCH_DAVINCI_DA8XX
++
+ comment "OMAP 243x high speed USB support"
+ depends on USB_MUSB_HDRC && ARCH_OMAP2430
+
+@@ -144,7 +147,7 @@ config USB_MUSB_HDRC_HCD
+ config MUSB_PIO_ONLY
+ bool 'Disable DMA (always use PIO)'
+ depends on USB_MUSB_HDRC
+- default y if USB_TUSB6010
++ default USB_TUSB6010 || ARCH_DAVINCI_DA8XX
+ help
+ All data is copied between memory and FIFO by the CPU.
+ DMA controllers are ignored.
+--- a/drivers/usb/musb/Makefile
++++ b/drivers/usb/musb/Makefile
+@@ -10,6 +10,10 @@ ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
+ musb_hdrc-objs += davinci.o
+ endif
+
++ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
++ musb_hdrc-objs += da8xx.o
++endif
++
+ ifeq ($(CONFIG_USB_TUSB6010),y)
+ musb_hdrc-objs += tusb6010.o
+ endif
+--- /dev/null
++++ b/drivers/usb/musb/da8xx.c
+@@ -0,0 +1,469 @@
++/*
++ * Texas Instruments DA8xx/OMAP-L1x "glue layer"
++ *
++ * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
++ *
++ * Based on the DaVinci "glue layer" code.
++ * Copyright (C) 2005-2006 by Texas Instruments
++ *
++ * This file is part of the Inventra Controller Driver for Linux.
++ *
++ * The Inventra Controller Driver for Linux is free software; you
++ * can redistribute it and/or modify it under the terms of the GNU
++ * General Public License version 2 as published by the Free Software
++ * Foundation.
++ *
++ * The Inventra Controller Driver for Linux is distributed in
++ * the hope that it will be useful, but WITHOUT ANY WARRANTY;
++ * without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
++ * License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with The Inventra Controller Driver for Linux ; if not,
++ * write to the Free Software Foundation, Inc., 59 Temple Place,
++ * Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++
++#include <mach/da8xx.h>
++#include <mach/usb.h>
++
++#include "musb_core.h"
++
++/*
++ * DA8XX specific definitions
++ */
++
++/* USB 2.0 OTG module registers */
++#define DA8XX_USB_REVISION_REG 0x00
++#define DA8XX_USB_CTRL_REG 0x04
++#define DA8XX_USB_STAT_REG 0x08
++#define DA8XX_USB_EMULATION_REG 0x0c
++#define DA8XX_USB_MODE_REG 0x10 /* Transparent, CDC, [Generic] RNDIS */
++#define DA8XX_USB_AUTOREQ_REG 0x14
++#define DA8XX_USB_SRP_FIX_TIME_REG 0x18
++#define DA8XX_USB_TEARDOWN_REG 0x1c
++#define DA8XX_USB_INTR_SRC_REG 0x20
++#define DA8XX_USB_INTR_SRC_SET_REG 0x24
++#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
++#define DA8XX_USB_INTR_MASK_REG 0x2c
++#define DA8XX_USB_INTR_MASK_SET_REG 0x30
++#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
++#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
++#define DA8XX_USB_END_OF_INTR_REG 0x3c
++#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
++
++/* Control register bits */
++#define DA8XX_SOFT_RESET_MASK 1
++
++#define DA8XX_USB_TX_EP_MASK 0x1f /* EP0 + 4 Tx EPs */
++#define DA8XX_USB_RX_EP_MASK 0x1e /* 4 Rx EPs */
++
++/* USB interrupt register bits */
++#define DA8XX_INTR_USB_SHIFT 16
++#define DA8XX_INTR_USB_MASK (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
++ /* interrupts and DRVVBUS interrupt */
++#define DA8XX_INTR_DRVVBUS 0x100
++#define DA8XX_INTR_RX_SHIFT 8
++#define DA8XX_INTR_RX_MASK (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
++#define DA8XX_INTR_TX_SHIFT 0
++#define DA8XX_INTR_TX_MASK (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
++
++#define DA8XX_MENTOR_CORE_OFFSET 0x400
++
++#define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG)
++
++/*
++ * REVISIT (PM): we should be able to keep the PHY in low power mode most
++ * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0
++ * and, when in host mode, autosuspending idle root ports... PHY_PLLON
++ * (overriding SUSPENDM?) then likely needs to stay off.
++ */
++
++static inline void phy_on(void)
++{
++ u32 cfgchip2 = __raw_readl(CFGCHIP2);
++
++ /*
++ * Start the on-chip PHY and its PLL.
++ */
++ cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN);
++ cfgchip2 |= CFGCHIP2_PHY_PLLON;
++ __raw_writel(cfgchip2, CFGCHIP2);
++
++ pr_info("Waiting for USB PHY clock good...\n");
++ while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD))
++ cpu_relax();
++}
++
++static inline void phy_off(void)
++{
++ u32 cfgchip2 = __raw_readl(CFGCHIP2);
++
++ /*
++ * Ensure that USB 1.1 reference clock is not being sourced from
++ * USB 2.0 PHY. Otherwise do not power down the PHY.
++ */
++ if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) &&
++ (cfgchip2 & CFGCHIP2_USB1SUSPENDM)) {
++ pr_warning("USB 1.1 clocked from USB 2.0 PHY -- "
++ "can't power it down\n");
++ return;
++ }
++
++ /*
++ * Power down the on-chip PHY.
++ */
++ cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN;
++ __raw_writel(cfgchip2, CFGCHIP2);
++}
++
++/*
++ * Because we don't set CTRL.UINT, it's "important" to:
++ * - not read/write INTRUSB/INTRUSBE (except during
++ * initial setup, as a workaround);
++ * - use INTSET/INTCLR instead.
++ */
++
++/**
++ * musb_platform_enable - enable interrupts
++ */
++void musb_platform_enable(struct musb *musb)
++{
++ void __iomem *reg_base = musb->ctrl_base;
++ u32 mask;
++
++ /* Workaround: setup IRQs through both register sets. */
++ mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
++ ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
++ DA8XX_INTR_USB_MASK;
++ musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
++
++ /* Force the DRVVBUS IRQ so we can start polling for ID change. */
++ if (is_otg_enabled(musb))
++ musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
++ DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
++}
++
++/**
++ * musb_platform_disable - disable HDRC and flush interrupts
++ */
++void musb_platform_disable(struct musb *musb)
++{
++ void __iomem *reg_base = musb->ctrl_base;
++
++ musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
++ DA8XX_INTR_USB_MASK |
++ DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
++ musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
++ musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
++}
++
++#ifdef CONFIG_USB_MUSB_HDRC_HCD
++#define portstate(stmt) stmt
++#else
++#define portstate(stmt)
++#endif
++
++static void da8xx_set_vbus(struct musb *musb, int is_on)
++{
++ WARN_ON(is_on && is_peripheral_active(musb));
++}
++
++#define POLL_SECONDS 2
++
++static struct timer_list otg_workaround;
++
++static void otg_timer(unsigned long _musb)
++{
++ struct musb *musb = (void *)_musb;
++ void __iomem *mregs = musb->mregs;
++ u8 devctl;
++ unsigned long flags;
++
++ /*
++ * We poll because DaVinci's won't expose several OTG-critical
++ * status change events (from the transceiver) otherwise.
++ */
++ devctl = musb_readb(mregs, MUSB_DEVCTL);
++ DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
++
++ spin_lock_irqsave(&musb->lock, flags);
++ switch (musb->xceiv->state) {
++ case OTG_STATE_A_WAIT_BCON:
++ devctl &= ~MUSB_DEVCTL_SESSION;
++ musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++
++ devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
++ if (devctl & MUSB_DEVCTL_BDEVICE) {
++ musb->xceiv->state = OTG_STATE_B_IDLE;
++ MUSB_DEV_MODE(musb);
++ } else {
++ musb->xceiv->state = OTG_STATE_A_IDLE;
++ MUSB_HST_MODE(musb);
++ }
++ break;
++ case OTG_STATE_A_WAIT_VFALL:
++ /*
++ * Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3
++ * RTL seems to mis-handle session "start" otherwise (or in
++ * our case "recover"), in routine "VBUS was valid by the time
++ * VBUSERR got reported during enumeration" cases.
++ */
++ if (devctl & MUSB_DEVCTL_VBUS) {
++ mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
++ break;
++ }
++ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
++ musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG,
++ MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT);
++ break;
++ case OTG_STATE_B_IDLE:
++ if (!is_peripheral_enabled(musb))
++ break;
++
++ /*
++ * There's no ID-changed IRQ, so we have no good way to tell
++ * when to switch to the A-Default state machine (by setting
++ * the DEVCTL.Session bit).
++ *
++ * Workaround: whenever we're in B_IDLE, try setting the
++ * session flag every few seconds. If it works, ID was
++ * grounded and we're now in the A-Default state machine.
++ *
++ * NOTE: setting the session flag is _supposed_ to trigger
++ * SRP but clearly it doesn't.
++ */
++ musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION);
++ devctl = musb_readb(mregs, MUSB_DEVCTL);
++ if (devctl & MUSB_DEVCTL_BDEVICE)
++ mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
++ else
++ musb->xceiv->state = OTG_STATE_A_IDLE;
++ break;
++ default:
++ break;
++ }
++ spin_unlock_irqrestore(&musb->lock, flags);
++}
++
++void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
++{
++ static unsigned long last_timer;
++
++ if (!is_otg_enabled(musb))
++ return;
++
++ if (timeout == 0)
++ timeout = jiffies + msecs_to_jiffies(3);
++
++ /* Never idle if active, or when VBUS timeout is not set as host */
++ if (musb->is_active || (musb->a_wait_bcon == 0 &&
++ musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
++ DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
++ del_timer(&otg_workaround);
++ last_timer = jiffies;
++ return;
++ }
++
++ if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) {
++ DBG(4, "Longer idle timer already pending, ignoring...\n");
++ return;
++ }
++ last_timer = timeout;
++
++ DBG(4, "%s inactive, starting idle timer for %u ms\n",
++ otg_state_string(musb), jiffies_to_msecs(timeout - jiffies));
++ mod_timer(&otg_workaround, timeout);
++}
++
++static irqreturn_t da8xx_interrupt(int irq, void *hci)
++{
++ struct musb *musb = hci;
++ void __iomem *reg_base = musb->ctrl_base;
++ unsigned long flags;
++ irqreturn_t ret = IRQ_NONE;
++ u32 status;
++
++ spin_lock_irqsave(&musb->lock, flags);
++
++ /*
++ * NOTE: DA8XX shadows the Mentor IRQs. Don't manage them through
++ * the Mentor registers (except for setup), use the TI ones and EOI.
++ */
++
++ /* Acknowledge and handle non-CPPI interrupts */
++ status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG);
++ if (!status)
++ goto eoi;
++
++ musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status);
++ DBG(4, "USB IRQ %08x\n", status);
++
++ musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT;
++ musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT;
++ musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT;
++
++ /*
++ * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
++ * DA8xx's missing ID change IRQ. We need an ID change IRQ to
++ * switch appropriately between halves of the OTG state machine.
++ * Managing DEVCTL.Session per Mentor docs requires that we know its
++ * value but DEVCTL.BDevice is invalid without DEVCTL.Session set.
++ * Also, DRVVBUS pulses for SRP (but not at 5 V)...
++ */
++ if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) {
++ int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG);
++ void __iomem *mregs = musb->mregs;
++ u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
++ int err;
++
++ err = is_host_enabled(musb) && (musb->int_usb &
++ MUSB_INTR_VBUSERROR);
++ if (err) {
++ /*
++ * The Mentor core doesn't debounce VBUS as needed
++ * to cope with device connect current spikes. This
++ * means it's not uncommon for bus-powered devices
++ * to get VBUS errors during enumeration.
++ *
++ * This is a workaround, but newer RTL from Mentor
++ * seems to allow a better one: "re"-starting sessions
++ * without waiting for VBUS to stop registering in
++ * devctl.
++ */
++ musb->int_usb &= ~MUSB_INTR_VBUSERROR;
++ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
++ mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
++ WARNING("VBUS error workaround (delay coming)\n");
++ } else if (is_host_enabled(musb) && drvvbus) {
++ MUSB_HST_MODE(musb);
++ musb->xceiv->default_a = 1;
++ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
++ portstate(musb->port1_status |= USB_PORT_STAT_POWER);
++ del_timer(&otg_workaround);
++ } else {
++ musb->is_active = 0;
++ MUSB_DEV_MODE(musb);
++ musb->xceiv->default_a = 0;
++ musb->xceiv->state = OTG_STATE_B_IDLE;
++ portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
++ }
++
++ DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
++ drvvbus ? "on" : "off",
++ otg_state_string(musb),
++ err ? " ERROR" : "",
++ devctl);
++ ret = IRQ_HANDLED;
++ }
++
++ if (musb->int_tx || musb->int_rx || musb->int_usb)
++ ret |= musb_interrupt(musb);
++
++ eoi:
++ /* EOI needs to be written for the IRQ to be re-asserted. */
++ if (ret == IRQ_HANDLED || status)
++ musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
++
++ /* Poll for ID change */
++ if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
++ mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
++
++ spin_unlock_irqrestore(&musb->lock, flags);
++
++ return ret;
++}
++
++int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
++{
++ u32 cfgchip2 = __raw_readl(CFGCHIP2);
++
++ cfgchip2 &= ~CFGCHIP2_OTGMODE;
++ switch (musb_mode) {
++#ifdef CONFIG_USB_MUSB_HDRC_HCD
++ case MUSB_HOST: /* Force VBUS valid, ID = 0 */
++ cfgchip2 |= CFGCHIP2_FORCE_HOST;
++ break;
++#endif
++#ifdef CONFIG_USB_GADGET_MUSB_HDRC
++ case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
++ cfgchip2 |= CFGCHIP2_FORCE_DEVICE;
++ break;
++#endif
++#ifdef CONFIG_USB_MUSB_OTG
++ case MUSB_OTG: /* Don't override the VBUS/ID comparators */
++ cfgchip2 |= CFGCHIP2_NO_OVERRIDE;
++ break;
++#endif
++ default:
++ DBG(2, "Trying to set unsupported mode %u\n", musb_mode);
++ }
++
++ __raw_writel(cfgchip2, CFGCHIP2);
++ return 0;
++}
++
++int __init musb_platform_init(struct musb *musb, void *board_data)
++{
++ void __iomem *reg_base = musb->ctrl_base;
++ u32 rev;
++
++ musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
++
++ clk_enable(musb->clock);
++
++ /* Returns zero if e.g. not clocked */
++ rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG);
++ if (!rev)
++ goto fail;
++
++ usb_nop_xceiv_register();
++ musb->xceiv = otg_get_transceiver();
++ if (!musb->xceiv)
++ goto fail;
++
++ if (is_host_enabled(musb))
++ setup_timer(&otg_workaround, otg_timer, (unsigned long)musb);
++
++ musb->board_set_vbus = da8xx_set_vbus;
++
++ /* Reset the controller */
++ musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
++
++ /* Start the on-chip PHY and its PLL. */
++ phy_on();
++
++ msleep(5);
++
++ /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
++ pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n",
++ rev, __raw_readl(CFGCHIP2),
++ musb_readb(reg_base, DA8XX_USB_CTRL_REG));
++
++ musb->isr = da8xx_interrupt;
++ return 0;
++fail:
++ clk_disable(musb->clock);
++ return -ENODEV;
++}
++
++int musb_platform_exit(struct musb *musb)
++{
++ if (is_host_enabled(musb))
++ del_timer_sync(&otg_workaround);
++
++ phy_off();
++
++ otg_put_transceiver(musb->xceiv);
++ usb_nop_xceiv_unregister();
++
++ clk_disable(musb->clock);
++
++ return 0;
++}
+--- a/drivers/usb/musb/musb_core.h
++++ b/drivers/usb/musb/musb_core.h
+@@ -599,6 +599,7 @@ extern void musb_hnp_stop(struct musb *m
+ extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
+
+ #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
++ defined(CONFIG_ARCH_DAVINCI_DA8XX) || \
+ defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
+ defined(CONFIG_ARCH_OMAP4)
+ extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
diff --git a/usb/usb-musb-make-dbg-calls-actually-depend-on-config_usb_musb_debug.patch b/usb/usb-musb-make-dbg-calls-actually-depend-on-config_usb_musb_debug.patch
new file mode 100644
index 00000000000000..e9a02f1087711e
--- /dev/null
+++ b/usb/usb-musb-make-dbg-calls-actually-depend-on-config_usb_musb_debug.patch
@@ -0,0 +1,56 @@
+From balbi@ti.com Tue Oct 5 13:28:24 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: USB: musb: make DBG() calls actually depend on CONFIG_USB_MUSB_DEBUG
+Date: Fri, 24 Sep 2010 13:44:02 +0300
+Message-Id: <1285325055-1247-2-git-send-email-balbi@ti.com>
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+Enabling CONFIG_USB_MUSB_DEBUG option causes -DDEBUG to be added to gcc's
+command line, however the DBG() macro doesn't depend on DEBUG, so that the
+debugging messages get printed regardless of the option, and I don't think
+that this was intended. Get rid of otherwise unused xprintk() macro and make
+DBG() macro directly call pr_debug() which only results in the actual code
+generated if DEBUG is defined.
+
+This change makes musb_hdrc.o ~30% less in size with CONFIG_USB_MUSB_DEBUG
+disabled (in host mode).
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_debug.h | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/musb/musb_debug.h
++++ b/drivers/usb/musb/musb_debug.h
+@@ -42,11 +42,10 @@
+ #define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args)
+ #define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args)
+
+-#define xprintk(level, facility, format, args...) do { \
+- if (_dbg_level(level)) { \
+- printk(facility "%s %d: " format , \
+- __func__, __LINE__ , ## args); \
+- } } while (0)
++#define DBG(level, format, args...) do { \
++ if (_dbg_level(level)) \
++ pr_debug("%s %d: " format, __func__, __LINE__, ## args); \
++ } while (0)
+
+ extern unsigned musb_debug;
+
+@@ -55,8 +54,6 @@ static inline int _dbg_level(unsigned l)
+ return musb_debug >= l;
+ }
+
+-#define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
+-
+ extern const char *otg_state_string(struct musb *);
+
+ #ifdef CONFIG_DEBUG_FS
diff --git a/usb/usb-musb-musbhsdma-increase-max_len-to-1mb.patch b/usb/usb-musb-musbhsdma-increase-max_len-to-1mb.patch
new file mode 100644
index 00000000000000..8f7361b9af86a8
--- /dev/null
+++ b/usb/usb-musb-musbhsdma-increase-max_len-to-1mb.patch
@@ -0,0 +1,32 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:29:16 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Anil Shetty <anil@ti.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: musbhsdma: increase max_len to 1MB
+Date: Fri, 24 Sep 2010 13:44:05 +0300
+Message-Id: <1285325055-1247-5-git-send-email-balbi@ti.com>
+
+From: Anil Shetty <anil@ti.com>
+
+MUSB's DMA controller max channel length was set to 64k.
+Transfer length greater than this max value is being truncated.
+
+Signed-off-by: Anil Shetty <anil@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musbhsdma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musbhsdma.c
++++ b/drivers/usb/musb/musbhsdma.c
+@@ -91,7 +91,7 @@ static struct dma_channel *dma_channel_a
+ channel = &(musb_channel->channel);
+ channel->private_data = musb_channel;
+ channel->status = MUSB_DMA_STATUS_FREE;
+- channel->max_len = 0x10000;
++ channel->max_len = 0x100000;
+ /* Tx => mode 1; Rx => mode 0 */
+ channel->desired_mode = transmit;
+ channel->actual_len = 0;
diff --git a/usb/usb-musb-support-iso-high-bandwidth-for-gadget-mode.patch b/usb/usb-musb-support-iso-high-bandwidth-for-gadget-mode.patch
new file mode 100644
index 00000000000000..e615d7525a0533
--- /dev/null
+++ b/usb/usb-musb-support-iso-high-bandwidth-for-gadget-mode.patch
@@ -0,0 +1,146 @@
+From balbi@ti.com Tue Oct 5 13:28:57 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: support ISO high bandwidth for gadget mode
+Date: Fri, 24 Sep 2010 13:44:04 +0300
+Message-Id: <1285325055-1247-4-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+This patch has been tested OK on beagle B5 board and
+use usbtest #15 and #16 as testcase.
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Reviewed-by: Sergei Shtylyov <sshtylyov@mvista.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/musb_gadget.c | 49 ++++++++++++++++++++++++++++++-----------
+ drivers/usb/musb/musb_gadget.h | 2 +
+ 2 files changed, 39 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -337,13 +337,15 @@ static void txstate(struct musb *musb, s
+ csr |= (MUSB_TXCSR_DMAENAB |
+ MUSB_TXCSR_MODE);
+ /* against programming guide */
+- } else
+- csr |= (MUSB_TXCSR_AUTOSET
+- | MUSB_TXCSR_DMAENAB
++ } else {
++ csr |= (MUSB_TXCSR_DMAENAB
+ | MUSB_TXCSR_DMAMODE
+ | MUSB_TXCSR_MODE);
+-
++ if (!musb_ep->hb_mult)
++ csr |= MUSB_TXCSR_AUTOSET;
++ }
+ csr &= ~MUSB_TXCSR_P_UNDERRUN;
++
+ musb_writew(epio, MUSB_TXCSR, csr);
+ }
+ }
+@@ -643,7 +645,8 @@ static void rxstate(struct musb *musb, s
+ */
+
+ csr |= MUSB_RXCSR_DMAENAB;
+- csr |= MUSB_RXCSR_AUTOCLEAR;
++ if (!musb_ep->hb_mult)
++ csr |= MUSB_RXCSR_AUTOCLEAR;
+ #ifdef USE_MODE1
+ /* csr |= MUSB_RXCSR_DMAMODE; */
+
+@@ -875,9 +878,25 @@ static int musb_gadget_enable(struct usb
+
+ /* REVISIT this rules out high bandwidth periodic transfers */
+ tmp = le16_to_cpu(desc->wMaxPacketSize);
+- if (tmp & ~0x07ff)
+- goto fail;
+- musb_ep->packet_sz = tmp;
++ if (tmp & ~0x07ff) {
++ int ok;
++
++ if (usb_endpoint_dir_in(desc))
++ ok = musb->hb_iso_tx;
++ else
++ ok = musb->hb_iso_rx;
++
++ if (!ok) {
++ DBG(4, "%s: not support ISO high bandwidth\n", __func__);
++ goto fail;
++ }
++ musb_ep->hb_mult = (tmp >> 11) & 3;
++ } else {
++ musb_ep->hb_mult = 0;
++ }
++
++ musb_ep->packet_sz = tmp & 0x7ff;
++ tmp = musb_ep->packet_sz * (musb_ep->hb_mult + 1);
+
+ /* enable the interrupts for the endpoint, set the endpoint
+ * packet size (or fail), set the mode, clear the fifo
+@@ -890,8 +909,11 @@ static int musb_gadget_enable(struct usb
+ musb_ep->is_in = 1;
+ if (!musb_ep->is_in)
+ goto fail;
+- if (tmp > hw_ep->max_packet_sz_tx)
++
++ if (tmp > hw_ep->max_packet_sz_tx) {
++ DBG(4, "%s: packet size beyond hw fifo size\n", __func__);
+ goto fail;
++ }
+
+ int_txe |= (1 << epnum);
+ musb_writew(mbase, MUSB_INTRTXE, int_txe);
+@@ -906,7 +928,7 @@ static int musb_gadget_enable(struct usb
+ if (musb->hwvers < MUSB_HWVERS_2000)
+ musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
+ else
+- musb_writew(regs, MUSB_TXMAXP, tmp);
++ musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+
+ csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
+ if (musb_readw(regs, MUSB_TXCSR)
+@@ -927,8 +949,11 @@ static int musb_gadget_enable(struct usb
+ musb_ep->is_in = 0;
+ if (musb_ep->is_in)
+ goto fail;
+- if (tmp > hw_ep->max_packet_sz_rx)
++
++ if (tmp > hw_ep->max_packet_sz_rx) {
++ DBG(4, "%s: packet size beyond hw fifo size\n", __func__);
+ goto fail;
++ }
+
+ int_rxe |= (1 << epnum);
+ musb_writew(mbase, MUSB_INTRRXE, int_rxe);
+@@ -942,7 +967,7 @@ static int musb_gadget_enable(struct usb
+ if (musb->hwvers < MUSB_HWVERS_2000)
+ musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx);
+ else
+- musb_writew(regs, MUSB_RXMAXP, tmp);
++ musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+
+ /* force shared fifo to OUT-only mode */
+ if (hw_ep->is_shared_fifo) {
+--- a/drivers/usb/musb/musb_gadget.h
++++ b/drivers/usb/musb/musb_gadget.h
+@@ -79,6 +79,8 @@ struct musb_ep {
+
+ /* true if lock must be dropped but req_list may not be advanced */
+ u8 busy;
++
++ u8 hb_mult;
+ };
+
+ static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
diff --git a/usb/usb-musb-suppress-warning-about-unused-flags.patch b/usb/usb-musb-suppress-warning-about-unused-flags.patch
new file mode 100644
index 00000000000000..b2cc71efe4d3a2
--- /dev/null
+++ b/usb/usb-musb-suppress-warning-about-unused-flags.patch
@@ -0,0 +1,35 @@
+From linux-usb-owner@vger.kernel.org Tue Oct 5 13:30:15 2010
+From: Felipe Balbi <balbi@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linux USB Mailing List <linux-usb@vger.kernel.org>,
+ Jon Povey <jon.povey@racelogic.co.uk>,
+ Felipe Balbi <balbi@ti.com>
+Subject: USB: musb: suppress warning about unused flags
+Date: Fri, 24 Sep 2010 13:44:10 +0300
+Message-Id: <1285325055-1247-10-git-send-email-balbi@ti.com>
+
+From: Jon Povey <jon.povey@racelogic.co.uk>
+
+Wrap flags with uninitialized_var() to suppress this:
+
+drivers/usb/musb/cppi_dma.c:1158: warning: 'flags' may be used uninitialized
+in this function
+
+Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/musb/cppi_dma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/cppi_dma.c
++++ b/drivers/usb/musb/cppi_dma.c
+@@ -1156,7 +1156,7 @@ irqreturn_t cppi_interrupt(int irq, void
+ struct musb_hw_ep *hw_ep = NULL;
+ u32 rx, tx;
+ int i, index;
+- unsigned long flags;
++ unsigned long uninitialized_var(flags);
+
+ cppi = container_of(musb->dma_controller, struct cppi, controller);
+ if (cppi->irq)
diff --git a/usb/usb-yurex-fix-memory-leak-and-corrupted-messages.patch b/usb/usb-yurex-fix-memory-leak-and-corrupted-messages.patch
new file mode 100644
index 00000000000000..289c600642e15b
--- /dev/null
+++ b/usb/usb-yurex-fix-memory-leak-and-corrupted-messages.patch
@@ -0,0 +1,100 @@
+From tomoki.sekiyama@gmail.com Tue Oct 5 14:18:42 2010
+From: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
+To: gregkh@suse.de
+Cc: linux-usb@vger.kernel.org,
+ Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
+Subject: USB: yurex: fix memory leak and corrupted messages
+Date: Sun, 3 Oct 2010 06:59:06 +0900
+Message-Id: <1286056746-25648-1-git-send-email-tomoki.sekiyama@gmail.com>
+
+This fixes the memory leak on disconnecting the device.
+In addition, it fixes some messages corrupted by incorrect encoding.
+
+Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/yurex.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -37,7 +37,7 @@
+ #define CMD_PADDING 0xff
+
+ #define YUREX_BUF_SIZE 8
+-#define YUREX_WRITE_TIMEOUT (HZ)
++#define YUREX_WRITE_TIMEOUT (HZ*2)
+
+ /* table of devices that work with this driver */
+ static struct usb_device_id yurex_table[] = {
+@@ -83,7 +83,7 @@ static void yurex_control_callback(struc
+ int status = urb->status;
+
+ if (status) {
+- err("%s - control failed: %d�n", __func__, status);
++ err("%s - control failed: %d\n", __func__, status);
+ wake_up_interruptible(&dev->waitq);
+ return;
+ }
+@@ -97,6 +97,16 @@ static void yurex_delete(struct kref *kr
+ dbg("yurex_delete");
+
+ usb_put_dev(dev->udev);
++ if (dev->cntl_urb) {
++ usb_kill_urb(dev->cntl_urb);
++ if (dev->cntl_req)
++ usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
++ dev->cntl_req, dev->cntl_urb->setup_dma);
++ if (dev->cntl_buffer)
++ usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
++ dev->cntl_buffer, dev->cntl_urb->transfer_dma);
++ usb_free_urb(dev->cntl_urb);
++ }
+ if (dev->urb) {
+ usb_kill_urb(dev->urb);
+ if (dev->int_buffer)
+@@ -253,7 +263,7 @@ static int yurex_probe(struct usb_interf
+ usb_sndctrlpipe(dev->udev, 0),
+ (void *)dev->cntl_req, dev->cntl_buffer,
+ YUREX_BUF_SIZE, yurex_control_callback, dev);
+- dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++ dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+
+ /* allocate interrupt URB */
+@@ -276,6 +286,7 @@ static int yurex_probe(struct usb_interf
+ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
+ dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
+ dev, 1);
++ dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
+ retval = -EIO;
+ err("Could not submitting URB");
+@@ -296,7 +307,7 @@ static int yurex_probe(struct usb_interf
+ dev->bbu = -1;
+
+ dev_info(&interface->dev,
+- "USB Yurex device now attached to Yurex-%d�n",
++ "USB YUREX device now attached to Yurex #%d\n",
+ interface->minor);
+
+ return 0;
+@@ -331,7 +342,7 @@ static void yurex_disconnect(struct usb_
+ /* decrement our usage count */
+ kref_put(&dev->kref, yurex_delete);
+
+- dev_info(&interface->dev, "USB Yurex #%d now disconnected", minor);
++ dev_info(&interface->dev, "USB YUREX #%d now disconnected\n", minor);
+ }
+
+ static struct usb_driver yurex_driver = {
+@@ -417,7 +428,7 @@ static ssize_t yurex_read(struct file *f
+ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+- bytes_read = snprintf(in_buffer, 20, "%lld�n", dev->bbu);
++ bytes_read = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ if (*ppos < bytes_read) {