Skip to content

Commit 5a62491

Browse files
maxskiierjic23
authored andcommitted
iio: magnetometer: rm3100: Modernize locking and refactor control flow
Replace mutex_lock() and mutex_unlock() calls in rm3100-core.c with the more modern guard(mutex)() family. This will help modernize the driver and bring it up-to-date with modern available macros/functions. While replacing mutex_lock() and mutex_unlock(), the critical sections of rm3100_read_mag() and rm3100_get_samp_freq() have been extended to include negligible operations for cleaner logic. Add new helper-wrapper function rm3100_regmap_bulk_read_locked() to help keep rm3100_trigger_handler() switch-cases clean while maintaining mutex locking and avoiding re-entrancy risks from potential callbacks. While at it, remove redundant gotos where applicable, and use direct returns instead. In addition, remove regmap variable in rm3100_trigger_handler() as its references have been replaced with variable data. Suggested-by: Jonathan Cameron <jic23@kernel.org> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Maxwell Doose <m32285159@gmail.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
1 parent d0b396c commit 5a62491

1 file changed

Lines changed: 51 additions & 43 deletions

File tree

drivers/iio/magnetometer/rm3100-core.c

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -204,27 +204,23 @@ static int rm3100_read_mag(struct rm3100_data *data, int idx, int *val)
204204
u8 buffer[3];
205205
int ret;
206206

207-
mutex_lock(&data->lock);
207+
guard(mutex)(&data->lock);
208+
208209
ret = regmap_write(regmap, RM3100_REG_POLL, BIT(4 + idx));
209210
if (ret < 0)
210-
goto unlock_return;
211+
return ret;
211212

212213
ret = rm3100_wait_measurement(data);
213214
if (ret < 0)
214-
goto unlock_return;
215+
return ret;
215216

216217
ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * idx, buffer, 3);
217218
if (ret < 0)
218-
goto unlock_return;
219-
mutex_unlock(&data->lock);
219+
return ret;
220220

221221
*val = sign_extend32(get_unaligned_be24(&buffer[0]), 23);
222222

223223
return IIO_VAL_INT;
224-
225-
unlock_return:
226-
mutex_unlock(&data->lock);
227-
return ret;
228224
}
229225

230226
#define RM3100_CHANNEL(axis, idx) \
@@ -284,11 +280,12 @@ static int rm3100_get_samp_freq(struct rm3100_data *data, int *val, int *val2)
284280
unsigned int tmp;
285281
int ret;
286282

287-
mutex_lock(&data->lock);
283+
guard(mutex)(&data->lock);
284+
288285
ret = regmap_read(data->regmap, RM3100_REG_TMRC, &tmp);
289-
mutex_unlock(&data->lock);
290286
if (ret < 0)
291287
return ret;
288+
292289
*val = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][0];
293290
*val2 = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][1];
294291

@@ -338,56 +335,50 @@ static int rm3100_set_samp_freq(struct iio_dev *indio_dev, int val, int val2)
338335
int ret;
339336
int i;
340337

341-
mutex_lock(&data->lock);
338+
guard(mutex)(&data->lock);
339+
342340
/* All cycle count registers use the same value. */
343341
ret = regmap_read(regmap, RM3100_REG_CC_X, &cycle_count);
344342
if (ret < 0)
345-
goto unlock_return;
343+
return ret;
346344

347345
for (i = 0; i < RM3100_SAMP_NUM; i++) {
348346
if (val == rm3100_samp_rates[i][0] &&
349347
val2 == rm3100_samp_rates[i][1])
350348
break;
351349
}
352-
if (i == RM3100_SAMP_NUM) {
353-
ret = -EINVAL;
354-
goto unlock_return;
355-
}
350+
if (i == RM3100_SAMP_NUM)
351+
return -EINVAL;
356352

357353
ret = regmap_write(regmap, RM3100_REG_TMRC, i + RM3100_TMRC_OFFSET);
358354
if (ret < 0)
359-
goto unlock_return;
355+
return ret;
360356

361357
/* Checking if cycle count registers need changing. */
362358
if (val == 600 && cycle_count == 200) {
363359
ret = rm3100_set_cycle_count(data, 100);
364360
if (ret < 0)
365-
goto unlock_return;
361+
return ret;
366362
} else if (val != 600 && cycle_count == 100) {
367363
ret = rm3100_set_cycle_count(data, 200);
368364
if (ret < 0)
369-
goto unlock_return;
365+
return ret;
370366
}
371367

