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

Commit c4c5210b authored by Jack Pham's avatar Jack Pham
Browse files

usb: dwc3-msm: Prevent suspend during pwr_event_handler



While a pwr event IRQ can arrive asynchronously, the handler
takes care to only call dwc3_pwr_event_handler() when not in
LPM mode since the core clock needs to be on to access the
status registers. However, this doesn't account for concurrent
runtime PM occurring which could still result in an unclocked
access if suspend completes before pwr_event_handler() does.
Prevent a premature suspend by temporarily incrementing the
runtime PM count at the beginning of pwr_event_handler() and
calling put() when done.

Change-Id: I0d0d26445c5ff0f7c7a3fc51862e4fa8a1ff7d6e
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 4fc51d05
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -1980,6 +1980,13 @@ static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc)
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	u32 irq_stat, irq_clear = 0;
	u32 irq_stat, irq_clear = 0;


	/*
	 * Increment the PM count to prevent suspend from happening
	 * during this routine. noresume is fine, since this function
	 * should only be called when not in LPM.
	 */
	pm_runtime_get_noresume(mdwc->dev);

	irq_stat = dwc3_msm_read_reg(mdwc->base, PWR_EVNT_IRQ_STAT_REG);
	irq_stat = dwc3_msm_read_reg(mdwc->base, PWR_EVNT_IRQ_STAT_REG);
	dev_dbg(mdwc->dev, "%s irq_stat=%X\n", __func__, irq_stat);
	dev_dbg(mdwc->dev, "%s irq_stat=%X\n", __func__, irq_stat);


@@ -2029,6 +2036,7 @@ static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc)
			__func__, irq_stat);
			__func__, irq_stat);


	dwc3_msm_write_reg(mdwc->base, PWR_EVNT_IRQ_STAT_REG, irq_clear);
	dwc3_msm_write_reg(mdwc->base, PWR_EVNT_IRQ_STAT_REG, irq_clear);
	pm_runtime_put(mdwc->dev);
}
}


static irqreturn_t msm_dwc3_pwr_irq_thread(int irq, void *_mdwc)
static irqreturn_t msm_dwc3_pwr_irq_thread(int irq, void *_mdwc)