Loading drivers/i2c/busses/i2c-qcom-geni.c +111 −41 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/msm_gpi.h> #include <linux/ioctl.h> #include <linux/pinctrl/consumer.h> #include <linux/slab.h> #define SE_I2C_TX_TRANS_LEN (0x26C) #define SE_I2C_RX_TRANS_LEN (0x270) Loading Loading @@ -74,12 +75,19 @@ #define I2C_TIMEOUT_MIN_USEC 500000 #define MAX_SE 20 enum i2c_se_mode { UNINITIALIZED, FIFO_SE_DMA, GSI_ONLY, }; struct dbg_buf_ctxt { void *virt_buf; void *map_buf; }; struct geni_i2c_dev { struct device *dev; void __iomem *base; Loading Loading @@ -118,8 +126,13 @@ struct geni_i2c_dev { enum i2c_se_mode se_mode; bool cmd_done; bool is_shared; u32 dbg_num; struct dbg_buf_ctxt *dbg_buf_ptr; }; static struct geni_i2c_dev *gi2c_dev_dbg[MAX_SE]; static int arr_idx; struct geni_i2c_err_log { int err; const char *msg; Loading Loading @@ -209,12 +222,6 @@ static inline void qcom_geni_i2c_calc_timeout(struct geni_i2c_dev *gi2c) static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err) { if (gi2c->cur) GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "len:%d, slv-addr:0x%x, RD/WR:%d timeout:%u\n", gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags, gi2c->xfer_timeout); if (err == I2C_NACK || err == GENI_ABORT_DONE) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", gi2c_log[err].msg); Loading @@ -223,8 +230,6 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s\n", gi2c_log[err].msg); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s: se-mode:%d\n", __func__, gi2c->se_mode); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); err_ret: gi2c->err = gi2c_log[err].err; Loading @@ -241,7 +246,13 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev) u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN); struct i2c_msg *cur = gi2c->cur; if (!cur || (m_stat & M_CMD_FAILURE_EN) || if (!cur) { geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n"); goto irqret; } if ((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)) { Loading @@ -268,12 +279,6 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev) goto irqret; } if (dma) { dev_dbg(gi2c->dev, "i2c dma tx:0x%x, dma rx:0x%x\n", dm_tx_st, dm_rx_st); goto irqret; } if (((m_stat & M_RX_FIFO_WATERMARK_EN) || (m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) { u32 rxcnt = rx_st & RX_FIFO_WC_MSK; Loading Loading @@ -444,6 +449,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], goto geni_i2c_gsi_xfer_out; } } if (!gi2c->rx_c) { gi2c->rx_c = dma_request_slave_channel(gi2c->dev, "rx"); if (!gi2c->rx_c) { Loading Loading @@ -559,6 +565,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], sizeof(gi2c->go_t)); if (msgs[i].flags & I2C_M_RD) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msg[%d].len:%d R\n", i, gi2c->cur->len); sg_init_table(&gi2c->rx_sg, 1); ret = geni_se_iommu_map_buf(rx_dev, &gi2c->rx_ph, dma_buf, msgs[i].len, Loading @@ -571,6 +579,11 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], false); goto geni_i2c_gsi_xfer_out; } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&gi2c->rx_ph; } gi2c->rx_t.dword[0] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(gi2c->rx_ph); Loading Loading @@ -601,6 +614,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], rx_cookie = dmaengine_submit(gi2c->rx_desc); dma_async_issue_pending(gi2c->rx_c); } else { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msg[%d].len:%d W\n", i, gi2c->cur->len); ret = geni_se_iommu_map_buf(tx_dev, &gi2c->tx_ph, dma_buf, msgs[i].len, DMA_TO_DEVICE); Loading @@ -612,7 +627,13 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], false); goto geni_i2c_gsi_xfer_out; } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&gi2c->tx_ph; } gi2c->tx_t.dword[0] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(gi2c->tx_ph); gi2c->tx_t.dword[1] = Loading Loading @@ -656,9 +677,9 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], gi2c->xfer_timeout); if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI Txn timed out: %u len: %d slv:addr: 0x%x R/W: %d\n", gi2c->xfer_timeout, gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags); "I2C gsi xfer timeout:%u flags:%d addr:0x%x\n", gi2c->xfer_timeout, gi2c->cur->flags, gi2c->cur->addr); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); gi2c->err = -ETIMEDOUT; Loading Loading @@ -693,8 +714,15 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, int i, ret = 0, timeout = 0; gi2c->err = 0; gi2c->cur = &msgs[0]; reinit_completion(&gi2c->xfer); /* Client to respect system suspend */ if (!pm_runtime_enabled(gi2c->dev)) { GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "%s: System suspended\n", __func__); return -EACCES; } ret = pm_runtime_get_sync(gi2c->dev); if (ret < 0) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, Loading @@ -704,6 +732,18 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_set_suspended(gi2c->dev); return ret; } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "n:%d addr:0x%x\n", num, msgs[0].addr); gi2c->dbg_num = num; kfree(gi2c->dbg_buf_ptr); gi2c->dbg_buf_ptr = kcalloc(num, sizeof(struct dbg_buf_ctxt), GFP_KERNEL); if (!gi2c->dbg_buf_ptr) GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "Buf logging pointer not available\n"); if (gi2c->se_mode == GSI_ONLY) { ret = geni_i2c_gsi_xfer(adap, msgs, num); goto geni_i2c_txn_ret; Loading @@ -712,9 +752,6 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, gi2c->is_shared = false; } qcom_geni_i2c_conf(gi2c, 0); dev_dbg(gi2c->dev, "i2c xfer:num:%d, msgs:len:%d,flg:%d\n", num, msgs[0].len, msgs[0].flags); for (i = 0; i < num; i++) { int stretch = (i < (num - 1)); u32 m_param = 0; Loading Loading @@ -748,9 +785,8 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, } if (msgs[i].flags & I2C_M_RD) { dev_dbg(gi2c->dev, "READ,n:%d,i:%d len:%d, stretch:%d\n", num, i, msgs[i].len, stretch); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msgs[%d].len:%d R\n", i, msgs[i].len); geni_write_reg(msgs[i].len, gi2c->base, SE_I2C_RX_TRANS_LEN); m_cmd = I2C_READ; Loading @@ -765,12 +801,16 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, mode = FIFO_MODE; ret = geni_se_select_mode(gi2c->base, mode); } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&rx_dma; } } } else { dev_dbg(gi2c->dev, "WRITE:n:%d,i:%d len:%d, stretch:%d, m_param:0x%x\n", num, i, msgs[i].len, stretch, m_param); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msgs[%d].len:%d W\n", i, msgs[i].len); geni_write_reg(msgs[i].len, gi2c->base, SE_I2C_TX_TRANS_LEN); m_cmd = I2C_WRITE; Loading @@ -785,6 +825,11 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, mode = FIFO_MODE; ret = geni_se_select_mode(gi2c->base, mode); } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&tx_dma; } } if (mode == FIFO_MODE) /* Get FIFO IRQ */ Loading @@ -795,19 +840,23 @@ 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_SE_ERR(gi2c->ipcl, true, gi2c->dev, "I2C xfer timeout: %d\n", gi2c->xfer_timeout); geni_i2c_err(gi2c, GENI_TIMEOUT); } if (gi2c->err) { reinit_completion(&gi2c->xfer); gi2c->cur = NULL; geni_cancel_m_cmd(gi2c->base); timeout = wait_for_completion_timeout(&gi2c->xfer, HZ); if (!timeout) if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "Abort\n"); geni_abort_m_cmd(gi2c->base); } gi2c->cur_wr = 0; gi2c->cur_rd = 0; } if (mode == SE_DMA) { if (gi2c->err) { reinit_completion(&gi2c->xfer); Loading @@ -825,9 +874,11 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, msgs[i].len); i2c_put_dma_safe_msg_buf(dma_buf, &msgs[i], !gi2c->err); } ret = gi2c->err; if (gi2c->err) { dev_err(gi2c->dev, "i2c error :%d\n", gi2c->err); GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "i2c error :%d\n", gi2c->err); break; } } Loading @@ -837,9 +888,12 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_mark_last_busy(gi2c->dev); pm_runtime_put_autosuspend(gi2c->dev); gi2c->cur_wr = 0; gi2c->cur_rd = 0; gi2c->cur = NULL; gi2c->err = 0; dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c txn ret:%d\n", ret); return ret; } Loading @@ -865,6 +919,10 @@ static int geni_i2c_probe(struct platform_device *pdev) if (!gi2c) return -ENOMEM; if (arr_idx++ < MAX_SE) /* Debug purpose */ gi2c_dev_dbg[arr_idx] = gi2c; gi2c->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); Loading Loading @@ -901,14 +959,12 @@ static int geni_i2c_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret); return ret; } gi2c->i2c_rsc.m_ahb_clk = devm_clk_get(&pdev->dev, "m-ahb"); if (IS_ERR(gi2c->i2c_rsc.m_ahb_clk)) { ret = PTR_ERR(gi2c->i2c_rsc.m_ahb_clk); dev_err(&pdev->dev, "Err getting M AHB clk %d\n", ret); return ret; } gi2c->i2c_rsc.s_ahb_clk = devm_clk_get(&pdev->dev, "s-ahb"); if (IS_ERR(gi2c->i2c_rsc.s_ahb_clk)) { ret = PTR_ERR(gi2c->i2c_rsc.s_ahb_clk); Loading Loading @@ -987,6 +1043,7 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->irq, ret); return ret; } disable_irq(gi2c->irq); i2c_set_adapdata(&gi2c->adap, gi2c); gi2c->adap.dev.parent = gi2c->dev; Loading @@ -998,7 +1055,11 @@ static int geni_i2c_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(gi2c->dev, I2C_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(gi2c->dev); pm_runtime_enable(gi2c->dev); i2c_add_adapter(&gi2c->adap); ret = i2c_add_adapter(&gi2c->adap); if (ret) { dev_err(gi2c->dev, "Add adapter failed\n"); return ret; } dev_dbg(gi2c->dev, "I2C probed\n"); return 0; Loading @@ -1017,6 +1078,9 @@ static int geni_i2c_remove(struct platform_device *pdev) static int geni_i2c_resume_noirq(struct device *device) { struct geni_i2c_dev *gi2c = dev_get_drvdata(device); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1034,6 +1098,7 @@ static int geni_i2c_runtime_suspend(struct device *dev) } else { se_geni_resources_off(&gi2c->i2c_rsc); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1050,7 +1115,6 @@ static int geni_i2c_runtime_resume(struct device *dev) } ret = se_geni_resources_on(&gi2c->i2c_rsc); if (ret) return ret; Loading @@ -1070,23 +1134,27 @@ static int geni_i2c_runtime_resume(struct device *dev) gi2c->se_mode = GSI_ONLY; geni_se_select_mode(gi2c->base, GSI_DMA); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c in GSI ONLY mode\n"); "i2c GSI mode\n"); } else { int gi2c_tx_depth = get_tx_fifo_depth(gi2c->base); gi2c->se_mode = FIFO_SE_DMA; gi2c->tx_wm = gi2c_tx_depth - 1; geni_se_init(gi2c->base, gi2c->tx_wm, gi2c_tx_depth); se_config_packing(gi2c->base, 8, 4, true); qcom_geni_i2c_conf(gi2c, 0); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", gi2c_tx_depth); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c-%d: %s\n", gi2c->adap.nr, dev_name(gi2c->dev)); } if (gi2c->se_mode == FIFO_SE_DMA) enable_irq(gi2c->irq); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1103,6 +1171,8 @@ static int geni_i2c_suspend_noirq(struct device *device) return -EBUSY; } if (!pm_runtime_status_suspended(device)) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); geni_i2c_runtime_suspend(device); pm_runtime_disable(device); pm_runtime_set_suspended(device); Loading Loading
drivers/i2c/busses/i2c-qcom-geni.c +111 −41 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/msm_gpi.h> #include <linux/ioctl.h> #include <linux/pinctrl/consumer.h> #include <linux/slab.h> #define SE_I2C_TX_TRANS_LEN (0x26C) #define SE_I2C_RX_TRANS_LEN (0x270) Loading Loading @@ -74,12 +75,19 @@ #define I2C_TIMEOUT_MIN_USEC 500000 #define MAX_SE 20 enum i2c_se_mode { UNINITIALIZED, FIFO_SE_DMA, GSI_ONLY, }; struct dbg_buf_ctxt { void *virt_buf; void *map_buf; }; struct geni_i2c_dev { struct device *dev; void __iomem *base; Loading Loading @@ -118,8 +126,13 @@ struct geni_i2c_dev { enum i2c_se_mode se_mode; bool cmd_done; bool is_shared; u32 dbg_num; struct dbg_buf_ctxt *dbg_buf_ptr; }; static struct geni_i2c_dev *gi2c_dev_dbg[MAX_SE]; static int arr_idx; struct geni_i2c_err_log { int err; const char *msg; Loading Loading @@ -209,12 +222,6 @@ static inline void qcom_geni_i2c_calc_timeout(struct geni_i2c_dev *gi2c) static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err) { if (gi2c->cur) GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "len:%d, slv-addr:0x%x, RD/WR:%d timeout:%u\n", gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags, gi2c->xfer_timeout); if (err == I2C_NACK || err == GENI_ABORT_DONE) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", gi2c_log[err].msg); Loading @@ -223,8 +230,6 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s\n", gi2c_log[err].msg); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s: se-mode:%d\n", __func__, gi2c->se_mode); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); err_ret: gi2c->err = gi2c_log[err].err; Loading @@ -241,7 +246,13 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev) u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN); struct i2c_msg *cur = gi2c->cur; if (!cur || (m_stat & M_CMD_FAILURE_EN) || if (!cur) { geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n"); goto irqret; } if ((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)) { Loading @@ -268,12 +279,6 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev) goto irqret; } if (dma) { dev_dbg(gi2c->dev, "i2c dma tx:0x%x, dma rx:0x%x\n", dm_tx_st, dm_rx_st); goto irqret; } if (((m_stat & M_RX_FIFO_WATERMARK_EN) || (m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) { u32 rxcnt = rx_st & RX_FIFO_WC_MSK; Loading Loading @@ -444,6 +449,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], goto geni_i2c_gsi_xfer_out; } } if (!gi2c->rx_c) { gi2c->rx_c = dma_request_slave_channel(gi2c->dev, "rx"); if (!gi2c->rx_c) { Loading Loading @@ -559,6 +565,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], sizeof(gi2c->go_t)); if (msgs[i].flags & I2C_M_RD) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msg[%d].len:%d R\n", i, gi2c->cur->len); sg_init_table(&gi2c->rx_sg, 1); ret = geni_se_iommu_map_buf(rx_dev, &gi2c->rx_ph, dma_buf, msgs[i].len, Loading @@ -571,6 +579,11 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], false); goto geni_i2c_gsi_xfer_out; } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&gi2c->rx_ph; } gi2c->rx_t.dword[0] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(gi2c->rx_ph); Loading Loading @@ -601,6 +614,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], rx_cookie = dmaengine_submit(gi2c->rx_desc); dma_async_issue_pending(gi2c->rx_c); } else { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msg[%d].len:%d W\n", i, gi2c->cur->len); ret = geni_se_iommu_map_buf(tx_dev, &gi2c->tx_ph, dma_buf, msgs[i].len, DMA_TO_DEVICE); Loading @@ -612,7 +627,13 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], false); goto geni_i2c_gsi_xfer_out; } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&gi2c->tx_ph; } gi2c->tx_t.dword[0] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(gi2c->tx_ph); gi2c->tx_t.dword[1] = Loading Loading @@ -656,9 +677,9 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], gi2c->xfer_timeout); if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI Txn timed out: %u len: %d slv:addr: 0x%x R/W: %d\n", gi2c->xfer_timeout, gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags); "I2C gsi xfer timeout:%u flags:%d addr:0x%x\n", gi2c->xfer_timeout, gi2c->cur->flags, gi2c->cur->addr); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); gi2c->err = -ETIMEDOUT; Loading Loading @@ -693,8 +714,15 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, int i, ret = 0, timeout = 0; gi2c->err = 0; gi2c->cur = &msgs[0]; reinit_completion(&gi2c->xfer); /* Client to respect system suspend */ if (!pm_runtime_enabled(gi2c->dev)) { GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "%s: System suspended\n", __func__); return -EACCES; } ret = pm_runtime_get_sync(gi2c->dev); if (ret < 0) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, Loading @@ -704,6 +732,18 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_set_suspended(gi2c->dev); return ret; } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "n:%d addr:0x%x\n", num, msgs[0].addr); gi2c->dbg_num = num; kfree(gi2c->dbg_buf_ptr); gi2c->dbg_buf_ptr = kcalloc(num, sizeof(struct dbg_buf_ctxt), GFP_KERNEL); if (!gi2c->dbg_buf_ptr) GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "Buf logging pointer not available\n"); if (gi2c->se_mode == GSI_ONLY) { ret = geni_i2c_gsi_xfer(adap, msgs, num); goto geni_i2c_txn_ret; Loading @@ -712,9 +752,6 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, gi2c->is_shared = false; } qcom_geni_i2c_conf(gi2c, 0); dev_dbg(gi2c->dev, "i2c xfer:num:%d, msgs:len:%d,flg:%d\n", num, msgs[0].len, msgs[0].flags); for (i = 0; i < num; i++) { int stretch = (i < (num - 1)); u32 m_param = 0; Loading Loading @@ -748,9 +785,8 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, } if (msgs[i].flags & I2C_M_RD) { dev_dbg(gi2c->dev, "READ,n:%d,i:%d len:%d, stretch:%d\n", num, i, msgs[i].len, stretch); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msgs[%d].len:%d R\n", i, msgs[i].len); geni_write_reg(msgs[i].len, gi2c->base, SE_I2C_RX_TRANS_LEN); m_cmd = I2C_READ; Loading @@ -765,12 +801,16 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, mode = FIFO_MODE; ret = geni_se_select_mode(gi2c->base, mode); } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&rx_dma; } } } else { dev_dbg(gi2c->dev, "WRITE:n:%d,i:%d len:%d, stretch:%d, m_param:0x%x\n", num, i, msgs[i].len, stretch, m_param); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "msgs[%d].len:%d W\n", i, msgs[i].len); geni_write_reg(msgs[i].len, gi2c->base, SE_I2C_TX_TRANS_LEN); m_cmd = I2C_WRITE; Loading @@ -785,6 +825,11 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, mode = FIFO_MODE; ret = geni_se_select_mode(gi2c->base, mode); } else if (gi2c->dbg_buf_ptr) { gi2c->dbg_buf_ptr[i].virt_buf = (void *)dma_buf; gi2c->dbg_buf_ptr[i].map_buf = (void *)&tx_dma; } } if (mode == FIFO_MODE) /* Get FIFO IRQ */ Loading @@ -795,19 +840,23 @@ 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_SE_ERR(gi2c->ipcl, true, gi2c->dev, "I2C xfer timeout: %d\n", gi2c->xfer_timeout); geni_i2c_err(gi2c, GENI_TIMEOUT); } if (gi2c->err) { reinit_completion(&gi2c->xfer); gi2c->cur = NULL; geni_cancel_m_cmd(gi2c->base); timeout = wait_for_completion_timeout(&gi2c->xfer, HZ); if (!timeout) if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "Abort\n"); geni_abort_m_cmd(gi2c->base); } gi2c->cur_wr = 0; gi2c->cur_rd = 0; } if (mode == SE_DMA) { if (gi2c->err) { reinit_completion(&gi2c->xfer); Loading @@ -825,9 +874,11 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, msgs[i].len); i2c_put_dma_safe_msg_buf(dma_buf, &msgs[i], !gi2c->err); } ret = gi2c->err; if (gi2c->err) { dev_err(gi2c->dev, "i2c error :%d\n", gi2c->err); GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "i2c error :%d\n", gi2c->err); break; } } Loading @@ -837,9 +888,12 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_mark_last_busy(gi2c->dev); pm_runtime_put_autosuspend(gi2c->dev); gi2c->cur_wr = 0; gi2c->cur_rd = 0; gi2c->cur = NULL; gi2c->err = 0; dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c txn ret:%d\n", ret); return ret; } Loading @@ -865,6 +919,10 @@ static int geni_i2c_probe(struct platform_device *pdev) if (!gi2c) return -ENOMEM; if (arr_idx++ < MAX_SE) /* Debug purpose */ gi2c_dev_dbg[arr_idx] = gi2c; gi2c->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); Loading Loading @@ -901,14 +959,12 @@ static int geni_i2c_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret); return ret; } gi2c->i2c_rsc.m_ahb_clk = devm_clk_get(&pdev->dev, "m-ahb"); if (IS_ERR(gi2c->i2c_rsc.m_ahb_clk)) { ret = PTR_ERR(gi2c->i2c_rsc.m_ahb_clk); dev_err(&pdev->dev, "Err getting M AHB clk %d\n", ret); return ret; } gi2c->i2c_rsc.s_ahb_clk = devm_clk_get(&pdev->dev, "s-ahb"); if (IS_ERR(gi2c->i2c_rsc.s_ahb_clk)) { ret = PTR_ERR(gi2c->i2c_rsc.s_ahb_clk); Loading Loading @@ -987,6 +1043,7 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->irq, ret); return ret; } disable_irq(gi2c->irq); i2c_set_adapdata(&gi2c->adap, gi2c); gi2c->adap.dev.parent = gi2c->dev; Loading @@ -998,7 +1055,11 @@ static int geni_i2c_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(gi2c->dev, I2C_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(gi2c->dev); pm_runtime_enable(gi2c->dev); i2c_add_adapter(&gi2c->adap); ret = i2c_add_adapter(&gi2c->adap); if (ret) { dev_err(gi2c->dev, "Add adapter failed\n"); return ret; } dev_dbg(gi2c->dev, "I2C probed\n"); return 0; Loading @@ -1017,6 +1078,9 @@ static int geni_i2c_remove(struct platform_device *pdev) static int geni_i2c_resume_noirq(struct device *device) { struct geni_i2c_dev *gi2c = dev_get_drvdata(device); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1034,6 +1098,7 @@ static int geni_i2c_runtime_suspend(struct device *dev) } else { se_geni_resources_off(&gi2c->i2c_rsc); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1050,7 +1115,6 @@ static int geni_i2c_runtime_resume(struct device *dev) } ret = se_geni_resources_on(&gi2c->i2c_rsc); if (ret) return ret; Loading @@ -1070,23 +1134,27 @@ static int geni_i2c_runtime_resume(struct device *dev) gi2c->se_mode = GSI_ONLY; geni_se_select_mode(gi2c->base, GSI_DMA); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c in GSI ONLY mode\n"); "i2c GSI mode\n"); } else { int gi2c_tx_depth = get_tx_fifo_depth(gi2c->base); gi2c->se_mode = FIFO_SE_DMA; gi2c->tx_wm = gi2c_tx_depth - 1; geni_se_init(gi2c->base, gi2c->tx_wm, gi2c_tx_depth); se_config_packing(gi2c->base, 8, 4, true); qcom_geni_i2c_conf(gi2c, 0); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", gi2c_tx_depth); } GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c-%d: %s\n", gi2c->adap.nr, dev_name(gi2c->dev)); } if (gi2c->se_mode == FIFO_SE_DMA) enable_irq(gi2c->irq); GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); return 0; } Loading @@ -1103,6 +1171,8 @@ static int geni_i2c_suspend_noirq(struct device *device) return -EBUSY; } if (!pm_runtime_status_suspended(device)) { GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n", __func__); geni_i2c_runtime_suspend(device); pm_runtime_disable(device); pm_runtime_set_suspended(device); Loading