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

Commit 11d53609 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "i2c-qcom-geni: Updated error handling in I2C driver"

parents f067574c 1dd0ec41
Loading
Loading
Loading
Loading
+19 −5
Original line number Original line Diff line number Diff line
@@ -122,6 +122,7 @@ struct geni_i2c_dev {
	struct msm_gpi_dma_async_tx_cb_param tx_cb;
	struct msm_gpi_dma_async_tx_cb_param tx_cb;
	struct msm_gpi_dma_async_tx_cb_param rx_cb;
	struct msm_gpi_dma_async_tx_cb_param rx_cb;
	enum i2c_se_mode se_mode;
	enum i2c_se_mode se_mode;
	bool cmd_done;
};
};


struct geni_i2c_err_log {
struct geni_i2c_err_log {
@@ -247,6 +248,7 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)


	if (!cur || (m_stat & M_CMD_FAILURE_EN) ||
	if (!cur || (m_stat & M_CMD_FAILURE_EN) ||
		    (dm_rx_st & (DM_I2C_CB_ERR)) ||
		    (dm_rx_st & (DM_I2C_CB_ERR)) ||
		    (m_stat & M_CMD_CANCEL_EN) ||
		    (m_stat & M_CMD_ABORT_EN)) {
		    (m_stat & M_CMD_ABORT_EN)) {


		if (m_stat & M_GP_IRQ_1_EN)
		if (m_stat & M_GP_IRQ_1_EN)
@@ -267,6 +269,7 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
		if (!dma)
		if (!dma)
			writel_relaxed(0, (gi2c->base +
			writel_relaxed(0, (gi2c->base +
					   SE_GENI_TX_WATERMARK_REG));
					   SE_GENI_TX_WATERMARK_REG));
		gi2c->cmd_done = true;
		goto irqret;
		goto irqret;
	}
	}


@@ -323,18 +326,24 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
		if (dm_tx_st)
		if (dm_tx_st)
			writel_relaxed(dm_tx_st, gi2c->base +
			writel_relaxed(dm_tx_st, gi2c->base +
				       SE_DMA_TX_IRQ_CLR);
				       SE_DMA_TX_IRQ_CLR);

		if (dm_rx_st)
		if (dm_rx_st)
			writel_relaxed(dm_rx_st, gi2c->base +
			writel_relaxed(dm_rx_st, gi2c->base +
				       SE_DMA_RX_IRQ_CLR);
				       SE_DMA_RX_IRQ_CLR);
		/* Ensure all writes are done before returning from ISR. */
		/* Ensure all writes are done before returning from ISR. */
		wmb();
		wmb();
		if ((dm_tx_st & TX_DMA_DONE) || (dm_rx_st & RX_DMA_DONE))
			complete(&gi2c->xfer);


		if ((dm_tx_st & TX_DMA_DONE) || (dm_rx_st & RX_DMA_DONE))
			gi2c->cmd_done = true;
	}
	}
	/* if this is err with done-bit not set, handle that thr' timeout. */

	else if (m_stat & M_CMD_DONE_EN)
	else if (m_stat & M_CMD_DONE_EN)
		gi2c->cmd_done = true;

	if (gi2c->cmd_done) {
		gi2c->cmd_done = false;
		complete(&gi2c->xfer);
		complete(&gi2c->xfer);
	}


	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}
@@ -731,13 +740,18 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
		mb();
		mb();
		timeout = wait_for_completion_timeout(&gi2c->xfer,
		timeout = wait_for_completion_timeout(&gi2c->xfer,
						gi2c->xfer_timeout);
						gi2c->xfer_timeout);
		if (!timeout) {
		if (!timeout)
			geni_i2c_err(gi2c, GENI_TIMEOUT);
			geni_i2c_err(gi2c, GENI_TIMEOUT);

		if (gi2c->err) {
			reinit_completion(&gi2c->xfer);
			reinit_completion(&gi2c->xfer);
			gi2c->cur = NULL;
			gi2c->cur = NULL;
			geni_abort_m_cmd(gi2c->base);
			geni_cancel_m_cmd(gi2c->base);
			timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
			timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
			if (!timeout)
				geni_abort_m_cmd(gi2c->base);
		}
		}

		gi2c->cur_wr = 0;
		gi2c->cur_wr = 0;
		gi2c->cur_rd = 0;
		gi2c->cur_rd = 0;
		if (mode == SE_DMA) {
		if (mode == SE_DMA) {
+8 −6
Original line number Original line Diff line number Diff line
@@ -334,10 +334,6 @@ static int geni_se_select_fifo_mode(void __iomem *base)
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_RX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_RX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_IRQ_EN);
	geni_write_reg(0xFFFFFFFF, base, SE_IRQ_EN);


	/* Clearing registers before reading */
	geni_write_reg(0x00000000, base, SE_GENI_M_IRQ_EN);
	geni_write_reg(0x00000000, base, SE_GENI_S_IRQ_EN);

	common_geni_m_irq_en = geni_read_reg(base, SE_GENI_M_IRQ_EN);
	common_geni_m_irq_en = geni_read_reg(base, SE_GENI_M_IRQ_EN);
	common_geni_s_irq_en = geni_read_reg(base, SE_GENI_S_IRQ_EN);
	common_geni_s_irq_en = geni_read_reg(base, SE_GENI_S_IRQ_EN);
	geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN);
	geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN);
@@ -357,7 +353,9 @@ static int geni_se_select_fifo_mode(void __iomem *base)


static int geni_se_select_dma_mode(void __iomem *base)
static int geni_se_select_dma_mode(void __iomem *base)
{
{
	int proto = get_se_proto(base);
	unsigned int geni_dma_mode = 0;
	unsigned int geni_dma_mode = 0;
	unsigned int common_geni_m_irq_en;


	geni_write_reg(0, base, SE_GSI_EVENT_EN);
	geni_write_reg(0, base, SE_GSI_EVENT_EN);
	geni_write_reg(0xFFFFFFFF, base, SE_GENI_M_IRQ_CLEAR);
	geni_write_reg(0xFFFFFFFF, base, SE_GENI_M_IRQ_CLEAR);
@@ -365,9 +363,13 @@ static int geni_se_select_dma_mode(void __iomem *base)
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_TX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_TX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_RX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_DMA_RX_IRQ_CLR);
	geni_write_reg(0xFFFFFFFF, base, SE_IRQ_EN);
	geni_write_reg(0xFFFFFFFF, base, SE_IRQ_EN);
	geni_write_reg(0x00000000, base, SE_GENI_M_IRQ_EN);
	geni_write_reg(0x00000000, base, SE_GENI_S_IRQ_EN);


	common_geni_m_irq_en = geni_read_reg(base, SE_GENI_M_IRQ_EN);
	if (proto != UART)
		common_geni_m_irq_en &=
			~(M_TX_FIFO_WATERMARK_EN | M_RX_FIFO_WATERMARK_EN);

	geni_write_reg(common_geni_m_irq_en, base, SE_GENI_M_IRQ_EN);
	geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN);
	geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN);
	geni_dma_mode |= GENI_DMA_MODE_EN;
	geni_dma_mode |= GENI_DMA_MODE_EN;
	geni_write_reg(geni_dma_mode, base, SE_GENI_DMA_MODE_EN);
	geni_write_reg(geni_dma_mode, base, SE_GENI_DMA_MODE_EN);