Skip to content

Commit

Permalink
usb: musb: Perform only write access on MUSB_INTRTXE
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sebastian Andrzej Siewior authored and Felipe Balbi committed Oct 31, 2012
1 parent af5ec14 commit b18d26f
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 16 deletions.
10 changes: 6 additions & 4 deletions drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/musb/musb_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ struct musb_csr_regs {
struct musb_context_registers {

u8 power;
u16 intrtxe;
u8 intrusbe;
u16 frame;
u8 index, testmode;
Expand All @@ -314,6 +313,7 @@ struct musb {
u16 hwvers;

u16 intrrxe;
u16 intrtxe;
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
#define MUSB_PORT_STAT_RESUME (1 << 31)

Expand Down
17 changes: 7 additions & 10 deletions drivers/usb/musb/musb_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1530,16 +1528,15 @@ 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;

spin_lock_irqsave(&musb->lock, flags);
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);
Expand All @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/musb/musb_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
csr = musb_readw(epio, MUSB_TXCSR);

/* disable interrupt in case we flush */
int_txe = musb_readw(mbase, MUSB_INTRTXE);
int_txe = musb->intrtxe;
musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));

/* general endpoint setup */
Expand Down

0 comments on commit b18d26f

Please sign in to comment.