usb: musb: read MUSB_POWER register only when required.
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 8bit read access to MUSB_POWER results in an 32bit read access which also reads INTRTX and therefore may lose interrupts. This patch tries to minimize reads to MUSB_POWER and perform them only when required. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Родитель
4b0de6f383
Коммит
b11e94d037
|
@ -467,12 +467,12 @@ void musb_hnp_stop(struct musb *musb)
|
|||
*/
|
||||
|
||||
static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
||||
u8 devctl, u8 power)
|
||||
u8 devctl)
|
||||
{
|
||||
struct usb_otg *otg = musb->xceiv->otg;
|
||||
irqreturn_t handled = IRQ_NONE;
|
||||
|
||||
dev_dbg(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
|
||||
dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl,
|
||||
int_usb);
|
||||
|
||||
/* in host mode, the peripheral may issue remote wakeup.
|
||||
|
@ -485,6 +485,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
|||
|
||||
if (devctl & MUSB_DEVCTL_HM) {
|
||||
void __iomem *mbase = musb->mregs;
|
||||
u8 power;
|
||||
|
||||
switch (musb->xceiv->state) {
|
||||
case OTG_STATE_A_SUSPEND:
|
||||
|
@ -492,6 +493,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
|||
* will stop RESUME signaling
|
||||
*/
|
||||
|
||||
power = musb_readb(musb->mregs, MUSB_POWER);
|
||||
if (power & MUSB_POWER_SUSPENDM) {
|
||||
/* spurious */
|
||||
musb->int_usb &= ~MUSB_INTR_SUSPEND;
|
||||
|
@ -655,8 +657,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
|||
}
|
||||
|
||||
if (int_usb & MUSB_INTR_SUSPEND) {
|
||||
dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n",
|
||||
otg_state_string(musb->xceiv->state), devctl, power);
|
||||
dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n",
|
||||
otg_state_string(musb->xceiv->state), devctl);
|
||||
handled = IRQ_HANDLED;
|
||||
|
||||
switch (musb->xceiv->state) {
|
||||
|
@ -1560,12 +1562,11 @@ static irqreturn_t generic_interrupt(int irq, void *__hci)
|
|||
irqreturn_t musb_interrupt(struct musb *musb)
|
||||
{
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
u8 devctl, power;
|
||||
u8 devctl;
|
||||
int ep_num;
|
||||
u32 reg;
|
||||
|
||||
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
||||
power = musb_readb(musb->mregs, MUSB_POWER);
|
||||
|
||||
dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n",
|
||||
(devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral",
|
||||
|
@ -1576,7 +1577,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
|
|||
*/
|
||||
if (musb->int_usb)
|
||||
retval |= musb_stage0_irq(musb, musb->int_usb,
|
||||
devctl, power);
|
||||
devctl);
|
||||
|
||||
/* "stage 1" is handling endpoint irqs */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче