i2c-msm-v2: Print error logs in process context
Move error logs from interrupt context to process context to avoid blocking other interrupts and reduce latencies in ISR handling. Also keep error check for BAM rx completion. Change-Id: Ibf355561495b35702118eaf9a0f38c0fdc9310b3 Signed-off-by: Shrey Vijay <shreyv@codeaurora.org>
This commit is contained in:
parent
3d82d66409
commit
e7b5532deb
2 changed files with 30 additions and 23 deletions
|
@ -1310,7 +1310,8 @@ static int i2c_msm_dma_xfer_process(struct i2c_msm_ctrl *ctrl)
|
|||
|
||||
ret = i2c_msm_xfer_wait_for_completion(ctrl, &ctrl->xfer.complete);
|
||||
if (!ret && ctrl->xfer.rx_cnt)
|
||||
i2c_msm_xfer_wait_for_completion(ctrl, &ctrl->xfer.rx_complete);
|
||||
ret = i2c_msm_xfer_wait_for_completion(ctrl,
|
||||
&ctrl->xfer.rx_complete);
|
||||
|
||||
dma_xfer_end:
|
||||
/* free scatter-gather lists */
|
||||
|
@ -1716,9 +1717,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
void __iomem *base = ctrl->rsrcs.base;
|
||||
struct i2c_msm_xfer *xfer = &ctrl->xfer;
|
||||
struct i2c_msm_xfer_mode_blk *blk = &ctrl->xfer.blk;
|
||||
u32 i2c_status = 0;
|
||||
u32 err_flags = 0;
|
||||
u32 qup_op = 0;
|
||||
u32 clr_flds = 0;
|
||||
bool log_event = false;
|
||||
bool signal_complete = false;
|
||||
|
@ -1731,24 +1730,24 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
i2c_status = readl_relaxed(base + QUP_I2C_STATUS);
|
||||
err_flags = readl_relaxed(base + QUP_ERROR_FLAGS);
|
||||
qup_op = readl_relaxed(base + QUP_OPERATIONAL);
|
||||
ctrl->i2c_sts_reg = readl_relaxed(base + QUP_I2C_STATUS);
|
||||
err_flags = readl_relaxed(base + QUP_ERROR_FLAGS);
|
||||
ctrl->qup_op_reg = readl_relaxed(base + QUP_OPERATIONAL);
|
||||
|
||||
if (i2c_status & QUP_MSTR_STTS_ERR_MASK) {
|
||||
if (ctrl->i2c_sts_reg & QUP_MSTR_STTS_ERR_MASK) {
|
||||
signal_complete = true;
|
||||
log_event = true;
|
||||
/*
|
||||
* If there is more than 1 error here, last one sticks.
|
||||
* The order of the error set here matters.
|
||||
*/
|
||||
if (i2c_status & QUP_ARB_LOST)
|
||||
if (ctrl->i2c_sts_reg & QUP_ARB_LOST)
|
||||
ctrl->xfer.err = I2C_MSM_ERR_ARB_LOST;
|
||||
|
||||
if (i2c_status & QUP_BUS_ERROR)
|
||||
if (ctrl->i2c_sts_reg & QUP_BUS_ERROR)
|
||||
ctrl->xfer.err = I2C_MSM_ERR_BUS_ERR;
|
||||
|
||||
if (i2c_status & QUP_PACKET_NACKED)
|
||||
if (ctrl->i2c_sts_reg & QUP_PACKET_NACKED)
|
||||
ctrl->xfer.err = I2C_MSM_ERR_NACK;
|
||||
}
|
||||
|
||||
|
@ -1761,7 +1760,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
i2c_msm_dbg_qup_reg_dump(ctrl);
|
||||
|
||||
/* clear interrupts fields */
|
||||
clr_flds = i2c_status & QUP_MSTR_STTS_ERR_MASK;
|
||||
clr_flds = ctrl->i2c_sts_reg & QUP_MSTR_STTS_ERR_MASK;
|
||||
if (clr_flds) {
|
||||
writel_relaxed(clr_flds, base + QUP_I2C_STATUS);
|
||||
need_wmb = true;
|
||||
|
@ -1773,7 +1772,9 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
need_wmb = true;
|
||||
}
|
||||
|
||||
clr_flds = qup_op & (QUP_OUTPUT_SERVICE_FLAG | QUP_INPUT_SERVICE_FLAG);
|
||||
clr_flds = ctrl->qup_op_reg &
|
||||
(QUP_OUTPUT_SERVICE_FLAG |
|
||||
QUP_INPUT_SERVICE_FLAG);
|
||||
if (clr_flds) {
|
||||
writel_relaxed(clr_flds, base + QUP_OPERATIONAL);
|
||||
need_wmb = true;
|
||||
|
@ -1814,25 +1815,25 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
/* handle data completion */
|
||||
if (xfer->mode_id == I2C_MSM_XFER_MODE_BLOCK) {
|
||||
/* block ready for writing */
|
||||
if (qup_op & QUP_OUTPUT_SERVICE_FLAG) {
|
||||
if (ctrl->qup_op_reg & QUP_OUTPUT_SERVICE_FLAG) {
|
||||
log_event = true;
|
||||
if (qup_op & QUP_OUT_BLOCK_WRITE_REQ)
|
||||
if (ctrl->qup_op_reg & QUP_OUT_BLOCK_WRITE_REQ)
|
||||
complete(&blk->wait_tx_blk);
|
||||
|
||||
if ((qup_op & blk->complete_mask)
|
||||
if ((ctrl->qup_op_reg & blk->complete_mask)
|
||||
== blk->complete_mask) {
|
||||
log_event = true;
|
||||
signal_complete = true;
|
||||
}
|
||||
}
|
||||
/* block ready for reading */
|
||||
if (qup_op & QUP_INPUT_SERVICE_FLAG) {
|
||||
if (ctrl->qup_op_reg & QUP_INPUT_SERVICE_FLAG) {
|
||||
log_event = true;
|
||||
complete(&blk->wait_rx_blk);
|
||||
}
|
||||
} else {
|
||||
/* for FIFO/DMA Mode*/
|
||||
if (qup_op & QUP_MAX_INPUT_DONE_FLAG) {
|
||||
if (ctrl->qup_op_reg & QUP_MAX_INPUT_DONE_FLAG) {
|
||||
log_event = true;
|
||||
/*
|
||||
* If last transaction is an input then the entire
|
||||
|
@ -1850,7 +1851,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
* here QUP_OUTPUT_SERVICE_FLAG and assumes that
|
||||
* QUP_MAX_OUTPUT_DONE_FLAG.
|
||||
*/
|
||||
if (qup_op & (QUP_OUTPUT_SERVICE_FLAG |
|
||||
if (ctrl->qup_op_reg & (QUP_OUTPUT_SERVICE_FLAG |
|
||||
QUP_MAX_OUTPUT_DONE_FLAG)) {
|
||||
log_event = true;
|
||||
/*
|
||||
|
@ -1863,13 +1864,11 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid)
|
|||
}
|
||||
|
||||
isr_end:
|
||||
if (ctrl->xfer.err || (ctrl->dbgfs.dbg_lvl >= MSM_DBG))
|
||||
i2c_msm_dbg_dump_diag(ctrl, true, i2c_status, qup_op);
|
||||
|
||||
if (log_event || (ctrl->dbgfs.dbg_lvl >= MSM_DBG))
|
||||
i2c_msm_prof_evnt_add(ctrl, MSM_PROF,
|
||||
I2C_MSM_IRQ_END,
|
||||
i2c_status, qup_op, err_flags);
|
||||
ctrl->i2c_sts_reg, ctrl->qup_op_reg,
|
||||
err_flags);
|
||||
|
||||
if (signal_complete)
|
||||
complete(&ctrl->xfer.complete);
|
||||
|
@ -2078,8 +2077,12 @@ static int i2c_msm_xfer_wait_for_completion(struct i2c_msm_ctrl *ctrl,
|
|||
xfer->timeout, time_left, 0);
|
||||
} else {
|
||||
/* return an error if one detected by ISR */
|
||||
if (xfer->err)
|
||||
if (ctrl->xfer.err ||
|
||||
(ctrl->dbgfs.dbg_lvl >= MSM_DBG)) {
|
||||
i2c_msm_dbg_dump_diag(ctrl, true,
|
||||
ctrl->i2c_sts_reg, ctrl->qup_op_reg);
|
||||
ret = -(xfer->err);
|
||||
}
|
||||
i2c_msm_prof_evnt_add(ctrl, MSM_DBG, I2C_MSM_COMPLT_OK,
|
||||
xfer->timeout, time_left, 0);
|
||||
}
|
||||
|
|
|
@ -581,6 +581,8 @@ struct i2c_msm_xfer {
|
|||
* @rsrcs resources from platform data including clocks, gpios, irqs, and
|
||||
* memory regions.
|
||||
* @mstr_clk_ctl cached value for programming to mstr_clk_ctl register
|
||||
* @i2c_sts_reg status of QUP_I2C_MASTER_STATUS register.
|
||||
* @qup_op_reg status of QUP_OPERATIONAL register.
|
||||
*/
|
||||
struct i2c_msm_ctrl {
|
||||
struct device *dev;
|
||||
|
@ -589,6 +591,8 @@ struct i2c_msm_ctrl {
|
|||
struct i2c_msm_dbgfs dbgfs;
|
||||
struct i2c_msm_resources rsrcs;
|
||||
u32 mstr_clk_ctl;
|
||||
u32 i2c_sts_reg;
|
||||
u32 qup_op_reg;
|
||||
enum i2c_msm_power_state pwr_state;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue