Loading drivers/i2c/busses/i2c-qcom-geni.c +43 −13 Original line number Diff line number Diff line Loading @@ -74,6 +74,8 @@ #define I2C_ARB_LOST GP_IRQ4 #define DM_I2C_RX_ERR ((GP_IRQ1 | GP_IRQ3 | GP_IRQ4) >> 4) #define I2C_AUTO_SUSPEND_DELAY 250 enum i2c_se_mode { UNINITIALIZED, FIFO_SE_DMA, Loading Loading @@ -385,12 +387,22 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); int i, ret = 0, timeout = 0; ret = pinctrl_select_state(gi2c->i2c_rsc.geni_pinctrl, gi2c->i2c_rsc.geni_gpio_active); if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s: Error %d pinctrl_select_state active\n", __func__, ret); return ret; } if (!gi2c->tx_c) { gi2c->tx_c = dma_request_slave_channel(gi2c->dev, "tx"); if (!gi2c->tx_c) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "tx dma req slv chan ret :%d\n", ret); return -EIO; ret = -EIO; goto geni_i2c_gsi_xfer_out; } gi2c->tx_ev.init.callback = gi2c_ev_cb; gi2c->tx_ev.init.cb_param = gi2c; Loading @@ -400,7 +412,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "tx dma slave config ret :%d\n", ret); return ret; goto geni_i2c_gsi_xfer_out; } } if (!gi2c->rx_c) { Loading @@ -408,7 +420,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (!gi2c->rx_c) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "rx dma req slv chan ret :%d\n", ret); return -EIO; ret = -EIO; goto geni_i2c_gsi_xfer_out; } gi2c->rx_ev.init.cb_param = gi2c; gi2c->rx_ev.init.callback = gi2c_ev_cb; Loading @@ -418,7 +431,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "rx dma slave config ret :%d\n", ret); return ret; goto geni_i2c_gsi_xfer_out; } } Loading Loading @@ -502,7 +515,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "prep_slave_sg for rx failed\n"); gi2c->err = -ENOMEM; return gi2c->err; goto geni_i2c_gsi_xfer_out; } gi2c->rx_desc->callback = gi2c_gsi_rx_cb; gi2c->rx_desc->callback_param = &gi2c->rx_cb; Loading Loading @@ -534,7 +547,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "prep_slave_sg for tx failed\n"); gi2c->err = -ENOMEM; return gi2c->err; goto geni_i2c_gsi_xfer_out; } gi2c->tx_desc->callback = gi2c_gsi_tx_cb; gi2c->tx_desc->callback_param = &gi2c->tx_cb; Loading @@ -559,10 +572,15 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (gi2c->err) { dmaengine_terminate_all(gi2c->tx_c); gi2c->cfg_sent = 0; return gi2c->err; goto geni_i2c_gsi_xfer_out; } } return gi2c->err; geni_i2c_gsi_xfer_out: if (!ret && gi2c->err) ret = gi2c->err; pinctrl_select_state(gi2c->i2c_rsc.geni_pinctrl, gi2c->i2c_rsc.geni_gpio_sleep); return ret; } static int geni_i2c_xfer(struct i2c_adapter *adap, Loading Loading @@ -686,7 +704,9 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, geni_i2c_txn_ret: if (ret == 0) ret = num; pm_runtime_put_sync(gi2c->dev); 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 @@ -830,6 +850,8 @@ 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); pm_runtime_use_autosuspend(gi2c->dev); pm_runtime_enable(gi2c->dev); i2c_add_adapter(&gi2c->adap); Loading Loading @@ -858,10 +880,13 @@ static int geni_i2c_runtime_suspend(struct device *dev) { struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); if (gi2c->se_mode == FIFO_SE_DMA) if (gi2c->se_mode == FIFO_SE_DMA) { disable_irq(gi2c->irq); se_geni_resources_off(&gi2c->i2c_rsc); } else { /* GPIO is set to sleep state already. So just clocks off */ se_geni_clks_off(&gi2c->i2c_rsc); } return 0; } Loading @@ -876,7 +901,12 @@ static int geni_i2c_runtime_resume(struct device *dev) snprintf(ipc_name, I2C_NAME_SIZE, "i2c-%d", gi2c->adap.nr); gi2c->ipcl = ipc_log_context_create(2, ipc_name, 0); } if (gi2c->se_mode != GSI_ONLY) ret = se_geni_resources_on(&gi2c->i2c_rsc); else ret = se_geni_clks_on(&gi2c->i2c_rsc); if (ret) return ret; Loading drivers/platform/msm/qcom-geni-se.c +77 −36 Original line number Diff line number Diff line Loading @@ -575,13 +575,6 @@ void se_config_packing(void __iomem *base, int bpw, } EXPORT_SYMBOL(se_config_packing); static void se_geni_clks_off(struct se_geni_rsc *rsc) { clk_disable_unprepare(rsc->se_clk); clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); } static bool geni_se_check_bus_bw(struct geni_se_device *geni_se_dev) { int i; Loading Loading @@ -641,13 +634,13 @@ static int geni_se_rmv_ab_ib(struct geni_se_device *geni_se_dev, } /** * se_geni_resources_off() - Turn off resources associated with the serial * se_geni_clks_off() - Turn off clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_off(struct se_geni_rsc *rsc) int se_geni_clks_off(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; Loading @@ -659,42 +652,50 @@ int se_geni_resources_off(struct se_geni_rsc *rsc) if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw)) return -ENODEV; ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_sleep); if (ret) { GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); return ret; } se_geni_clks_off(rsc); clk_disable_unprepare(rsc->se_clk); clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); ret = geni_se_rmv_ab_ib(geni_se_dev, rsc); if (ret) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d during bus_bw_update\n", __func__, ret); return ret; } EXPORT_SYMBOL(se_geni_resources_off); EXPORT_SYMBOL(se_geni_clks_off); static int se_geni_clks_on(struct se_geni_rsc *rsc) /** * se_geni_resources_off() - Turn off resources associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_off(struct se_geni_rsc *rsc) { int ret; int ret = 0; struct geni_se_device *geni_se_dev; ret = clk_prepare_enable(rsc->m_ahb_clk); if (ret) return ret; if (unlikely(!rsc || !rsc->wrapper_dev)) return -EINVAL; ret = clk_prepare_enable(rsc->s_ahb_clk); if (ret) { clk_disable_unprepare(rsc->m_ahb_clk); return ret; } geni_se_dev = dev_get_drvdata(rsc->wrapper_dev); if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw)) return -ENODEV; ret = clk_prepare_enable(rsc->se_clk); ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_sleep); if (ret) { clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); return ret; } ret = se_geni_clks_off(rsc); if (ret) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d turning off clocks\n", __func__, ret); return ret; } EXPORT_SYMBOL(se_geni_resources_off); static int geni_se_add_ab_ib(struct geni_se_device *geni_se_dev, struct se_geni_rsc *rsc) Loading Loading @@ -733,13 +734,13 @@ static int geni_se_add_ab_ib(struct geni_se_device *geni_se_dev, } /** * se_geni_resources_on() - Turn on resources associated with the serial * se_geni_clks_on() - Turn on clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_on(struct se_geni_rsc *rsc) int se_geni_clks_on(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; Loading @@ -758,11 +759,52 @@ int se_geni_resources_on(struct se_geni_rsc *rsc) return ret; } ret = clk_prepare_enable(rsc->m_ahb_clk); if (ret) goto clks_on_err1; ret = clk_prepare_enable(rsc->s_ahb_clk); if (ret) goto clks_on_err2; ret = clk_prepare_enable(rsc->se_clk); if (ret) goto clks_on_err3; return 0; clks_on_err3: clk_disable_unprepare(rsc->s_ahb_clk); clks_on_err2: clk_disable_unprepare(rsc->m_ahb_clk); clks_on_err1: geni_se_rmv_ab_ib(geni_se_dev, rsc); return ret; } EXPORT_SYMBOL(se_geni_clks_on); /** * se_geni_resources_on() - Turn on resources associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_on(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; if (unlikely(!rsc || !rsc->wrapper_dev)) return -EINVAL; geni_se_dev = dev_get_drvdata(rsc->wrapper_dev); if (unlikely(!geni_se_dev)) return -EPROBE_DEFER; ret = se_geni_clks_on(rsc); if (ret) { GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d during clks_on\n", __func__, ret); geni_se_rmv_ab_ib(geni_se_dev, rsc); return ret; } Loading @@ -771,7 +813,6 @@ int se_geni_resources_on(struct se_geni_rsc *rsc) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); se_geni_clks_off(rsc); geni_se_rmv_ab_ib(geni_se_dev, rsc); } return ret; } Loading include/linux/qcom-geni-se.h +28 −0 Original line number Diff line number Diff line Loading @@ -546,6 +546,24 @@ void se_get_packing_config(int bpw, int pack_words, bool msb_to_lsb, void se_config_packing(void __iomem *base, int bpw, int pack_words, bool msb_to_lsb); /** * se_geni_clks_off() - Turn off clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_clks_off(struct se_geni_rsc *rsc); /** * se_geni_clks_on() - Turn on clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_clks_on(struct se_geni_rsc *rsc); /** * se_geni_resources_off() - Turn off resources associated with the serial * engine Loading Loading @@ -842,6 +860,16 @@ static inline void se_config_packing(void __iomem *base, int bpw, { } static inline int se_geni_clks_on(struct se_geni_rsc *rsc) { return -ENXIO; } static inline int se_geni_clks_off(struct se_geni_rsc *rsc) { return -ENXIO; } static inline int se_geni_resources_on(struct se_geni_rsc *rsc) { return -ENXIO; Loading Loading
drivers/i2c/busses/i2c-qcom-geni.c +43 −13 Original line number Diff line number Diff line Loading @@ -74,6 +74,8 @@ #define I2C_ARB_LOST GP_IRQ4 #define DM_I2C_RX_ERR ((GP_IRQ1 | GP_IRQ3 | GP_IRQ4) >> 4) #define I2C_AUTO_SUSPEND_DELAY 250 enum i2c_se_mode { UNINITIALIZED, FIFO_SE_DMA, Loading Loading @@ -385,12 +387,22 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); int i, ret = 0, timeout = 0; ret = pinctrl_select_state(gi2c->i2c_rsc.geni_pinctrl, gi2c->i2c_rsc.geni_gpio_active); if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s: Error %d pinctrl_select_state active\n", __func__, ret); return ret; } if (!gi2c->tx_c) { gi2c->tx_c = dma_request_slave_channel(gi2c->dev, "tx"); if (!gi2c->tx_c) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "tx dma req slv chan ret :%d\n", ret); return -EIO; ret = -EIO; goto geni_i2c_gsi_xfer_out; } gi2c->tx_ev.init.callback = gi2c_ev_cb; gi2c->tx_ev.init.cb_param = gi2c; Loading @@ -400,7 +412,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "tx dma slave config ret :%d\n", ret); return ret; goto geni_i2c_gsi_xfer_out; } } if (!gi2c->rx_c) { Loading @@ -408,7 +420,8 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (!gi2c->rx_c) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "rx dma req slv chan ret :%d\n", ret); return -EIO; ret = -EIO; goto geni_i2c_gsi_xfer_out; } gi2c->rx_ev.init.cb_param = gi2c; gi2c->rx_ev.init.callback = gi2c_ev_cb; Loading @@ -418,7 +431,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (ret) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "rx dma slave config ret :%d\n", ret); return ret; goto geni_i2c_gsi_xfer_out; } } Loading Loading @@ -502,7 +515,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "prep_slave_sg for rx failed\n"); gi2c->err = -ENOMEM; return gi2c->err; goto geni_i2c_gsi_xfer_out; } gi2c->rx_desc->callback = gi2c_gsi_rx_cb; gi2c->rx_desc->callback_param = &gi2c->rx_cb; Loading Loading @@ -534,7 +547,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "prep_slave_sg for tx failed\n"); gi2c->err = -ENOMEM; return gi2c->err; goto geni_i2c_gsi_xfer_out; } gi2c->tx_desc->callback = gi2c_gsi_tx_cb; gi2c->tx_desc->callback_param = &gi2c->tx_cb; Loading @@ -559,10 +572,15 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (gi2c->err) { dmaengine_terminate_all(gi2c->tx_c); gi2c->cfg_sent = 0; return gi2c->err; goto geni_i2c_gsi_xfer_out; } } return gi2c->err; geni_i2c_gsi_xfer_out: if (!ret && gi2c->err) ret = gi2c->err; pinctrl_select_state(gi2c->i2c_rsc.geni_pinctrl, gi2c->i2c_rsc.geni_gpio_sleep); return ret; } static int geni_i2c_xfer(struct i2c_adapter *adap, Loading Loading @@ -686,7 +704,9 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, geni_i2c_txn_ret: if (ret == 0) ret = num; pm_runtime_put_sync(gi2c->dev); 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 @@ -830,6 +850,8 @@ 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); pm_runtime_use_autosuspend(gi2c->dev); pm_runtime_enable(gi2c->dev); i2c_add_adapter(&gi2c->adap); Loading Loading @@ -858,10 +880,13 @@ static int geni_i2c_runtime_suspend(struct device *dev) { struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); if (gi2c->se_mode == FIFO_SE_DMA) if (gi2c->se_mode == FIFO_SE_DMA) { disable_irq(gi2c->irq); se_geni_resources_off(&gi2c->i2c_rsc); } else { /* GPIO is set to sleep state already. So just clocks off */ se_geni_clks_off(&gi2c->i2c_rsc); } return 0; } Loading @@ -876,7 +901,12 @@ static int geni_i2c_runtime_resume(struct device *dev) snprintf(ipc_name, I2C_NAME_SIZE, "i2c-%d", gi2c->adap.nr); gi2c->ipcl = ipc_log_context_create(2, ipc_name, 0); } if (gi2c->se_mode != GSI_ONLY) ret = se_geni_resources_on(&gi2c->i2c_rsc); else ret = se_geni_clks_on(&gi2c->i2c_rsc); if (ret) return ret; Loading
drivers/platform/msm/qcom-geni-se.c +77 −36 Original line number Diff line number Diff line Loading @@ -575,13 +575,6 @@ void se_config_packing(void __iomem *base, int bpw, } EXPORT_SYMBOL(se_config_packing); static void se_geni_clks_off(struct se_geni_rsc *rsc) { clk_disable_unprepare(rsc->se_clk); clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); } static bool geni_se_check_bus_bw(struct geni_se_device *geni_se_dev) { int i; Loading Loading @@ -641,13 +634,13 @@ static int geni_se_rmv_ab_ib(struct geni_se_device *geni_se_dev, } /** * se_geni_resources_off() - Turn off resources associated with the serial * se_geni_clks_off() - Turn off clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_off(struct se_geni_rsc *rsc) int se_geni_clks_off(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; Loading @@ -659,42 +652,50 @@ int se_geni_resources_off(struct se_geni_rsc *rsc) if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw)) return -ENODEV; ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_sleep); if (ret) { GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); return ret; } se_geni_clks_off(rsc); clk_disable_unprepare(rsc->se_clk); clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); ret = geni_se_rmv_ab_ib(geni_se_dev, rsc); if (ret) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d during bus_bw_update\n", __func__, ret); return ret; } EXPORT_SYMBOL(se_geni_resources_off); EXPORT_SYMBOL(se_geni_clks_off); static int se_geni_clks_on(struct se_geni_rsc *rsc) /** * se_geni_resources_off() - Turn off resources associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_off(struct se_geni_rsc *rsc) { int ret; int ret = 0; struct geni_se_device *geni_se_dev; ret = clk_prepare_enable(rsc->m_ahb_clk); if (ret) return ret; if (unlikely(!rsc || !rsc->wrapper_dev)) return -EINVAL; ret = clk_prepare_enable(rsc->s_ahb_clk); if (ret) { clk_disable_unprepare(rsc->m_ahb_clk); return ret; } geni_se_dev = dev_get_drvdata(rsc->wrapper_dev); if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw)) return -ENODEV; ret = clk_prepare_enable(rsc->se_clk); ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_sleep); if (ret) { clk_disable_unprepare(rsc->s_ahb_clk); clk_disable_unprepare(rsc->m_ahb_clk); GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); return ret; } ret = se_geni_clks_off(rsc); if (ret) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d turning off clocks\n", __func__, ret); return ret; } EXPORT_SYMBOL(se_geni_resources_off); static int geni_se_add_ab_ib(struct geni_se_device *geni_se_dev, struct se_geni_rsc *rsc) Loading Loading @@ -733,13 +734,13 @@ static int geni_se_add_ab_ib(struct geni_se_device *geni_se_dev, } /** * se_geni_resources_on() - Turn on resources associated with the serial * se_geni_clks_on() - Turn on clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_on(struct se_geni_rsc *rsc) int se_geni_clks_on(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; Loading @@ -758,11 +759,52 @@ int se_geni_resources_on(struct se_geni_rsc *rsc) return ret; } ret = clk_prepare_enable(rsc->m_ahb_clk); if (ret) goto clks_on_err1; ret = clk_prepare_enable(rsc->s_ahb_clk); if (ret) goto clks_on_err2; ret = clk_prepare_enable(rsc->se_clk); if (ret) goto clks_on_err3; return 0; clks_on_err3: clk_disable_unprepare(rsc->s_ahb_clk); clks_on_err2: clk_disable_unprepare(rsc->m_ahb_clk); clks_on_err1: geni_se_rmv_ab_ib(geni_se_dev, rsc); return ret; } EXPORT_SYMBOL(se_geni_clks_on); /** * se_geni_resources_on() - Turn on resources associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_resources_on(struct se_geni_rsc *rsc) { int ret = 0; struct geni_se_device *geni_se_dev; if (unlikely(!rsc || !rsc->wrapper_dev)) return -EINVAL; geni_se_dev = dev_get_drvdata(rsc->wrapper_dev); if (unlikely(!geni_se_dev)) return -EPROBE_DEFER; ret = se_geni_clks_on(rsc); if (ret) { GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d during clks_on\n", __func__, ret); geni_se_rmv_ab_ib(geni_se_dev, rsc); return ret; } Loading @@ -771,7 +813,6 @@ int se_geni_resources_on(struct se_geni_rsc *rsc) GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL, "%s: Error %d pinctrl_select_state\n", __func__, ret); se_geni_clks_off(rsc); geni_se_rmv_ab_ib(geni_se_dev, rsc); } return ret; } Loading
include/linux/qcom-geni-se.h +28 −0 Original line number Diff line number Diff line Loading @@ -546,6 +546,24 @@ void se_get_packing_config(int bpw, int pack_words, bool msb_to_lsb, void se_config_packing(void __iomem *base, int bpw, int pack_words, bool msb_to_lsb); /** * se_geni_clks_off() - Turn off clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_clks_off(struct se_geni_rsc *rsc); /** * se_geni_clks_on() - Turn on clocks associated with the serial * engine * @rsc: Handle to resources associated with the serial engine. * * Return: 0 on success, standard Linux error codes on failure/error. */ int se_geni_clks_on(struct se_geni_rsc *rsc); /** * se_geni_resources_off() - Turn off resources associated with the serial * engine Loading Loading @@ -842,6 +860,16 @@ static inline void se_config_packing(void __iomem *base, int bpw, { } static inline int se_geni_clks_on(struct se_geni_rsc *rsc) { return -ENXIO; } static inline int se_geni_clks_off(struct se_geni_rsc *rsc) { return -ENXIO; } static inline int se_geni_resources_on(struct se_geni_rsc *rsc) { return -ENXIO; Loading