Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
[sfrench/cifs-2.6.git] / drivers / pwm / pwm-stm32.c
index 6139512aab7b8953c708279ee9a61580d9adcbc3..2708212933f72f077d2f23ef6b283a35c7bd0413 100644 (file)
@@ -1,10 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics 2016
  *
  * Author: Gerald Baeza <gerald.baeza@st.com>
  *
- * License terms: GNU General Public License (GPL), version 2
- *
  * Inspired by timer-stm32.c from Maxime Coquelin
  *             pwm-atmel.c from Bo Shen
  */
@@ -21,7 +20,7 @@
 
 struct stm32_pwm {
        struct pwm_chip chip;
-       struct device *dev;
+       struct mutex lock; /* protect pwm config/enable */
        struct clk *clk;
        struct regmap *regmap;
        u32 max_arr;
@@ -214,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,
@@ -336,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;