summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/pwm-stm32.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 014e2a759fa6..2708212933f7 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -20,6 +20,7 @@
struct stm32_pwm {
struct pwm_chip chip;
+ struct mutex lock; /* protect pwm config/enable */
struct clk *clk;
struct regmap *regmap;
u32 max_arr;
@@ -212,9 +213,23 @@ static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;
}
+static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
+ int ret;
+
+ /* protect common prescaler for all active channels */
+ mutex_lock(&priv->lock);
+ ret = stm32_pwm_apply(chip, pwm, state);
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
static const struct pwm_ops stm32pwm_ops = {
.owner = THIS_MODULE,
- .apply = stm32_pwm_apply,
+ .apply = stm32_pwm_apply_locked,
};
static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
@@ -334,6 +349,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ mutex_init(&priv->lock);
priv->regmap = ddata->regmap;
priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr;