usb: musb: Perform only write access on MUSB_INTRRXE
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>
This commit is contained in:
Родитель
515ba29cd7
Коммит
af5ec14d40
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче