aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/include/linux/pwm.h
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>2024-09-20 10:57:57 +0200
committerUwe Kleine-König <ukleinek@kernel.org>2024-09-27 17:03:15 +0200
commit1cc2e1faafb3b5a2be25112559bdb495736b5af7 (patch)
tree61897cfec378c08e04fd8a5c9bd84a3d037ddb0b /include/linux/pwm.h
parentpwm: stm32: Fix a typo (diff)
downloadwireguard-linux-1cc2e1faafb3b5a2be25112559bdb495736b5af7.tar.xz
wireguard-linux-1cc2e1faafb3b5a2be25112559bdb495736b5af7.zip
pwm: Add more locking
This ensures that a pwm_chip that has no corresponding driver isn't used and that a driver doesn't go away while a callback is still running. In the presence of device links this isn't necessary yet (so this is no fix) but for pwm character device support this is needed. To not serialize all pwm_apply_state() calls, this introduces a per chip lock. An additional complication is that for atomic chips a mutex cannot be used (as pwm_apply_atomic() must not sleep) and a spinlock cannot be held while calling an operation for a sleeping chip. So depending on the chip being atomic or not a spinlock or a mutex is used. An additional change implemented here is that on driver remove the .free() callback is called for each requested pwm_device. This is the right time because later (e.g. when the consumer calls pwm_put()) the free function is (maybe) not available any more. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Link: https://lore.kernel.org/r/026aa891c8270a11723a1ba7e4256f456f7e1e86.1726819463.git.u.kleine-koenig@baylibre.com Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
Diffstat (limited to 'include/linux/pwm.h')
-rw-r--r--include/linux/pwm.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 8acd60b53f58..3ea73e075abe 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -275,6 +275,9 @@ struct pwm_ops {
* @of_xlate: request a PWM device given a device tree PWM specifier
* @atomic: can the driver's ->apply() be called in atomic context
* @uses_pwmchip_alloc: signals if pwmchip_allow was used to allocate this chip
+ * @operational: signals if the chip can be used (or is already deregistered)
+ * @nonatomic_lock: mutex for nonatomic chips
+ * @atomic_lock: mutex for atomic chips
* @pwms: array of PWM devices allocated by the framework
*/
struct pwm_chip {
@@ -290,6 +293,16 @@ struct pwm_chip {
/* only used internally by the PWM framework */
bool uses_pwmchip_alloc;
+ bool operational;
+ union {
+ /*
+ * depending on the chip being atomic or not either the mutex or
+ * the spinlock is used. It protects .operational and
+ * synchronizes the callbacks in .ops
+ */
+ struct mutex nonatomic_lock;
+ spinlock_t atomic_lock;
+ };
struct pwm_device pwms[] __counted_by(npwm);
};