summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2023-09-15 11:53:22 +0300
committerGeert Uytterhoeven <geert+renesas@glider.be>2023-10-16 12:47:43 +0300
commit616f73c9d3255342a037c5204ce381a4d7aa274a (patch)
treed2cf209190336ab6c23b751c0b13461a3f287b12 /drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
parentb25064ef997bf30ad8c6abe5fbd6e3ddae75d17b (diff)
downloadlinux-616f73c9d3255342a037c5204ce381a4d7aa274a.tar.xz
drm: renesas: shmobile: Add support for Runtime PM
The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs (clock domain on all, power domain on some). Hence it may not be sufficient to manage the LCDC module clock explicitly (e.g. if the selected clock source differs from SHMOB_DRM_CLK_BUS). Fix this by using Runtime PM for all clock handling. Add an explicit dependency on CONFIG_PM, which should already be met on all affected platforms. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lore.kernel.org/r/e7359a64963bd9a4f1531c2beae850774ce140bc.1694767209.git.geert+renesas@glider.be
Diffstat (limited to 'drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c')
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index e5db4e0095ba..a0f8b7666ab3 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <drm/drm_drv.h>
@@ -165,8 +166,35 @@ static int shmob_drm_pm_resume(struct device *dev)
return 0;
}
-static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
- shmob_drm_pm_suspend, shmob_drm_pm_resume);
+static int shmob_drm_pm_runtime_suspend(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+
+ if (sdev->clock)
+ clk_disable_unprepare(sdev->clock);
+
+ return 0;
+}
+
+static int shmob_drm_pm_runtime_resume(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+ int ret;
+
+ if (sdev->clock) {
+ ret = clk_prepare_enable(sdev->clock);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops shmob_drm_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(shmob_drm_pm_suspend, shmob_drm_pm_resume)
+ RUNTIME_PM_OPS(shmob_drm_pm_runtime_suspend,
+ shmob_drm_pm_runtime_resume, NULL)
+};
/* -----------------------------------------------------------------------------
* Platform driver
@@ -218,6 +246,10 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
+ return ret;
+
ret = shmob_drm_init_interface(sdev);
if (ret < 0)
return ret;
@@ -289,7 +321,7 @@ static struct platform_driver shmob_drm_platform_driver = {
.remove_new = shmob_drm_remove,
.driver = {
.name = "shmob-drm",
- .pm = pm_sleep_ptr(&shmob_drm_pm_ops),
+ .pm = &shmob_drm_pm_ops,
},
};