Skip to content
This repository has been archived by the owner on Dec 29, 2017. It is now read-only.

Commit

Permalink
pwm: rockchip: State of PWM clock should synchronize with PWM enabled…
Browse files Browse the repository at this point in the history
… state

commit a900152 upstream.

If the PWM was not enabled at U-Boot loader, PWM could not work for
clock always disabled at PWM driver. The PWM clock is enabled at
beginning of pwm_apply(), but disabled at end of pwm_apply().

If the PWM was enabled at U-Boot loader, PWM clock is always enabled
unless closed by ATF. The pwm-backlight might turn off the power at
early suspend, should disable PWM clock for saving power consume.

It is important to provide opportunity to enable/disable clock at PWM
driver, the PWM consumer should ensure correct order to call PWM enable
and disable, and PWM driver ensure state of PWM clock synchronized with
PWM enabled state.

Fixes: 2bf1c98 ("pwm: rockchip: Add support for atomic update")
Signed-off-by: David Wu <[email protected]>
Reviewed-by: Boris Brezillon <[email protected]>
Signed-off-by: Thierry Reding <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
SuperDavidWu authored and gregkh committed Apr 21, 2017
1 parent 088e580 commit 5f48cac
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions drivers/pwm/pwm-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}

static int rockchip_pwm_enable(struct pwm_chip *chip,
struct pwm_device *pwm,
bool enable,
enum pwm_polarity polarity)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
int ret;

if (enable) {
ret = clk_enable(pc->clk);
if (ret)
return ret;
}

pc->data->set_enable(chip, pwm, enable, polarity);

if (!enable)
clk_disable(pc->clk);

return 0;
}

static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
Expand All @@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;

if (state->polarity != curstate.polarity && enabled) {
pc->data->set_enable(chip, pwm, false, state->polarity);
ret = rockchip_pwm_enable(chip, pwm, false, state->polarity);
if (ret)
goto out;
enabled = false;
}

ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
if (ret) {
if (enabled != curstate.enabled)
pc->data->set_enable(chip, pwm, !enabled,
state->polarity);

rockchip_pwm_enable(chip, pwm, !enabled,
state->polarity);
goto out;
}

if (state->enabled != enabled)
pc->data->set_enable(chip, pwm, state->enabled,
state->polarity);
if (state->enabled != enabled) {
ret = rockchip_pwm_enable(chip, pwm, state->enabled,
state->polarity);
if (ret)
goto out;
}

/*
* Update the state with the real hardware, which can differ a bit
Expand Down

0 comments on commit 5f48cac

Please sign in to comment.