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

Commit 89ca22e0 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 d254e1bb 28546f13
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ struct geni_i2c_dev {
	struct msm_gpi_dma_async_tx_cb_param tx_cb;
	struct msm_gpi_dma_async_tx_cb_param rx_cb;
	enum i2c_se_mode se_mode;
	bool cmd_done;
};

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

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

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

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

		if (dm_rx_st)
			writel_relaxed(dm_rx_st, gi2c->base +
				       SE_DMA_RX_IRQ_CLR);
		/* Ensure all writes are done before returning from ISR. */
		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)
		gi2c->cmd_done = true;

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

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

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

		gi2c->cur_wr = 0;
		gi2c->cur_rd = 0;
		if (mode == SE_DMA) {
+8 −6
Original line number Diff line number Diff line
@@ -324,10 +324,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_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_s_irq_en = geni_read_reg(base, SE_GENI_S_IRQ_EN);
	geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN);
@@ -347,7 +343,9 @@ static int geni_se_select_fifo_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 common_geni_m_irq_en;

	geni_write_reg(0, base, SE_GSI_EVENT_EN);
	geni_write_reg(0xFFFFFFFF, base, SE_GENI_M_IRQ_CLEAR);
@@ -355,9 +353,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_RX_IRQ_CLR);
	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_DMA_MODE_EN;
	geni_write_reg(geni_dma_mode, base, SE_GENI_DMA_MODE_EN);