Instead of open-coding the clk enable/disable in all of the callers
move this to the RPM suspend/resume functions.

Signed-off-by: Lucas Stach <l.st...@pengutronix.de>
Signed-off-by: Philipp Zabel <p.za...@pengutronix.de>
---
 drivers/gpu/ipu-v3/ipu-prg.c | 71 +++++++++++++++++++++++++++++++-------------
 1 file changed, 50 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c
index 0013ca9f72c8..fd98f48e8a08 100644
--- a/drivers/gpu/ipu-v3/ipu-prg.c
+++ b/drivers/gpu/ipu-v3/ipu-prg.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <video/imx-ipu-v3.h>
 
@@ -139,21 +140,11 @@ EXPORT_SYMBOL_GPL(ipu_prg_format_supported);
 int ipu_prg_enable(struct ipu_soc *ipu)
 {
        struct ipu_prg *prg = ipu->prg_priv;
-       int ret;
 
        if (!prg)
                return 0;
 
-       ret = clk_prepare_enable(prg->clk_axi);
-       if (ret)
-               goto fail_disable_ipg;
-
-       return 0;
-
-fail_disable_ipg:
-       clk_disable_unprepare(prg->clk_ipg);
-
-       return ret;
+       return pm_runtime_get_sync(prg->dev);
 }
 EXPORT_SYMBOL_GPL(ipu_prg_enable);
 
@@ -164,7 +155,7 @@ void ipu_prg_disable(struct ipu_soc *ipu)
        if (!prg)
                return;
 
-       clk_disable_unprepare(prg->clk_axi);
+       pm_runtime_put(prg->dev);
 }
 EXPORT_SYMBOL_GPL(ipu_prg_disable);
 
@@ -255,7 +246,7 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
        if (!chan->enabled || prg_chan < 0)
                return;
 
-       clk_prepare_enable(prg->clk_ipg);
+       pm_runtime_get_sync(prg->dev);
 
        val = readl(prg->regs + IPU_PRG_CTL);
        val |= IPU_PRG_CTL_BYPASS(prg_chan);
@@ -264,7 +255,7 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
        val = IPU_PRG_REG_UPDATE_REG_UPDATE;
        writel(val, prg->regs + IPU_PRG_REG_UPDATE);
 
-       clk_disable_unprepare(prg->clk_ipg);
+       pm_runtime_put(prg->dev);
 
        ipu_prg_put_pre(prg, prg_chan);
 
@@ -299,11 +290,7 @@ int ipu_prg_channel_configure(struct ipuv3_channel 
*ipu_chan,
                          width, height, stride, format, *eba);
 
 
-       ret = clk_prepare_enable(prg->clk_ipg);
-       if (ret) {
-               ipu_prg_put_pre(prg, prg_chan);
-               return ret;
-       }
+       pm_runtime_get_sync(prg->dev);
 
        val = (stride - 1) & IPU_PRG_STRIDE_STRIDE_MASK;
        writel(val, prg->regs + IPU_PRG_STRIDE(prg_chan));
@@ -336,7 +323,7 @@ int ipu_prg_channel_configure(struct ipuv3_channel 
*ipu_chan,
                           (val & IPU_PRG_STATUS_BUFFER1_READY(prg_chan)),
                           5, 1000);
 
-       clk_disable_unprepare(prg->clk_ipg);
+       pm_runtime_put(prg->dev);
 
        chan->enabled = true;
        return 0;
@@ -384,6 +371,12 @@ static int ipu_prg_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       ret = clk_prepare_enable(prg->clk_axi);
+       if (ret) {
+               clk_disable_unprepare(prg->clk_ipg);
+               return ret;
+       }
+
        /* init to free running mode */
        val = readl(prg->regs + IPU_PRG_CTL);
        val |= IPU_PRG_CTL_SHADOW_EN;
@@ -392,7 +385,8 @@ static int ipu_prg_probe(struct platform_device *pdev)
        /* disable address threshold */
        writel(0xffffffff, prg->regs + IPU_PRG_THD);
 
-       clk_disable_unprepare(prg->clk_ipg);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
 
        prg->dev = dev;
        platform_set_drvdata(pdev, prg);
@@ -414,6 +408,40 @@ static int ipu_prg_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int prg_suspend(struct device *dev)
+{
+       struct ipu_prg *prg = dev_get_drvdata(dev);
+
+       clk_disable_unprepare(prg->clk_axi);
+       clk_disable_unprepare(prg->clk_ipg);
+
+       return 0;
+}
+
+static int prg_resume(struct device *dev)
+{
+       struct ipu_prg *prg = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_prepare_enable(prg->clk_ipg);
+       if (ret)
+               return ret;
+
+       ret = clk_prepare_enable(prg->clk_axi);
+       if (ret) {
+               clk_disable_unprepare(prg->clk_ipg);
+               return ret;
+       }
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops prg_pm_ops = {
+       SET_RUNTIME_PM_OPS(prg_suspend, prg_resume, NULL)
+};
+
 static const struct of_device_id ipu_prg_dt_ids[] = {
        { .compatible = "fsl,imx6qp-prg", },
        { /* sentinel */ },
@@ -424,6 +452,7 @@ struct platform_driver ipu_prg_drv = {
        .remove         = ipu_prg_remove,
        .driver         = {
                .name   = "imx-ipu-prg",
+               .pm     = &prg_pm_ops,
                .of_match_table = ipu_prg_dt_ids,
        },
 };
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to