Gather all clock enables and disables into a single function to avoid repetitions between driver init/fini and device resume/suspend, since these clocks are always handled in bulk.
Also do clk (un)prepares and dis/enables at the same time, since the clk_prepare_* family of functions can simply increase the refcnt of an already prepared clock. Signed-off-by: Adrián Larumbe <[email protected]> --- drivers/gpu/drm/panfrost/panfrost_device.c | 118 +++++++++++++---------------- 1 file changed, 52 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index b3a53504bd01..2fcbd223204c 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -34,10 +34,46 @@ static void panfrost_reset_fini(struct panfrost_device *pfdev) reset_control_assert(pfdev->rstc); } -static int panfrost_clk_init(struct panfrost_device *pfdev) +static int panfrost_clk_enable(struct panfrost_device *pfdev, bool enable_ace_clock) { int err; + + err = clk_prepare_enable(pfdev->clock); + if (err) + return err; + + err = clk_prepare_enable(pfdev->bus_clock); + if (err) + goto disable_clock; + + if (enable_ace_clock) { + err = clk_prepare_enable(pfdev->bus_ace_clock); + if (err) + goto disable_bus_clock; + } + + return 0; + +disable_bus_clock: + clk_disable_unprepare(pfdev->bus_clock); +disable_clock: + clk_disable_unprepare(pfdev->clock); + + return err; +} + +static void panfrost_clk_disable(struct panfrost_device *pfdev, bool disable_ace_clock) +{ + if (disable_ace_clock) + clk_disable_unprepare(pfdev->bus_ace_clock); + clk_disable_unprepare(pfdev->bus_clock); + clk_disable_unprepare(pfdev->clock); +} + +static int panfrost_clk_init(struct panfrost_device *pfdev) +{ unsigned long rate; + int err; pfdev->clock = devm_clk_get(pfdev->base.dev, NULL); if (IS_ERR(pfdev->clock)) { @@ -48,53 +84,31 @@ static int panfrost_clk_init(struct panfrost_device *pfdev) rate = clk_get_rate(pfdev->clock); dev_info(pfdev->base.dev, "clock rate = %lu\n", rate); - err = clk_prepare_enable(pfdev->clock); - if (err) - return err; - pfdev->bus_clock = devm_clk_get_optional(pfdev->base.dev, "bus"); if (IS_ERR(pfdev->bus_clock)) { - dev_err(pfdev->base.dev, "get bus_clock failed %ld\n", - PTR_ERR(pfdev->bus_clock)); err = PTR_ERR(pfdev->bus_clock); - goto disable_clock; + dev_err(pfdev->base.dev, "get bus_clock failed %d\n", err); + return err; } if (pfdev->bus_clock) { rate = clk_get_rate(pfdev->bus_clock); dev_info(pfdev->base.dev, "bus_clock rate = %lu\n", rate); - - err = clk_prepare_enable(pfdev->bus_clock); - if (err) - goto disable_clock; } pfdev->bus_ace_clock = devm_clk_get_optional(pfdev->base.dev, "bus_ace"); if (IS_ERR(pfdev->bus_ace_clock)) { err = PTR_ERR(pfdev->bus_ace_clock); dev_err(pfdev->base.dev, "get bus_ace_clock failed %d\n", err); - goto disable_bus_clock; + return err; } - err = clk_prepare_enable(pfdev->bus_ace_clock); - if (err) - goto disable_bus_clock; - - return 0; - -disable_bus_clock: - clk_disable_unprepare(pfdev->bus_clock); -disable_clock: - clk_disable_unprepare(pfdev->clock); - - return err; + return panfrost_clk_enable(pfdev, true); } static void panfrost_clk_fini(struct panfrost_device *pfdev) { - clk_disable_unprepare(pfdev->bus_ace_clock); - clk_disable_unprepare(pfdev->bus_clock); - clk_disable_unprepare(pfdev->clock); + panfrost_clk_disable(pfdev, true); } static int panfrost_regulator_init(struct panfrost_device *pfdev) @@ -436,34 +450,17 @@ static int panfrost_device_runtime_resume(struct device *dev) if (ret) return ret; - ret = clk_enable(pfdev->clock); - if (ret) - goto err_clk; - - ret = clk_enable(pfdev->bus_clock); - if (ret) - goto err_bus_clk; - - ret = clk_enable(pfdev->bus_ace_clock); - if (ret) - goto err_bus_ace_clk; + ret = panfrost_clk_enable(pfdev, true); + if (ret) { + reset_control_assert(pfdev->rstc); + return ret; + } } panfrost_device_reset(pfdev, true); panfrost_devfreq_resume(pfdev); return 0; - -err_bus_ace_clk: - if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) - clk_disable(pfdev->bus_clock); -err_bus_clk: - if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) - clk_disable(pfdev->clock); -err_clk: - if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) - reset_control_assert(pfdev->rstc); - return ret; } static int panfrost_device_runtime_suspend(struct device *dev) @@ -480,9 +477,7 @@ static int panfrost_device_runtime_suspend(struct device *dev) panfrost_gpu_power_off(pfdev); if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) { - clk_disable(pfdev->bus_ace_clock); - clk_disable(pfdev->bus_clock); - clk_disable(pfdev->clock); + panfrost_clk_disable(pfdev, true); reset_control_assert(pfdev->rstc); } @@ -506,13 +501,9 @@ static int panfrost_device_resume(struct device *dev) } if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { - ret = clk_enable(pfdev->clock); + ret = panfrost_clk_enable(pfdev, false); if (ret) goto err_clk; - - ret = clk_enable(pfdev->bus_clock); - if (ret) - goto err_bus_clk; } ret = pm_runtime_force_resume(dev); @@ -523,10 +514,7 @@ static int panfrost_device_resume(struct device *dev) err_resume: if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) - clk_disable(pfdev->bus_clock); -err_bus_clk: - if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) - clk_disable(pfdev->clock); + clk_disable_unprepare(pfdev->bus_clock); err_clk: if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) dev_pm_opp_set_opp(dev, NULL); @@ -542,10 +530,8 @@ static int panfrost_device_suspend(struct device *dev) if (ret) return ret; - if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { - clk_disable(pfdev->bus_clock); - clk_disable(pfdev->clock); - } + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) + panfrost_clk_disable(pfdev, false); if (pfdev->comp->pm_features & BIT(GPU_PM_VREG_OFF)) dev_pm_opp_set_opp(dev, NULL); -- 2.55.0
