Skip to content

Commit 1cc2e1f

Browse files
ukleinekUwe Kleine-König
authored andcommitted
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>
1 parent d242fea commit 1cc2e1f

2 files changed

Lines changed: 105 additions & 8 deletions

File tree

drivers/pwm/core.c

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ static DEFINE_MUTEX(pwm_lock);
3131

3232
static DEFINE_IDR(pwm_chips);
3333

34+
static void pwmchip_lock(struct pwm_chip *chip)
35+
{
36+
if (chip->atomic)
37+
spin_lock(&chip->atomic_lock);
38+
else
39+
mutex_lock(&chip->nonatomic_lock);
40+
}
41+
42+
static void pwmchip_unlock(struct pwm_chip *chip)
43+
{
44+
if (chip->atomic)
45+
spin_unlock(&chip->atomic_lock);
46+
else
47+
mutex_unlock(&chip->nonatomic_lock);
48+
}
49+
50+
DEFINE_GUARD(pwmchip, struct pwm_chip *, pwmchip_lock(_T), pwmchip_unlock(_T))
51+
3452
static void pwm_apply_debug(struct pwm_device *pwm,
3553
const struct pwm_state *state)
3654
{
@@ -220,6 +238,7 @@ static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state)
220238
int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)
221239
{
222240
int err;
241+
struct pwm_chip *chip = pwm->chip;
223242

224243
/*
225244
* Some lowlevel driver's implementations of .apply() make use of
@@ -230,7 +249,12 @@ int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)
230249
*/
231250
might_sleep();
232251

233-
if (IS_ENABLED(CONFIG_PWM_DEBUG) && pwm->chip->atomic) {
252+
guard(pwmchip)(chip);
253+
254+
if (!chip->operational)
255+
return -ENODEV;
256+
257+
if (IS_ENABLED(CONFIG_PWM_DEBUG) && chip->atomic) {
234258
/*
235259
* Catch any drivers that have been marked as atomic but
236260
* that will sleep anyway.
@@ -254,9 +278,16 @@ EXPORT_SYMBOL_GPL(pwm_apply_might_sleep);
254278
*/
255279
int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state)
256280
{
257-
WARN_ONCE(!pwm->chip->atomic,
281+
struct pwm_chip *chip = pwm->chip;
282+
283+
WARN_ONCE(!chip->atomic,
258284
"sleeping PWM driver used in atomic context\n");
259285

286+
guard(pwmchip)(chip);
287+
288+
if (!chip->operational)
289+
return -ENODEV;
290+
260291
return __pwm_apply(pwm, state);
261292
}
262293
EXPORT_SYMBOL_GPL(pwm_apply_atomic);
@@ -334,8 +365,18 @@ static int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
334365
if (!ops->capture)
335366
return -ENOSYS;
336367

368+
/*
369+
* Holding the pwm_lock is probably not needed. If you use pwm_capture()
370+
* and you're interested to speed it up, please convince yourself it's
371+
* really not needed, test and then suggest a patch on the mailing list.
372+
*/
337373
guard(mutex)(&pwm_lock);
338374

375+
guard(pwmchip)(chip);
376+
377+
if (!chip->operational)
378+
return -ENODEV;
379+
339380
return ops->capture(chip, pwm, result, timeout);
340381
}
341382

@@ -368,6 +409,14 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
368409
if (test_bit(PWMF_REQUESTED, &pwm->flags))
369410
return -EBUSY;
370411

412+
/*
413+
* This function is called while holding pwm_lock. As .operational only
414+
* changes while holding this lock, checking it here without holding the
415+
* chip lock is fine.
416+
*/
417+
if (!chip->operational)
418+
return -ENODEV;
419+
371420
if (!try_module_get(chip->owner))
372421
return -ENODEV;
373422

@@ -396,7 +445,9 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
396445
*/
397446
struct pwm_state state = { 0, };
398447

399-
err = ops->get_state(chip, pwm, &state);
448+
scoped_guard(pwmchip, chip)
449+
err = ops->get_state(chip, pwm, &state);
450+
400451
trace_pwm_get(pwm, &state, err);
401452

402453
if (!err)
@@ -1020,6 +1071,7 @@ struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t
10201071

10211072
chip->npwm = npwm;
10221073
chip->uses_pwmchip_alloc = true;
1074+
chip->operational = false;
10231075

10241076
pwmchip_dev = &chip->dev;
10251077
device_initialize(pwmchip_dev);
@@ -1125,6 +1177,11 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
11251177

11261178
chip->owner = owner;
11271179

1180+
if (chip->atomic)
1181+
spin_lock_init(&chip->atomic_lock);
1182+
else
1183+
mutex_init(&chip->nonatomic_lock);
1184+
11281185
guard(mutex)(&pwm_lock);
11291186

11301187
ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL);
@@ -1138,13 +1195,19 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
11381195
if (IS_ENABLED(CONFIG_OF))
11391196
of_pwmchip_add(chip);
11401197

1198+
scoped_guard(pwmchip, chip)
1199+
chip->operational = true;
1200+
11411201
ret = device_add(&chip->dev);
11421202
if (ret)
11431203
goto err_device_add;
11441204

11451205
return 0;
11461206

11471207
err_device_add:
1208+
scoped_guard(pwmchip, chip)
1209+
chip->operational = false;
1210+
11481211
if (IS_ENABLED(CONFIG_OF))
11491212
of_pwmchip_remove(chip);
11501213

@@ -1164,11 +1227,27 @@ void pwmchip_remove(struct pwm_chip *chip)
11641227
{
11651228
pwmchip_sysfs_unexport(chip);
11661229

1167-
if (IS_ENABLED(CONFIG_OF))
1168-
of_pwmchip_remove(chip);
1230+
scoped_guard(mutex, &pwm_lock) {
1231+
unsigned int i;
1232+
1233+
scoped_guard(pwmchip, chip)
1234+
chip->operational = false;
1235+
1236+
for (i = 0; i < chip->npwm; ++i) {
1237+
struct pwm_device *pwm = &chip->pwms[i];
1238+
1239+
if (test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
1240+
dev_warn(&chip->dev, "Freeing requested PWM #%u\n", i);
1241+
if (pwm->chip->ops->free)
1242+
pwm->chip->ops->free(pwm->chip, pwm);
1243+
}
1244+
}
1245+
1246+
if (IS_ENABLED(CONFIG_OF))
1247+
of_pwmchip_remove(chip);
11691248

1170-
scoped_guard(mutex, &pwm_lock)
11711249
idr_remove(&pwm_chips, chip->id);
1250+
}
11721251

11731252
device_del(&chip->dev);
11741253
}
@@ -1538,12 +1617,17 @@ void pwm_put(struct pwm_device *pwm)
15381617

15391618
guard(mutex)(&pwm_lock);
15401619

1541-
if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
1620+
/*
1621+
* Trigger a warning if a consumer called pwm_put() twice.
1622+
* If the chip isn't operational, PWMF_REQUESTED was already cleared in
1623+
* pwmchip_remove(). So don't warn in this case.
1624+
*/
1625+
if (chip->operational && !test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
15421626
pr_warn("PWM device already freed\n");
15431627
return;
15441628
}
15451629

1546-
if (chip->ops->free)
1630+
if (chip->operational && chip->ops->free)
15471631
pwm->chip->ops->free(pwm->chip, pwm);
15481632

15491633
pwm->label = NULL;

include/linux/pwm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ struct pwm_ops {
275275
* @of_xlate: request a PWM device given a device tree PWM specifier
276276
* @atomic: can the driver's ->apply() be called in atomic context
277277
* @uses_pwmchip_alloc: signals if pwmchip_allow was used to allocate this chip
278+
* @operational: signals if the chip can be used (or is already deregistered)
279+
* @nonatomic_lock: mutex for nonatomic chips
280+
* @atomic_lock: mutex for atomic chips
278281
* @pwms: array of PWM devices allocated by the framework
279282
*/
280283
struct pwm_chip {
@@ -290,6 +293,16 @@ struct pwm_chip {
290293

291294
/* only used internally by the PWM framework */
292295
bool uses_pwmchip_alloc;
296+
bool operational;
297+
union {
298+
/*
299+
* depending on the chip being atomic or not either the mutex or
300+
* the spinlock is used. It protects .operational and
301+
* synchronizes the callbacks in .ops
302+
*/
303+
struct mutex nonatomic_lock;
304+
spinlock_t atomic_lock;
305+
};
293306
struct pwm_device pwms[] __counted_by(npwm);
294307
};
295308

0 commit comments

Comments
 (0)