diff options
-rw-r--r-- | drivers/phy/samsung/phy-exynos-mipi-video.c | 21 |
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); |