summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2021-07-16 20:34:35 +0200
committerLucas Stach <l.stach@pengutronix.de>2021-07-21 22:27:10 +0200
commitc58a4647d6a6fce8798092b4d19c90dd65ef62c1 (patch)
tree87b06bd151708090ae68c5bd322c867b862d4225
parentfd324ac75441f703ac3f939df5cfd9585e0c4c30 (diff)
downloadlinux-c58a4647d6a6fce8798092b4d19c90dd65ef62c1.tar.gz
linux-c58a4647d6a6fce8798092b4d19c90dd65ef62c1.tar.xz
phy: exynos-mipi-video: add basic runtime PM support
Add basic runtime PM support to the PHY driver. This allows to power up/down the power domain if the PHY is placed inside inside one. Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--drivers/phy/samsung/phy-exynos-mipi-video.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/phy/samsung/phy-exynos-mipi-video.c b/drivers/phy/samsung/phy-exynos-mipi-video.c
index b735b8089cd7..c508de53f97a 100644
--- a/drivers/phy/samsung/phy-exynos-mipi-video.c
+++ b/drivers/phy/samsung/phy-exynos-mipi-video.c
@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include <linux/mfd/syscon.h>
+#include <linux/pm_runtime.h>
enum exynos_mipi_phy_id {
EXYNOS_MIPI_PHY_ID_NONE = -1,
@@ -241,6 +242,7 @@ struct exynos_mipi_video_phy {
const struct exynos_mipi_phy_desc *data;
} phys[EXYNOS_MIPI_PHYS_NUM];
spinlock_t slock;
+ struct device *dev;
};
static int __set_phy_state(const struct exynos_mipi_phy_desc *data,
@@ -280,6 +282,13 @@ static int exynos_mipi_video_phy_power_on(struct phy *phy)
{
struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
+ int ret;
+
+ ret = pm_runtime_get_sync(state->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(state->dev);
+ return ret;
+ }
return __set_phy_state(phy_desc->data, state, 1);
}
@@ -288,8 +297,15 @@ static int exynos_mipi_video_phy_power_off(struct phy *phy)
{
struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
+ int ret;
+
+ ret = __set_phy_state(phy_desc->data, state, 0);
+ if (ret)
+ return ret;
- return __set_phy_state(phy_desc->data, state, 0);
+ pm_runtime_put(state->dev);
+
+ return 0;
}
static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
@@ -322,6 +338,8 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
if (!phy_dev)
return -ENODEV;
+ pm_runtime_enable(dev);
+
state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
@@ -334,6 +352,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
}
state->num_phys = phy_dev->num_phys;
spin_lock_init(&state->slock);
+ state->dev = dev;
dev_set_drvdata(dev, state);