usb: musb: read MUSB_POWER register only when required.
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 30 Oct 2012 18:52:23 +0000 (19:52 +0100)
committerFelipe Balbi <balbi@ti.com>
Wed, 31 Oct 2012 13:20:40 +0000 (15:20 +0200)
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>
drivers/usb/musb/musb_core.c

index bb56a0e..d156fe8 100644 (file)
@@ -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 */