Commit 1ac99c58 authored by Paul Cercueil's avatar Paul Cercueil Committed by Thierry Reding

pwm: jz4740: Apply configuration atomically

This is cleaner, more future-proof, and incidentally it also fixes the
PWM resetting its config when stopped/started several times.
Signed-off-by: default avatarPaul Cercueil <paul@crapouillou.net>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 93808aca
...@@ -83,17 +83,16 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -83,17 +83,16 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
jz4740_timer_disable(pwm->hwpwm); jz4740_timer_disable(pwm->hwpwm);
} }
static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns) struct pwm_state *state)
{ {
struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip); struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
unsigned long long tmp; unsigned long long tmp;
unsigned long period, duty; unsigned long period, duty;
unsigned int prescaler = 0; unsigned int prescaler = 0;
uint16_t ctrl; uint16_t ctrl;
bool is_enabled;
tmp = (unsigned long long)clk_get_rate(jz4740->clk) * period_ns; tmp = (unsigned long long)clk_get_rate(jz4740->clk) * state->period;
do_div(tmp, 1000000000); do_div(tmp, 1000000000);
period = tmp; period = tmp;
...@@ -105,16 +104,14 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -105,16 +104,14 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
if (prescaler == 6) if (prescaler == 6)
return -EINVAL; return -EINVAL;
tmp = (unsigned long long)period * duty_ns; tmp = (unsigned long long)period * state->duty_cycle;
do_div(tmp, period_ns); do_div(tmp, state->period);
duty = period - tmp; duty = period - tmp;
if (duty >= period) if (duty >= period)
duty = period - 1; duty = period - 1;
is_enabled = jz4740_timer_is_enabled(pwm->hwpwm); jz4740_pwm_disable(chip, pwm);
if (is_enabled)
jz4740_pwm_disable(chip, pwm);
jz4740_timer_set_count(pwm->hwpwm, 0); jz4740_timer_set_count(pwm->hwpwm, 0);
jz4740_timer_set_duty(pwm->hwpwm, duty); jz4740_timer_set_duty(pwm->hwpwm, duty);
...@@ -125,18 +122,7 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -125,18 +122,7 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
jz4740_timer_set_ctrl(pwm->hwpwm, ctrl); jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
if (is_enabled) switch (state->polarity) {
jz4740_pwm_enable(chip, pwm);
return 0;
}
static int jz4740_pwm_set_polarity(struct pwm_chip *chip,
struct pwm_device *pwm, enum pwm_polarity polarity)
{
uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);
switch (polarity) {
case PWM_POLARITY_NORMAL: case PWM_POLARITY_NORMAL:
ctrl &= ~JZ_TIMER_CTRL_PWM_ACTIVE_LOW; ctrl &= ~JZ_TIMER_CTRL_PWM_ACTIVE_LOW;
break; break;
...@@ -146,16 +132,17 @@ static int jz4740_pwm_set_polarity(struct pwm_chip *chip, ...@@ -146,16 +132,17 @@ static int jz4740_pwm_set_polarity(struct pwm_chip *chip,
} }
jz4740_timer_set_ctrl(pwm->hwpwm, ctrl); jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
if (state->enabled)
jz4740_pwm_enable(chip, pwm);
return 0; return 0;
} }
static const struct pwm_ops jz4740_pwm_ops = { static const struct pwm_ops jz4740_pwm_ops = {
.request = jz4740_pwm_request, .request = jz4740_pwm_request,
.free = jz4740_pwm_free, .free = jz4740_pwm_free,
.config = jz4740_pwm_config, .apply = jz4740_pwm_apply,
.set_polarity = jz4740_pwm_set_polarity,
.enable = jz4740_pwm_enable,
.disable = jz4740_pwm_disable,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment