diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-10-30 14:52:25 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-10-31 09:22:03 -0400 |
commit | af5ec14d40e0da1de17fcca2b41c76fae5c2cb9d (patch) | |
tree | 0bdfddd642e2455e34ece3a5551038a470db61f1 /drivers/usb/musb/musb_core.c | |
parent | 515ba29cd7b571da45365e4db80c1b6905869ef3 (diff) |
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>
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d156fe8bebfa..7ff1986e5e52 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -725,7 +725,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
725 | /* REVISIT HNP; just force disconnect */ | 725 | /* REVISIT HNP; just force disconnect */ |
726 | } | 726 | } |
727 | musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask); | 727 | musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask); |
728 | musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe); | 728 | musb->intrrxe = musb->epmask & 0xfffe; |
729 | musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe); | ||
729 | musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); | 730 | musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); |
730 | musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED | 731 | musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED |
731 | |USB_PORT_STAT_HIGH_SPEED | 732 | |USB_PORT_STAT_HIGH_SPEED |
@@ -947,7 +948,8 @@ void musb_start(struct musb *musb) | |||
947 | 948 | ||
948 | /* Set INT enable registers, enable interrupts */ | 949 | /* Set INT enable registers, enable interrupts */ |
949 | musb_writew(regs, MUSB_INTRTXE, musb->epmask); | 950 | musb_writew(regs, MUSB_INTRTXE, musb->epmask); |
950 | musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe); | 951 | musb->intrrxe = musb->epmask & 0xfffe; |
952 | musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); | ||
951 | musb_writeb(regs, MUSB_INTRUSBE, 0xf7); | 953 | musb_writeb(regs, MUSB_INTRUSBE, 0xf7); |
952 | 954 | ||
953 | musb_writeb(regs, MUSB_TESTMODE, 0); | 955 | musb_writeb(regs, MUSB_TESTMODE, 0); |
@@ -986,6 +988,7 @@ static void musb_generic_disable(struct musb *musb) | |||
986 | /* disable interrupts */ | 988 | /* disable interrupts */ |
987 | musb_writeb(mbase, MUSB_INTRUSBE, 0); | 989 | musb_writeb(mbase, MUSB_INTRUSBE, 0); |
988 | musb_writew(mbase, MUSB_INTRTXE, 0); | 990 | musb_writew(mbase, MUSB_INTRTXE, 0); |
991 | musb->intrrxe = 0; | ||
989 | musb_writew(mbase, MUSB_INTRRXE, 0); | 992 | musb_writew(mbase, MUSB_INTRRXE, 0); |
990 | 993 | ||
991 | /* off */ | 994 | /* off */ |
@@ -2122,7 +2125,6 @@ static void musb_save_context(struct musb *musb) | |||
2122 | musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); | 2125 | musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); |
2123 | musb->context.power = musb_readb(musb_base, MUSB_POWER); | 2126 | musb->context.power = musb_readb(musb_base, MUSB_POWER); |
2124 | musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); | 2127 | musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); |
2125 | musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); | ||
2126 | musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); | 2128 | musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); |
2127 | musb->context.index = musb_readb(musb_base, MUSB_INDEX); | 2129 | musb->context.index = musb_readb(musb_base, MUSB_INDEX); |
2128 | musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); | 2130 | musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); |
@@ -2196,7 +2198,7 @@ static void musb_restore_context(struct musb *musb) | |||
2196 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); | 2198 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); |
2197 | musb_writeb(musb_base, MUSB_POWER, musb->context.power); | 2199 | musb_writeb(musb_base, MUSB_POWER, musb->context.power); |
2198 | musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); | 2200 | musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); |
2199 | musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe); | 2201 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); |
2200 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); | 2202 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); |
2201 | musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); | 2203 | musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); |
2202 | 2204 | ||