From 2cb5cd90f4cd3f819178bb47f3d1ef86ce612db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 10 Feb 2020 22:22:40 +0100 Subject: [PATCH] pwm: imx27: Ensure clocks being on iff the PWM is on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Up to now the .probe() function didn't enable clocks and relied on the core to call the .get_state() callback to have the clock running. The latter enabled the needed clocks and kept them running if the PWM wass enabled. This only works correctly if the .get_state() callback is called exactly once and this single call happens before unused clocks are disabled by the clk core. The former wasn't true for a short period while commit 01ccf903edd6 ("pwm: Let pwm_get_state() return the last implemented state") applied and not reverted yet and might become wrong in the future. The latter isn't true any more since commit cfc4c189bc70 ("pwm: Read initial hardware state at request time") which results in a running PWM being stopped at boot time if for example the consumer lives in a kernel module that is only loaded after the clk core disabled unused clocks. So ensure .probe() is left with the clocks on if the PWM is running and .get_state() disables everything it enabled. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx27.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index fb142813d455..e83c077bb7cc 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -171,8 +171,7 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, tmp = NSEC_PER_SEC * (u64)(val); state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk); - if (!state->enabled) - pwm_imx27_clk_disable_unprepare(imx); + pwm_imx27_clk_disable_unprepare(imx); } static void pwm_imx27_sw_reset(struct pwm_chip *chip) @@ -307,6 +306,8 @@ MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids); static int pwm_imx27_probe(struct platform_device *pdev) { struct pwm_imx27_chip *imx; + int ret; + u32 pwmcr; imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) @@ -349,6 +350,15 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); + ret = pwm_imx27_clk_prepare_enable(imx); + if (ret) + return ret; + + /* keep clks on if pwm is running */ + pwmcr = readl(imx->mmio_base + MX3_PWMCR); + if (!(pwmcr & MX3_PWMCR_EN)) + pwm_imx27_clk_disable_unprepare(imx); + return pwmchip_add(&imx->chip); }