Commit 76128728 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pwm/for-5.14-rc2' of...

Merge tag 'pwm/for-5.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm fixes from Thierry Reding:
 "A couple of fixes from Uwe that I missed for v5.14-rc1"

* tag 'pwm/for-5.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: ep93xx: Ensure configuring period and duty_cycle isn't wrongly skipped
  pwm: berlin: Ensure configuring period and duty_cycle isn't wrongly skipped
  pwm: tiecap: Ensure configuring period and duty_cycle isn't wrongly skipped
  pwm: spear: Ensure configuring period and duty_cycle isn't wrongly skipped
  pwm: sprd: Ensure configuring period and duty_cycle isn't wrongly skipped
parents e9338abf f4a8e31e
...@@ -190,12 +190,9 @@ static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -190,12 +190,9 @@ static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0; return 0;
} }
if (state->period != pwm->state.period || err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period);
state->duty_cycle != pwm->state.duty_cycle) { if (err)
err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period); return err;
if (err)
return err;
}
if (!enabled) if (!enabled)
return berlin_pwm_enable(chip, pwm); return berlin_pwm_enable(chip, pwm);
......
...@@ -64,6 +64,11 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -64,6 +64,11 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
int ret; int ret;
struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
bool enabled = state->enabled; bool enabled = state->enabled;
void __iomem *base = ep93xx_pwm->base;
unsigned long long c;
unsigned long period_cycles;
unsigned long duty_cycles;
unsigned long term;
if (state->polarity != pwm->state.polarity) { if (state->polarity != pwm->state.polarity) {
if (enabled) { if (enabled) {
...@@ -97,57 +102,47 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -97,57 +102,47 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0; return 0;
} }
if (state->period != pwm->state.period || /*
state->duty_cycle != pwm->state.duty_cycle) { * The clock needs to be enabled to access the PWM registers.
struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); * Configuration can be changed at any time.
void __iomem *base = ep93xx_pwm->base; */
unsigned long long c; if (!pwm_is_enabled(pwm)) {
unsigned long period_cycles; ret = clk_prepare_enable(ep93xx_pwm->clk);
unsigned long duty_cycles; if (ret)
unsigned long term; return ret;
}
/* c = clk_get_rate(ep93xx_pwm->clk);
* The clock needs to be enabled to access the PWM registers. c *= state->period;
* Configuration can be changed at any time. do_div(c, 1000000000);
*/ period_cycles = c;
if (!pwm_is_enabled(pwm)) {
ret = clk_prepare_enable(ep93xx_pwm->clk); c = period_cycles;
if (ret) c *= state->duty_cycle;
return ret; do_div(c, state->period);
} duty_cycles = c;
c = clk_get_rate(ep93xx_pwm->clk); if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
c *= state->period; term = readw(base + EP93XX_PWMx_TERM_COUNT);
do_div(c, 1000000000);
period_cycles = c; /* Order is important if PWM is running */
if (period_cycles > term) {
c = period_cycles; writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
c *= state->duty_cycle; writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
do_div(c, state->period);
duty_cycles = c;
if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
term = readw(base + EP93XX_PWMx_TERM_COUNT);
/* Order is important if PWM is running */
if (period_cycles > term) {
writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
} else {
writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
}
ret = 0;
} else { } else {
ret = -EINVAL; writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
} }
ret = 0;
} else {
ret = -EINVAL;
}
if (!pwm_is_enabled(pwm)) if (!pwm_is_enabled(pwm))
clk_disable_unprepare(ep93xx_pwm->clk); clk_disable_unprepare(ep93xx_pwm->clk);
if (ret) if (ret)
return ret; return ret;
}
if (!enabled) { if (!enabled) {
ret = clk_prepare_enable(ep93xx_pwm->clk); ret = clk_prepare_enable(ep93xx_pwm->clk);
......
...@@ -177,12 +177,9 @@ static int spear_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -177,12 +177,9 @@ static int spear_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0; return 0;
} }
if (state->period != pwm->state.period || err = spear_pwm_config(chip, pwm, state->duty_cycle, state->period);
state->duty_cycle != pwm->state.duty_cycle) { if (err)
err = spear_pwm_config(chip, pwm, state->duty_cycle, state->period); return err;
if (err)
return err;
}
if (!pwm->state.enabled) if (!pwm->state.enabled)
return spear_pwm_enable(chip, pwm); return spear_pwm_enable(chip, pwm);
......
...@@ -183,13 +183,10 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -183,13 +183,10 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
} }
} }
if (state->period != cstate->period || ret = sprd_pwm_config(spc, pwm, state->duty_cycle,
state->duty_cycle != cstate->duty_cycle) { state->period);
ret = sprd_pwm_config(spc, pwm, state->duty_cycle, if (ret)
state->period); return ret;
if (ret)
return ret;
}
sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1); sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1);
} else if (cstate->enabled) { } else if (cstate->enabled) {
......
...@@ -189,16 +189,13 @@ static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -189,16 +189,13 @@ static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0; return 0;
} }
if (state->period != pwm->state.period || if (state->period > NSEC_PER_SEC)
state->duty_cycle != pwm->state.duty_cycle) { return -ERANGE;
if (state->period > NSEC_PER_SEC)
return -ERANGE;
err = ecap_pwm_config(chip, pwm, state->duty_cycle, err = ecap_pwm_config(chip, pwm, state->duty_cycle,
state->period, enabled); state->period, enabled);
if (err) if (err)
return err; return err;
}
if (!enabled) if (!enabled)
return ecap_pwm_enable(chip, pwm); return ecap_pwm_enable(chip, pwm);
......
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