From a2a28229cdce7bd4d95ecf57ea1306a9e2c10137 Mon Sep 17 00:00:00 2001 From: Patrick Havelange Date: Wed, 12 Jun 2019 16:12:46 +0200 Subject: 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 Signed-off-by: Thierry Reding --- drivers/pwm/pwm-fsl-ftm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/pwm') 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; } -- cgit