From 041d81f493d90c940ec41f0ec98bc7c4f2fba431 Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Thu, 4 Oct 2012 11:58:00 +0300
Subject: [PATCH 1/6] usb: dwc3: gadget: fix 'endpoint always busy' bug

If a USB transfer has already been started, meaning
we have already issued StartTransfer command to that
particular endpoint, DWC3_EP_BUSY flag has also
already been set.

When we try to cancel this transfer which is already
in controller's cache, we will not receive XferComplete
event and we must clear DWC3_EP_BUSY in order to allow
subsequent requests to be properly started.

The best place to clear that flag is right after issuing
DWC3_DEPCMD_ENDTRANSFER.

Cc: stable@vger.kernel.org # v3.4 v3.5 v3.6
Reported-by: Moiz Sonasath <m-sonasath@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/gadget.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c9e729a4bf65..7b7deddf6a52 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
 	ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
 	WARN_ON_ONCE(ret);
 	dep->resource_index = 0;
-
+	dep->flags &= ~DWC3_EP_BUSY;
 	udelay(100);
 }
 

From 6ff1f3d3bd7c69c62ca5773b1b684bce42eff06a Mon Sep 17 00:00:00 2001
From: Stefano Babic <sbabic@denx.de>
Date: Mon, 15 Oct 2012 11:20:22 +0200
Subject: [PATCH 2/6] usb: musb: am35xx: drop spurious unplugging a device

On AM3517, tx and rx interrupt are detected together with
the disconnect event. This generates a kernel panic in musb_interrupt,
because rx / tx are handled after disconnect.
This issue was seen on a Technexion's TAM3517 SOM. Unplugging a device,
tx / rx interrupts together with disconnect are detected. This brings
to kernel panic like this:

[   68.526153] Unable to handle kernel NULL pointer dereference at virtual address 00000011
[   68.534698] pgd = c0004000
[   68.537536] [00000011] *pgd=00000000
[   68.541351] Internal error: Oops: 17 [#1] ARM
[   68.545928] Modules linked in:
[   68.549163] CPU: 0    Not tainted  (3.6.0-rc5-00020-g9e05905 #178)
[   68.555694] PC is at rxstate+0x8/0xdc
[   68.559539] LR is at musb_interrupt+0x98/0x858
[   68.564239] pc : [<c035cd88>]    lr : [<c035af1c>]    psr: 40000193
[   68.564239] sp : ce83fb40  ip : d0906410  fp : 00000000
[   68.576293] r10: 00000000  r9 : cf3b0e40  r8 : 00000002
[   68.581817] r7 : 00000019  r6 : 00000001  r5 : 00000001  r4 : 000000d4
[   68.588684] r3 : 00000000  r2 : 00000000  r1 : ffffffcc  r0 : cf23c108
[   68.595550] Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment ke

Note: this behavior is not seen with a USB hub, while it is
easy to reproduce connecting a USB-pen directly to the USB-A of
the board.

Drop tx / rx interrupts if disconnect is detected.

Signed-off-by: Stefano Babic <sbabic@denx.de>
CC: Felipe Balbi <balbi@ti.com>
Cc: stable@vger.kernel.org # 3.5 3.6
Tested-by: Dmitry Lifshitz <lifshitz@compulab.co.il>
Tested-by: Igor Grinberg <grinberg@compulab.co.il>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/am35x.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 457f25e62c51..c964d6af178b 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
 		ret = IRQ_HANDLED;
 	}
 
+	/* Drop spurious RX and TX if device is disconnected */
+	if (musb->int_usb & MUSB_INTR_DISCONNECT) {
+		musb->int_tx = 0;
+		musb->int_rx = 0;
+	}
+
 	if (musb->int_tx || musb->int_rx || musb->int_usb)
 		ret |= musb_interrupt(musb);
 

From 01b8daf71b2fd2f6ece5f063a089abf4b13f1d6e Mon Sep 17 00:00:00 2001
From: Vivek Gautam <gautam.vivek@samsung.com>
Date: Sat, 13 Oct 2012 19:20:18 +0530
Subject: [PATCH 3/6] usb: dwc3: shutdown usb_phy when removing the device

We call usb_phy_init() from dwc3_core_init() during
probe, so adding usb_phy_shutdown() to dwc3_core_exit()
while removing the device so we don't keep PHYs
turned on, consuming power, unnecessarily.

Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index b415c0c859d3..c14ebc975ba4 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc)
 {
 	dwc3_event_buffers_cleanup(dwc);
 	dwc3_free_event_buffers(dwc);
+
+	usb_phy_shutdown(dwc->usb2_phy);
+	usb_phy_shutdown(dwc->usb3_phy);
+
 }
 
 #define DWC3_ALIGN_MASK		(16 - 1)

