diff options
author | Patrick Havelange <patrick.havelange@essensium.com> | 2019-06-12 16:12:46 +0200 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2019-06-26 11:39:18 +0200 |
commit | a2a28229cdce7bd4d95ecf57ea1306a9e2c10137 (patch) | |
tree | 0343d179b052f50a8968d01dec828a3c09b9ef0b /drivers/pwm | |
parent | pwm: fsl-ftm: More relaxed permissions for updating period (diff) | |
download | linux-a2a28229cdce7bd4d95ecf57ea1306a9e2c10137.tar.xz linux-a2a28229cdce7bd4d95ecf57ea1306a9e2c10137.zip |
pwm: fsl-ftm: Use write protection for prescaler & polarity
Modifying the prescaler or polarity value must be done with the
write protection disabled. Currently this is working by chance as
the write protection is in a disabled state by default.
This patch makes sure that we enable/disable the write protection
when needed.
Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-fsl-ftm.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index e14b8e191cd4..6a4106c65cb4 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -63,6 +63,21 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip) return container_of(chip, struct fsl_pwm_chip, chip); } +static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc) +{ + u32 val; + + regmap_read(fpc->regmap, FTM_FMS, &val); + if (val & FTM_FMS_WPEN) + regmap_update_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS, + FTM_MODE_WPDIS); +} + +static void ftm_set_write_protection(struct fsl_pwm_chip *fpc) +{ + regmap_update_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN, FTM_FMS_WPEN); +} + static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a, const struct fsl_pwm_periodcfg *b) { @@ -257,6 +272,8 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc, do_write_period = true; } + ftm_clear_write_protection(fpc); + if (do_write_period) { regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK, FTM_SC_CLK(periodcfg.clk_select)); @@ -283,6 +300,8 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc, fpc->period.mod_period + 1); newstate->duty_cycle = fsl_pwm_ticks_to_ns(fpc, duty); + ftm_set_write_protection(fpc); + return 0; } @@ -367,6 +386,8 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc) static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { + case FTM_FMS: + case FTM_MODE: case FTM_CNT: return true; } |