Skip to content

Commit

Permalink
usb: musb: Perform only write access on MUSB_INTRRXE
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_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@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 515ba29 commit af5ec14
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 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 @@ -725,7 +725,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->intrrxe = musb->epmask & 0xfffe;
musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7);
musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
|USB_PORT_STAT_HIGH_SPEED
Expand Down Expand Up @@ -947,7 +948,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->intrrxe = musb->epmask & 0xfffe;
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);

musb_writeb(regs, MUSB_TESTMODE, 0);
Expand Down Expand Up @@ -986,6 +988,7 @@ static void musb_generic_disable(struct musb *musb)
/* disable interrupts */
musb_writeb(mbase, MUSB_INTRUSBE, 0);
musb_writew(mbase, MUSB_INTRTXE, 0);
musb->intrrxe = 0;
musb_writew(mbase, MUSB_INTRRXE, 0);

/* off */
Expand Down Expand Up @@ -2122,7 +2125,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.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);
Expand Down Expand Up @@ -2196,7 +2198,7 @@ static void musb_restore_context(struct musb *musb)
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_INTRRXE, musb->context.intrrxe);
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
3 changes: 2 additions & 1 deletion drivers/usb/musb/musb_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ struct musb_csr_regs {
struct musb_context_registers {

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

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

Expand Down
10 changes: 4 additions & 6 deletions drivers/usb/musb/musb_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,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;
Expand All @@ -1120,8 +1119,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
goto fail;
}

int_rxe |= (1 << epnum);
musb_writew(mbase, MUSB_INTRRXE, int_rxe);
musb->intrrxe |= (1 << epnum);
musb_writew(mbase, MUSB_INTRRXE, musb->intrrxe);

/* REVISIT if can_bulk_combine() use by updating "tmp"
* likewise high bandwidth periodic rx
Expand Down Expand Up @@ -1214,9 +1213,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->intrrxe &= ~(1 << epnum);
musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);
musb_writew(epio, MUSB_RXMAXP, 0);
}

Expand Down

0 comments on commit af5ec14

Please sign in to comment.