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

Commit 62cafffc 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: wait for qup core to be in valid state after reset"

parents cd2fa386 677936e0
Loading
Loading
Loading
Loading
+22 −22
Original line number Diff line number Diff line
@@ -2278,12 +2278,6 @@ static int i2c_msm_bam_init(struct i2c_msm_ctrl *ctrl)
	if (bam->is_init)
		return 0;

	ret = (*ctrl->ver.init)(ctrl);
	if (ret) {
		dev_err(ctrl->dev, "error on initializing QUP registers\n");
		return ret;
	}

	i2c_msm_dbg(ctrl, MSM_DBG, "initializing BAM@0x%p", bam);

	if (bam->is_core_init)
@@ -2729,12 +2723,18 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
		/* Dump the register values before reset the core */
		if (ctrl->dbgfs.dbg_lvl >= MSM_DBG)
			i2c_msm_dbg_qup_reg_dump(ctrl);
		/*
		 * HW workaround: when interrupt is level triggerd, more than
		 * one interrupt may fire in error cases. Thus we reset the
		 * core immidiatly in the ISR to ward off the next interrupt.

		/* Flush for the tags in case of an error and BAM Mode*/
		if (ctrl->xfer.mode_id == I2C_MSM_XFER_MODE_BAM)
			writel_relaxed(QUP_I2C_FLUSH, ctrl->rsrcs.base
								+ QUP_STATE);

		/* HW workaround: when interrupt is level triggerd, more
		 * than one interrupt may fire in error cases. Thus we
		 * reset the core immidiatly in the ISR to ward off the
		 * next interrupt.
		 */
		writel_relaxed(1, ctrl->rsrcs.base + QUP_SW_RESET);
		i2c_msm_qup_sw_reset(ctrl);

		need_wmb        = true;
		signal_complete = true;
@@ -2978,8 +2978,6 @@ static void i2c_msm_qup_teardown(struct i2c_msm_ctrl *ctrl)

static int i2c_msm_qup_post_xfer(struct i2c_msm_ctrl *ctrl, int err)
{
	bool need_reset = false;

	/* poll until bus is released */
	if (i2c_msm_qup_poll_bus_active_unset(ctrl)) {
		if ((ctrl->xfer.err & I2C_MSM_ERR_ARB_LOST) ||
@@ -2994,25 +2992,27 @@ static int i2c_msm_qup_post_xfer(struct i2c_msm_ctrl *ctrl, int err)
		}
	}

	/* flush bam data and reset the qup core in timeout error.
	 * for other error case, its handled by the ISR
	 */
	if (ctrl->xfer.err & I2C_MSM_ERR_TIMEOUT) {
		/* Flush for the BAM registers */
		if (ctrl->xfer.mode_id == I2C_MSM_XFER_MODE_BAM)
			writel_relaxed(QUP_I2C_FLUSH, ctrl->rsrcs.base
								+ QUP_STATE);

		/* reset the sw core */
		i2c_msm_qup_sw_reset(ctrl);
		err = -ETIMEDOUT;
		need_reset = true;
	}

	if (ctrl->xfer.err & I2C_MSM_ERR_BUS_ERR) {
		if (!err)
			err = -EIO;
		need_reset = true;
	}

	if (ctrl->xfer.err & I2C_MSM_ERR_NACK) {
		writel_relaxed(QUP_I2C_FLUSH,  ctrl->rsrcs.base + QUP_STATE);
	if (ctrl->xfer.err & I2C_MSM_ERR_NACK)
		err = -ENOTCONN;
		need_reset = true;
	}

	if (need_reset)
		i2c_msm_qup_init(ctrl);

	return err;
}