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@xxxxxxxxxxxxx> --- drivers/usb/musb/musb_core.c | 8 +++++--- drivers/usb/musb/musb_gadget.c | 17 +++++++---------- drivers/usb/musb/musb_host.c | 8 +++----- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index ee04eae..b1dffea 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -670,7 +670,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->context.intrtxe = musb->epmask; + musb_writew(musb->mregs, MUSB_INTRTXE, musb->context.intrtxe); musb->context.intrrxe = musb->epmask & 0xfffe; musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe); musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); @@ -893,7 +894,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->context.intrtxe = musb->epmask; + musb_writew(regs, MUSB_INTRTXE, musb->context.intrtxe); musb->context.intrrxe = musb->epmask & 0xfffe; musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe); musb_writeb(regs, MUSB_INTRUSBE, 0xf7); @@ -942,6 +944,7 @@ static void musb_generic_disable(struct musb *musb) /* disable interrupts */ musb_writeb(mbase, MUSB_INTRUSBE, 0); + musb->context.intrtxe = 0; musb_writew(mbase, MUSB_INTRTXE, 0); musb->context.intrrxe = 0; musb_writew(musb->mregs, MUSB_INTRRXE, musb->context.intrrxe); @@ -2142,7 +2145,6 @@ static void musb_save_context(struct musb *musb) 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); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 629c2ea..cc24445 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1079,7 +1079,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; @@ -1091,8 +1090,8 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; } - int_txe |= (1 << epnum); - musb_writew(mbase, MUSB_INTRTXE, int_txe); + musb->context.intrtxe |= (1 << epnum); + musb_writew(mbase, MUSB_INTRTXE, musb->context.intrtxe); /* REVISIT if can_bulk_split(), use by updating "tmp"; * likewise high bandwidth periodic tx @@ -1218,9 +1217,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->context.intrtxe &= ~(1 << epnum); + musb_writew(musb->mregs, MUSB_INTRTXE, musb->context.intrtxe); musb_writew(epio, MUSB_TXMAXP, 0); } else { musb->context.intrrxe &= ~(1 << epnum); @@ -1539,7 +1537,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; @@ -1547,8 +1545,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->context.intrtxe & ~(1 << epnum)); if (musb_ep->is_in) { csr = musb_readw(epio, MUSB_TXCSR); @@ -1572,7 +1569,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->context.intrtxe); spin_unlock_irqrestore(&musb->lock, flags); } diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af..34829fe 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -714,15 +714,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum, /* OUT/transmit/EP0 or IN/receive? */ if (is_out) { u16 csr; - u16 int_txe; u16 load_count; csr = musb_readw(epio, MUSB_TXCSR); /* disable interrupt in case we flush */ - int_txe = musb_readw(mbase, MUSB_INTRTXE); - musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum)); - + musb_writew(mbase, MUSB_INTRTXE, musb->context.intrtxe & + ~(1 << epnum)); /* general endpoint setup */ if (epnum) { /* flush all old state, set default */ @@ -807,7 +805,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, } /* re-enable interrupt */ - musb_writew(mbase, MUSB_INTRTXE, int_txe); + musb_writew(mbase, MUSB_INTRTXE, musb->context.intrtxe); /* IN/receive */ } else { -- 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