Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b11e94d0 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Felipe Balbi
Browse files

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: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 4b0de6f3
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -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 */