[PATCH 2/5] usb/musb: Perform only write access on MUSB_INTRRXE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is part of the workaround for AM35x advisory Advisory 1.1.20.
The advisory says that the IPSS bridge can't handle 8 & 16 bit read
access. An 16bit read access to MUSB_INTRRXE results in an 32bit read
access which also reads INTRUSB and therefore may lose interrupts.
This patch uses a shadow register of MUSB_INTRRXE so we only perform
write access to it.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/musb/musb_core.c   |   10 ++++++----
 drivers/usb/musb/musb_gadget.c |   11 ++++-------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index d05439c..ee04eae 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -671,7 +671,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 			/* REVISIT HNP; just force disconnect */
 		}
 		musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask);
-		musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+		musb->context.intrrxe = musb->epmask & 0xfffe;
+		musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe);
 		musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7);
 		musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
 					|USB_PORT_STAT_HIGH_SPEED
@@ -893,7 +894,8 @@ void musb_start(struct musb *musb)
 
 	/*  Set INT enable registers, enable interrupts */
 	musb_writew(regs, MUSB_INTRTXE, musb->epmask);
-	musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+	musb->context.intrrxe = musb->epmask & 0xfffe;
+	musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe);
 	musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
 
 	musb_writeb(regs, MUSB_TESTMODE, 0);
@@ -941,7 +943,8 @@ static void musb_generic_disable(struct musb *musb)
 	/* disable interrupts */
 	musb_writeb(mbase, MUSB_INTRUSBE, 0);
 	musb_writew(mbase, MUSB_INTRTXE, 0);
-	musb_writew(mbase, MUSB_INTRRXE, 0);
+	musb->context.intrrxe = 0;
+	musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe);
 
 	/* off */
 	musb_writeb(mbase, MUSB_DEVCTL, 0);
@@ -2140,7 +2143,6 @@ static void musb_save_context(struct musb *musb)
 	}
 	musb->context.power = musb_readb(musb_base, MUSB_POWER);
 	musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
-	musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
 	musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
 	musb->context.index = musb_readb(musb_base, MUSB_INDEX);
 	musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index a495a30..629c2ea 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1119,8 +1119,6 @@ static int musb_gadget_enable(struct usb_ep *ep,
 		musb_writew(regs, MUSB_TXCSR, csr);
 
 	} else {
-		u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE);
-
 		if (hw_ep->is_shared_fifo)
 			musb_ep->is_in = 0;
 		if (musb_ep->is_in)
@@ -1131,8 +1129,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
 			goto fail;
 		}
 
-		int_rxe |= (1 << epnum);
-		musb_writew(mbase, MUSB_INTRRXE, int_rxe);
+		musb->context.intrrxe |= (1 << epnum);
+		musb_writew(mbase, MUSB_INTRRXE, musb->context.intrrxe);
 
 		/* REVISIT if can_bulk_combine() use by updating "tmp"
 		 * likewise high bandwidth periodic rx
@@ -1225,9 +1223,8 @@ static int musb_gadget_disable(struct usb_ep *ep)
 		musb_writew(musb->mregs, MUSB_INTRTXE, int_txe);
 		musb_writew(epio, MUSB_TXMAXP, 0);
 	} else {
-		u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE);
-		int_rxe &= ~(1 << epnum);
-		musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe);
+		musb->context.intrrxe &= ~(1 << epnum);
+		musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe);
 		musb_writew(epio, MUSB_RXMAXP, 0);
 	}
 
-- 
1.7.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux