pwm: Make it explicit that pwm_apply_state() might sleep
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Thu, 9 Sep 2021 09:48:49 +0000 (11:48 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Fri, 5 Nov 2021 10:51:41 +0000 (11:51 +0100)
At least some implementations sleep. So mark pwm_apply_state() with a
might_sleep() to make callers aware. In the worst case this uncovers a
valid atomic user, then we revert this patch and at least gained some more
knowledge and then can work on a concept similar to
gpio_get_value/gpio_get_value_cansleep.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/core.c
include/linux/pwm.h

index 4527f09a5c5049c02cbec024893ecd3e65f120f8..fb04a439462c74bcd7db62f271dcb6b5f9f07234 100644 (file)
@@ -532,6 +532,15 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
        struct pwm_chip *chip;
        int err;
 
+       /*
+        * Some lowlevel driver's implementations of .apply() make use of
+        * mutexes, also with some drivers only returning when the new
+        * configuration is active calling pwm_apply_state() from atomic context
+        * is a bad idea. So make it explicit that calling this function might
+        * sleep.
+        */
+       might_sleep();
+
        if (!pwm || !state || !state->period ||
            state->duty_cycle > state->period)
                return -EINVAL;
index 515e33978e97b57cf92e45af180a720ba1d4dd48..e6dac95e4960923c51c46bfb142b515c1e055ad6 100644 (file)
@@ -441,6 +441,7 @@ static inline void pwm_free(struct pwm_device *pwm)
 static inline int pwm_apply_state(struct pwm_device *pwm,
                                  const struct pwm_state *state)
 {
+       might_sleep();
        return -ENOTSUPP;
 }
 
@@ -452,6 +453,7 @@ static inline int pwm_adjust_config(struct pwm_device *pwm)
 static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
                             int period_ns)
 {
+       might_sleep();
        return -EINVAL;
 }
 
@@ -464,11 +466,13 @@ static inline int pwm_capture(struct pwm_device *pwm,
 
 static inline int pwm_enable(struct pwm_device *pwm)
 {
+       might_sleep();
        return -EINVAL;
 }
 
 static inline void pwm_disable(struct pwm_device *pwm)
 {
+       might_sleep();
 }
 
 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)