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

Commit 2d8c44ac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "i2c-msm-v2: fix potential spinning forever in ISR"

parents c1f5e3d3 ac6c7ff9
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -1781,10 +1781,10 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)

		/* HW workaround: when interrupt is level triggerd, more
		 * than one interrupt may fire in error cases. Thus we
		 * resetting the QUP core state immediately in the ISR
		 * to ward off the next interrupt.
		 * change the QUP core state to Reset immediately in the
		 * ISR to ward off the next interrupt.
		 */
		i2c_msm_qup_state_set(ctrl, QUP_STATE_RESET);
		writel_relaxed(QUP_STATE_RESET, ctrl->rsrcs.base + QUP_STATE);

		signal_complete = true;
		log_event       = true;
@@ -1975,6 +1975,13 @@ static int i2c_msm_qup_post_xfer(struct i2c_msm_ctrl *ctrl, int err)
		}
	}

	/*
	 * Disable the IRQ before change to reset state to avoid
	 * spurious interrupts.
	 *
	 */
	disable_irq(ctrl->rsrcs.irq);

	/* flush dma data and reset the qup core in timeout error.
	 * for other error case, its handled by the ISR
	 */
@@ -1983,8 +1990,9 @@ static int i2c_msm_qup_post_xfer(struct i2c_msm_ctrl *ctrl, int err)
		if (ctrl->xfer.mode_id == I2C_MSM_XFER_MODE_DMA)
			writel_relaxed(QUP_I2C_FLUSH, ctrl->rsrcs.base
								+ QUP_STATE);
		/* reset the sw core */
		i2c_msm_qup_sw_reset(ctrl);

		/* reset the qup core */
		i2c_msm_qup_state_set(ctrl, QUP_STATE_RESET);
		err = -ETIMEDOUT;
	} else if (ctrl->xfer.err == I2C_MSM_ERR_NACK) {
		err = -ENOTCONN;
@@ -2214,7 +2222,6 @@ static int i2c_msm_pm_xfer_start(struct i2c_msm_ctrl *ctrl)

static void i2c_msm_pm_xfer_end(struct i2c_msm_ctrl *ctrl)
{
	disable_irq(ctrl->rsrcs.irq);

	atomic_set(&ctrl->xfer.is_active, 0);