372368
if (iio_buffer_enabled(indio_dev)) {
373369
/* Writing TMRC registers requires CMM reset. */
374370
ret = regmap_write(regmap, RM3100_REG_CMM, 0);
375371
if (ret < 0)
376-
goto unlock_return;
372+
return ret;
377373
ret = regmap_write(data->regmap, RM3100_REG_CMM,
378374
(*indio_dev->active_scan_mask & 0x7) <<
379375
RM3100_CMM_AXIS_SHIFT | RM3100_CMM_START);
380376
if (ret < 0)
381-
goto unlock_return;
377+
return ret;
382378
}
383-
mutex_unlock(&data->lock);
384379

385380
data->conversion_time = rm3100_samp_rates[i][2] * 2;
386381
return 0;
387-
388-
unlock_return:
389-
mutex_unlock(&data->lock);
390-
return ret;
391382
}
392383

393384
static int rm3100_read_raw(struct iio_dev *indio_dev,
@@ -458,58 +449,75 @@ static const struct iio_buffer_setup_ops rm3100_buffer_ops = {
458449
.postdisable = rm3100_buffer_postdisable,
459450
};
460451

452+
/**
453+
* rm3100_regmap_bulk_read_locked() - Wrapper around regmap_bulk_read() with a mutex
454+
*
455+
* @data: Data structure containing regmap and mutex
456+
* @reg: First register to be read from, passed to regmap_bulk_read()
457+
* @val: Pointer to store read value, in native register size for device,
458+
* passed to regmap_bulk_read()
459+
* @val_count: Number of registers to read, passed to regmap_bulk_read()
460+
*
461+
* Intended for use only in rm3100_trigger_handler().
462+
*
463+
* Return:
464+
* A value of zero on success, a negative errno in error cases.
465+
*/
466+
static int rm3100_regmap_bulk_read_locked(struct rm3100_data *data, unsigned int reg,
467+
void *val, size_t val_count)
468+
{
469+
guard(mutex)(&data->lock);
470+
return regmap_bulk_read(data->regmap, reg, val, val_count);
471+
}
472+
461473
static irqreturn_t rm3100_trigger_handler(int irq, void *p)
462474
{
463475
struct iio_poll_func *pf = p;
464476
struct iio_dev *indio_dev = pf->indio_dev;
465477
unsigned long scan_mask = *indio_dev->active_scan_mask;
466478
unsigned int mask_len = iio_get_masklength(indio_dev);
467479
struct rm3100_data *data = iio_priv(indio_dev);
468-
struct regmap *regmap = data->regmap;
469480
int ret, i, bit;
470481

471-
mutex_lock(&data->lock);
472482
switch (scan_mask) {
473483
case BIT(0) | BIT(1) | BIT(2):
474-
ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9);
475-
mutex_unlock(&data->lock);
484+
ret = rm3100_regmap_bulk_read_locked(data, RM3100_REG_MX2,
485+
data->buffer, 9);
476486
if (ret < 0)
477487
goto done;
478488
/* Convert XXXYYYZZZxxx to XXXxYYYxZZZx. x for paddings. */
479489
for (i = 2; i > 0; i--)
480490
memmove(data->buffer + i * 4, data->buffer + i * 3, 3);
481491
break;
482492
case BIT(0) | BIT(1):
483-
ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 6);
484-
mutex_unlock(&data->lock);
493+
ret = rm3100_regmap_bulk_read_locked(data, RM3100_REG_MX2,
494+
data->buffer, 6);
485495
if (ret < 0)
486496
goto done;
487497
memmove(data->buffer + 4, data->buffer + 3, 3);
488498
break;
489499
case BIT(1) | BIT(2):
490-
ret = regmap_bulk_read(regmap, RM3100_REG_MY2, data->buffer, 6);
491-
mutex_unlock(&data->lock);
500+
ret = rm3100_regmap_bulk_read_locked(data, RM3100_REG_MY2,
501+
data->buffer, 6);
492502
if (ret < 0)
493503
goto done;
494504
memmove(data->buffer + 4, data->buffer + 3, 3);
495505
break;
496506
case BIT(0) | BIT(2):
497-
ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9);
498-
mutex_unlock(&data->lock);
507+
ret = rm3100_regmap_bulk_read_locked(data, RM3100_REG_MX2,
508+
data->buffer, 9);
499509
if (ret < 0)
500510
goto done;
501511
memmove(data->buffer + 4, data->buffer + 6, 3);
502512
break;
503513
default:
504514
for_each_set_bit(bit, &scan_mask, mask_len) {
505-
ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * bit,
506-
data->buffer, 3);
507-
if (ret < 0) {
508-
mutex_unlock(&data->lock);
515+
ret = rm3100_regmap_bulk_read_locked(data,
516+
RM3100_REG_MX2 + 3 * bit,
517+
data->buffer, 3);
518+
if (ret < 0)
509519
goto done;
510-
}
511520
}
512-
mutex_unlock(&data->lock);
513521
}
514522
/*
515523
* Always using the same buffer so that we wouldn't need to set the

0 commit comments

Comments
 (0)