Skip to content

Commit

Permalink
pwm: imx27: Ensure clocks being on iff the PWM is on
Browse files Browse the repository at this point in the history
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 01ccf90
("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 cfc4c18 ("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 <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
  • Loading branch information
Uwe Kleine-König authored and Thierry Reding committed Mar 30, 2020
1 parent 4563654 commit 2cb5cd9
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions drivers/pwm/pwm-imx27.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 2cb5cd9

Please sign in to comment.