Skip to content

Commit

Permalink
usb: musb: read MUSB_POWER register only when required.
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 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>
  • Loading branch information
Sebastian Andrzej Siewior authored and Felipe Balbi committed Oct 31, 2012
1 parent 4b0de6f commit b11e94d
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -485,13 +485,15 @@ 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:
/* remote wakeup? later, GetPortStatus
* will stop RESUME signaling
*/

power = musb_readb(musb->mregs, MUSB_POWER);
if (power & MUSB_POWER_SUSPENDM) {
/* spurious */
musb->int_usb &= ~MUSB_INTR_SUSPEND;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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",
Expand All @@ -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 */

Expand Down

0 comments on commit b11e94d

Please sign in to comment.