diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-10-30 14:52:23 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-10-31 09:20:40 -0400 |
commit | b11e94d03726c5dbee0d9a841a025313504e90f4 (patch) | |
tree | 1c0b0f9dd296ca4580ad87b5d041b4a832f83d5c /drivers | |
parent | 4b0de6f38362960460d3693f122c6abe6bb0704b (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bb56a0e8b23b..d156fe8bebfa 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -467,12 +467,12 @@ void musb_hnp_stop(struct musb *musb) | |||
467 | */ | 467 | */ |
468 | 468 | ||
469 | static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | 469 | static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, |
470 | u8 devctl, u8 power) | 470 | u8 devctl) |
471 | { | 471 | { |
472 | struct usb_otg *otg = musb->xceiv->otg; | 472 | struct usb_otg *otg = musb->xceiv->otg; |
473 | irqreturn_t handled = IRQ_NONE; | 473 | irqreturn_t handled = IRQ_NONE; |
474 | 474 | ||
475 | dev_dbg(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, | 475 | dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, |
476 | int_usb); | 476 | int_usb); |
477 | 477 | ||
478 | /* in host mode, the peripheral may issue remote wakeup. | 478 | /* 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, | |||
485 | 485 | ||
486 | if (devctl & MUSB_DEVCTL_HM) { | 486 | if (devctl & MUSB_DEVCTL_HM) { |
487 | void __iomem *mbase = musb->mregs; | 487 | void __iomem *mbase = musb->mregs; |
488 | u8 power; | ||
488 | 489 | ||
489 | switch (musb->xceiv->state) { | 490 | switch (musb->xceiv->state) { |
490 | case OTG_STATE_A_SUSPEND: | 491 | case OTG_STATE_A_SUSPEND: |
@@ -492,6 +493,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
492 | * will stop RESUME signaling | 493 | * will stop RESUME signaling |
493 | */ | 494 | */ |
494 | 495 | ||
496 | power = musb_readb(musb->mregs, MUSB_POWER); | ||
495 | if (power & MUSB_POWER_SUSPENDM) { | 497 | if (power & MUSB_POWER_SUSPENDM) { |
496 | /* spurious */ | 498 | /* spurious */ |
497 | musb->int_usb &= ~MUSB_INTR_SUSPEND; | 499 | musb->int_usb &= ~MUSB_INTR_SUSPEND; |
@@ -655,8 +657,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
655 | } | 657 | } |
656 | 658 | ||
657 | if (int_usb & MUSB_INTR_SUSPEND) { | 659 | if (int_usb & MUSB_INTR_SUSPEND) { |
658 | dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n", | 660 | dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n", |
659 | otg_state_string(musb->xceiv->state), devctl, power); | 661 | otg_state_string(musb->xceiv->state), devctl); |
660 | handled = IRQ_HANDLED; | 662 | handled = IRQ_HANDLED; |
661 | 663 | ||
662 | switch (musb->xceiv->state) { | 664 | switch (musb->xceiv->state) { |
@@ -1560,12 +1562,11 @@ static irqreturn_t generic_interrupt(int irq, void *__hci) | |||
1560 | irqreturn_t musb_interrupt(struct musb *musb) | 1562 | irqreturn_t musb_interrupt(struct musb *musb) |
1561 | { | 1563 | { |
1562 | irqreturn_t retval = IRQ_NONE; | 1564 | irqreturn_t retval = IRQ_NONE; |
1563 | u8 devctl, power; | 1565 | u8 devctl; |
1564 | int ep_num; | 1566 | int ep_num; |
1565 | u32 reg; | 1567 | u32 reg; |
1566 | 1568 | ||
1567 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 1569 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
1568 | power = musb_readb(musb->mregs, MUSB_POWER); | ||
1569 | 1570 | ||
1570 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", | 1571 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", |
1571 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", | 1572 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", |
@@ -1576,7 +1577,7 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
1576 | */ | 1577 | */ |
1577 | if (musb->int_usb) | 1578 | if (musb->int_usb) |
1578 | retval |= musb_stage0_irq(musb, musb->int_usb, | 1579 | retval |= musb_stage0_irq(musb, musb->int_usb, |
1579 | devctl, power); | 1580 | devctl); |
1580 | 1581 | ||
1581 | /* "stage 1" is handling endpoint irqs */ | 1582 | /* "stage 1" is handling endpoint irqs */ |
1582 | 1583 | ||