Loading Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ Required properties: Optional property: - qcom,clk-freq-out : Desired I2C bus clock frequency in Hz. When missing default to 400000Hz. - qcom,disable-autosuspend : Disable autosuspend for I2C controller and I2C clients should call pm_runtime_get_sync()/put_sync() for the I2C controller. Child nodes should conform to i2c bus binding. Loading drivers/i2c/busses/i2c-qcom-geni.c +30 −4 Original line number Diff line number Diff line Loading @@ -121,6 +121,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 autosuspend_disable; }; struct geni_i2c_err_log { Loading Loading @@ -641,6 +642,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, { struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); int i, ret = 0, timeout = 0; int ref = 0; gi2c->err = 0; gi2c->cur = &msgs[0]; Loading @@ -654,6 +656,12 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_set_suspended(gi2c->dev); return ret; } ref = atomic_read(&gi2c->dev->power.usage_count); if (ref <= 0) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "resume usage count mismatch:%d\n", ref); } if (gi2c->se_mode == GSI_ONLY) { ret = geni_i2c_gsi_xfer(adap, msgs, num); goto geni_i2c_txn_ret; Loading Loading @@ -759,8 +767,17 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, if (ret == 0) ret = num; if (gi2c->autosuspend_disable) { pm_runtime_put_sync(gi2c->dev); ref = atomic_read(&gi2c->dev->power.usage_count); if (ref < 0) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "suspend usage count mismatch:%d\n", ref); } else { pm_runtime_mark_last_busy(gi2c->dev); pm_runtime_put_autosuspend(gi2c->dev); } gi2c->cur = NULL; gi2c->err = 0; dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret); Loading Loading @@ -874,6 +891,9 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->i2c_rsc.clk_freq_out = KHz(400); } gi2c->autosuspend_disable = of_property_read_bool(pdev->dev.of_node, "qcom,disable-autosuspend"); gi2c->irq = platform_get_irq(pdev, 0); if (gi2c->irq < 0) { dev_err(gi2c->dev, "IRQ error for i2c-geni\n"); Loading Loading @@ -905,8 +925,11 @@ static int geni_i2c_probe(struct platform_device *pdev) strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); pm_runtime_set_suspended(gi2c->dev); pm_runtime_set_autosuspend_delay(gi2c->dev, I2C_AUTO_SUSPEND_DELAY); if (!gi2c->autosuspend_disable) { 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); Loading Loading @@ -994,6 +1017,9 @@ static int geni_i2c_runtime_resume(struct device *dev) "i2c fifo/se-dma mode. fifo depth:%d\n", gi2c_tx_depth); } if (gi2c->autosuspend_disable) GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c in autosuspend disable mode\n"); } if (gi2c->se_mode == FIFO_SE_DMA) enable_irq(gi2c->irq); Loading Loading
Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ Required properties: Optional property: - qcom,clk-freq-out : Desired I2C bus clock frequency in Hz. When missing default to 400000Hz. - qcom,disable-autosuspend : Disable autosuspend for I2C controller and I2C clients should call pm_runtime_get_sync()/put_sync() for the I2C controller. Child nodes should conform to i2c bus binding. Loading
drivers/i2c/busses/i2c-qcom-geni.c +30 −4 Original line number Diff line number Diff line Loading @@ -121,6 +121,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 autosuspend_disable; }; struct geni_i2c_err_log { Loading Loading @@ -641,6 +642,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, { struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); int i, ret = 0, timeout = 0; int ref = 0; gi2c->err = 0; gi2c->cur = &msgs[0]; Loading @@ -654,6 +656,12 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_set_suspended(gi2c->dev); return ret; } ref = atomic_read(&gi2c->dev->power.usage_count); if (ref <= 0) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "resume usage count mismatch:%d\n", ref); } if (gi2c->se_mode == GSI_ONLY) { ret = geni_i2c_gsi_xfer(adap, msgs, num); goto geni_i2c_txn_ret; Loading Loading @@ -759,8 +767,17 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, if (ret == 0) ret = num; if (gi2c->autosuspend_disable) { pm_runtime_put_sync(gi2c->dev); ref = atomic_read(&gi2c->dev->power.usage_count); if (ref < 0) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "suspend usage count mismatch:%d\n", ref); } else { pm_runtime_mark_last_busy(gi2c->dev); pm_runtime_put_autosuspend(gi2c->dev); } gi2c->cur = NULL; gi2c->err = 0; dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret); Loading Loading @@ -874,6 +891,9 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->i2c_rsc.clk_freq_out = KHz(400); } gi2c->autosuspend_disable = of_property_read_bool(pdev->dev.of_node, "qcom,disable-autosuspend"); gi2c->irq = platform_get_irq(pdev, 0); if (gi2c->irq < 0) { dev_err(gi2c->dev, "IRQ error for i2c-geni\n"); Loading Loading @@ -905,8 +925,11 @@ static int geni_i2c_probe(struct platform_device *pdev) strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); pm_runtime_set_suspended(gi2c->dev); pm_runtime_set_autosuspend_delay(gi2c->dev, I2C_AUTO_SUSPEND_DELAY); if (!gi2c->autosuspend_disable) { 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); Loading Loading @@ -994,6 +1017,9 @@ static int geni_i2c_runtime_resume(struct device *dev) "i2c fifo/se-dma mode. fifo depth:%d\n", gi2c_tx_depth); } if (gi2c->autosuspend_disable) GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "i2c in autosuspend disable mode\n"); } if (gi2c->se_mode == FIFO_SE_DMA) enable_irq(gi2c->irq); Loading