summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_core.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior2012-10-30 19:52:26 +0100
committerFelipe Balbi2012-10-31 14:22:18 +0100
commitb18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2 (patch)
tree651526d8d433418664bcee887f6d1a60ee7946f7 /drivers/usb/musb/musb_core.c
parentusb: musb: Perform only write access on MUSB_INTRRXE (diff)
downloadkernel-qcow2-linux-b18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2.tar.gz
kernel-qcow2-linux-b18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2.tar.xz
kernel-qcow2-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_core.c')
-rw-r--r--drivers/usb/musb/musb_core.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 7ff1986e5e52..25a0d8e1be51 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -724,7 +724,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
if (is_peripheral_active(musb)) {
/* REVISIT HNP; just force disconnect */
}
- musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask);
+ musb->intrtxe = musb->epmask;
+ musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe);
musb->intrrxe = musb->epmask & 0xfffe;
musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7);
@@ -947,7 +948,8 @@ void musb_start(struct musb *musb)
dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
/* Set INT enable registers, enable interrupts */
- musb_writew(regs, MUSB_INTRTXE, musb->epmask);
+ musb->intrtxe = musb->epmask;
+ musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
musb->intrrxe = musb->epmask & 0xfffe;
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
@@ -987,6 +989,7 @@ static void musb_generic_disable(struct musb *musb)
/* disable interrupts */
musb_writeb(mbase, MUSB_INTRUSBE, 0);
+ musb->intrtxe = 0;
musb_writew(mbase, MUSB_INTRTXE, 0);
musb->intrrxe = 0;
musb_writew(mbase, MUSB_INTRRXE, 0);
@@ -2124,7 +2127,6 @@ static void musb_save_context(struct musb *musb)
musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
musb->context.power = musb_readb(musb_base, MUSB_POWER);
- musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
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);
@@ -2197,7 +2199,7 @@ static void musb_restore_context(struct musb *musb)
musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
musb_writeb(musb_base, MUSB_POWER, musb->context.power);
- musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe);
+ musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);