From c2fa3edc58a262dfcb7aea78e24661e90e00098c Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 15 Oct 2012 23:24:55 -0700
Subject: [PATCH 4/6] usb: renesas_usbhs: fixup __usbhs_for_each_pipe 1st pos

__usbhs_for_each_pipe() is the macro which moves around each pipe,
but it has a bug which didn't care about 1st pipe's position.
Because of this bug, it moves around
pipe0, pipe2, pipe3 ... even though it requested pipe1, pipe2, pipe3...
This patch modifies it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/renesas_usbhs/pipe.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 08786c06dcf1..3d80c7b1fd1b 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -54,7 +54,7 @@ struct usbhs_pipe_info {
  * pipe list
  */
 #define __usbhs_for_each_pipe(start, pos, info, i)	\
-	for (i = start, pos = (info)->pipe;		\
+	for (i = start, pos = (info)->pipe + i;		\
 	     i < (info)->size;				\
 	     i++, pos = (info)->pipe + i)
 

From d5c6a1e024dd5acd6ad2e1a6eb6a2fd5c15c50f1 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Thu, 11 Oct 2012 21:49:38 -0700
Subject: [PATCH 5/6] usb: renesas_usbhs: fixup interrupt status clear method

When interrupt happened, renesas_usbhs driver gets irq status
by usbhs_status_get_each_irq(), and cleared all status by using 0.
But, this method is incorrect,
since extra interrupt might occur between them.
This patch cleared corresponding bits only

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/renesas_usbhs/mod.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c
index 35c5208f3249..61933a90e5bf 100644
--- a/drivers/usb/renesas_usbhs/mod.c
+++ b/drivers/usb/renesas_usbhs/mod.c
@@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data)
 	usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
 	usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
 
-	usbhs_write(priv, BRDYSTS, 0);
-	usbhs_write(priv, NRDYSTS, 0);
-	usbhs_write(priv, BEMPSTS, 0);
+	usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
+	usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
+	usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
 
 	/*
 	 * call irq callback functions

From 69da85edbab5cd42909d3ba65b3dad1c1fb40206 Mon Sep 17 00:00:00 2001
From: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Date: Mon, 15 Oct 2012 09:47:35 -0300
Subject: [PATCH 6/6] usb: gadget: lpc32xx_udc: Fix compatibility with STOTG04

The STOTG04 is an replacement for ISP1301.

Most of the registers on STOTG04 are the same as on ISP1301, but the
register ISP1301_I2C_OTG_CONTROL_2 (address 0x10) doesn't exist on the
ST part.

This is a work around for this by using the interrupt source register that
should behave the same on both parts and has the needed information.

Tested-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/lpc32xx_udc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c
index f696fb9b136d..21a9861dabf0 100644
--- a/drivers/usb/gadget/lpc32xx_udc.c
+++ b/drivers/usb/gadget/lpc32xx_udc.c
@@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work)
 
 		/* Get the VBUS status from the transceiver */
 		value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client,
-						 ISP1301_I2C_OTG_CONTROL_2);
+						 ISP1301_I2C_INTERRUPT_SOURCE);
 
 		/* VBUS on or off? */
-		if (value & OTG_B_SESS_VLD)
+		if (value & INT_SESS_VLD)
 			udc->vbus = 1;
 		else
 			udc->vbus = 0;