summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-10-30 19:52:26 +0100
committerFelipe Balbi <balbi@ti.com>2012-10-31 14:22:18 +0100
commitb18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2 (patch)
tree651526d8d433418664bcee887f6d1a60ee7946f7 /drivers/usb/musb/musb_gadget.c
parentusb: musb: Perform only write access on MUSB_INTRRXE (diff)
downloadlinux-b18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2.tar.xz
linux-b18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2.zip
usb: musb: Perform only write access on MUSB_INTRTXE
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_INTRTXE results in an 32bit read access which also reads INTRRX and therefore may lose interrupts. This patch uses a shadow register of MUSB_INTRTXE so we only perform write access to it. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index bb684f0f790d..28b9790e84ea 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1068,7 +1068,6 @@ static int musb_gadget_enable(struct usb_ep *ep,
*/
musb_ep_select(mbase, epnum);
if (usb_endpoint_dir_in(desc)) {
- u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
if (hw_ep->is_shared_fifo)
musb_ep->is_in = 1;
@@ -1080,8 +1079,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
goto fail;
}
- int_txe |= (1 << epnum);
- musb_writew(mbase, MUSB_INTRTXE, int_txe);
+ musb->intrtxe |= (1 << epnum);
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);
/* REVISIT if can_bulk_split(), use by updating "tmp";
* likewise high bandwidth periodic tx
@@ -1208,9 +1207,8 @@ static int musb_gadget_disable(struct usb_ep *ep)
/* zero the endpoint sizes */
if (musb_ep->is_in) {
- u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE);
- int_txe &= ~(1 << epnum);
- musb_writew(musb->mregs, MUSB_INTRTXE, int_txe);
+ musb->intrtxe &= ~(1 << epnum);
+ musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe);
musb_writew(epio, MUSB_TXMAXP, 0);
} else {
musb->intrrxe &= ~(1 << epnum);
@@ -1530,7 +1528,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
void __iomem *epio = musb->endpoints[epnum].regs;
void __iomem *mbase;
unsigned long flags;
- u16 csr, int_txe;
+ u16 csr;
mbase = musb->mregs;
@@ -1538,8 +1536,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
musb_ep_select(mbase, (u8) epnum);
/* disable interrupts */
- int_txe = musb_readw(mbase, MUSB_INTRTXE);
- musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe & ~(1 << epnum));
if (musb_ep->is_in) {
csr = musb_readw(epio, MUSB_TXCSR);
@@ -1563,7 +1560,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
}
/* re-enable interrupt */
- musb_writew(mbase, MUSB_INTRTXE, int_txe);
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);
spin_unlock_irqrestore(&musb->lock, flags);
}