From 2578117ac197bd8585824bb788874e389bf5b3d7 Mon Sep 17 00:00:00 2001 From: Anil Veshala Veshala Date: Mon, 7 Mar 2022 08:20:51 -0800 Subject: [PATCH] i2c:i2c-msm-geni: Updating last mark busy failure case We are seeing xfer timeout due to IO lines not in proper state, if IO lines recovered we do cancel command, if IO lines not recovered we are returning without doing cancel operation and not updating last mark busy, due to this we are not receiving SUSPEND call. After sometime unexpected event is coming from GSI, due to this we are seeing the crash. To resolve this we have updated last mark busy for pending_cancel failure case as well. If we update last mark busy, runtime_suspend will invoke here we are doing gpi pause operation, unexpected event won't expected if we do gpi pause. Also,added RTL based SE flag, doing pending cancel only for RTL based SE's. Change-Id: Ia1af93fc9dadf4a11fa2e3f614878de550ab4c0e Signed-off-by: Anil Veshala Veshala --- drivers/i2c/busses/i2c-msm-geni.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-msm-geni.c b/drivers/i2c/busses/i2c-msm-geni.c index 9c508aa56efe..47015e1699d8 100644 --- a/drivers/i2c/busses/i2c-msm-geni.c +++ b/drivers/i2c/busses/i2c-msm-geni.c @@ -135,6 +135,7 @@ struct geni_i2c_dev { bool gpi_reset; bool disable_dma_mode; bool prev_cancel_pending; //Halt cancel till IOS in good state + bool is_i2c_rtl_based; /* doing pending cancel only for rtl based SE's */ }; static struct geni_i2c_dev *gi2c_dev_dbg[MAX_SE]; @@ -247,6 +248,10 @@ static int do_pending_cancel(struct geni_i2c_dev *gi2c) int timeout = 0; u32 geni_ios = 0; + /* doing pending cancel only rtl based SE's */ + if (!gi2c->is_i2c_rtl_based) + return 0; + geni_ios = geni_read_reg_nolog(gi2c->base, SE_GENI_IOS); if ((geni_ios & 0x3) != 0x3) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, @@ -1048,8 +1053,11 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, // WAR : Complete previous pending cancel cmd if (gi2c->prev_cancel_pending) { ret = do_pending_cancel(gi2c); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(gi2c->dev); + pm_runtime_put_autosuspend(gi2c->dev); return ret; //Don't perform xfer is cancel failed + } } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, @@ -1312,6 +1320,11 @@ static int geni_i2c_probe(struct platform_device *pdev) if (of_property_read_bool(pdev->dev.of_node, "qcom,leica-used-i2c")) gi2c->i2c_rsc.skip_bw_vote = true; + if (of_property_read_bool(pdev->dev.of_node, "qcom,rtl_se")) { + gi2c->is_i2c_rtl_based = true; + dev_info(&pdev->dev, "%s: RTL based SE\n", __func__); + } + gi2c->i2c_rsc.wrapper_dev = &wrapper_pdev->dev; gi2c->i2c_rsc.ctrl_dev = gi2c->dev;