Skip to content

Commit 469ad4d

Browse files
rfflrtjic23
authored andcommitted
iio: light: vcnl4000: use lock guard()
Use guard() and scoped_guard() for handling mutex lock instead of manually locking and unlocking. Remove gotos in error handling logic. This prevents forgotten locks on early exits. Signed-off-by: Raffael Raiel Trindade <raffaelraiel@usp.br> Co-developed-by: Kim Carvalho <kim.ca@usp.br> Signed-off-by: Kim Carvalho <kim.ca@usp.br> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
1 parent 29bf269 commit 469ad4d

1 file changed

Lines changed: 45 additions & 107 deletions

File tree

drivers/iio/light/vcnl4000.c

Lines changed: 45 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include <linux/bitfield.h>
21+
#include <linux/cleanup.h>
2122
#include <linux/delay.h>
2223
#include <linux/err.h>
2324
#include <linux/i2c.h>
@@ -268,46 +269,36 @@ static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
268269
{
269270
int ret;
270271

271-
mutex_lock(&data->vcnl4000_lock);
272+
guard(mutex)(&data->vcnl4000_lock);
272273

273274
ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
274275
if (ret < 0)
275-
goto out;
276+
return ret;
276277

277278
if (en)
278279
ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN;
279280
else
280281
ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN;
281282

282-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
283-
284-
out:
285-
mutex_unlock(&data->vcnl4000_lock);
286-
287-
return ret;
283+
return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
288284
}
289285

290286
static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en)
291287
{
292288
int ret;
293289

294-
mutex_lock(&data->vcnl4000_lock);
290+
guard(mutex)(&data->vcnl4000_lock);
295291

296292
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
297293
if (ret < 0)
298-
goto out;
294+
return ret;
299295

300296
if (en)
301297
ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN;
302298
else
303299
ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN;
304300

305-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
306-
307-
out:
308-
mutex_unlock(&data->vcnl4000_lock);
309-
310-
return ret;
301+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
311302
}
312303

313304
static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
@@ -442,18 +433,18 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
442433
int tries = 20;
443434
int ret;
444435

445-
mutex_lock(&data->vcnl4000_lock);
436+
guard(mutex)(&data->vcnl4000_lock);
446437

447438
ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
448439
req_mask);
449440
if (ret < 0)
450-
goto fail;
441+
return ret;
451442

452443
/* wait for data to become ready */
453444
while (tries--) {
454445
ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
455446
if (ret < 0)
456-
goto fail;
447+
return ret;
457448
if (ret & rdy_mask)
458449
break;
459450
msleep(20); /* measurement takes up to 100 ms */
@@ -462,21 +453,10 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
462453
if (tries < 0) {
463454
dev_err(&data->client->dev,
464455
"vcnl4000_measure() failed, data not ready\n");
465-
ret = -EIO;
466-
goto fail;
456+
return -EIO;
467457
}
468458

469-
ret = vcnl4000_read_data(data, data_reg, val);
470-
if (ret < 0)
471-
goto fail;
472-
473-
mutex_unlock(&data->vcnl4000_lock);
474-
475-
return 0;
476-
477-
fail:
478-
mutex_unlock(&data->vcnl4000_lock);
479-
return ret;
459+
return vcnl4000_read_data(data, data_reg, val);
480460
}
481461

482462
static int vcnl4200_measure(struct vcnl4000_data *data,
@@ -486,16 +466,14 @@ static int vcnl4200_measure(struct vcnl4000_data *data,
486466
s64 delta;
487467
ktime_t next_measurement;
488468

489-
mutex_lock(&chan->lock);
490-
491-
next_measurement = ktime_add(chan->last_measurement,
492-
chan->sampling_rate);
493-
delta = ktime_us_delta(next_measurement, ktime_get());
494-
if (delta > 0)
495-
usleep_range(delta, delta + 500);
496-
chan->last_measurement = ktime_get();
497-
498-
mutex_unlock(&chan->lock);
469+
scoped_guard(mutex, &chan->lock) {
470+
next_measurement = ktime_add(chan->last_measurement,
471+
chan->sampling_rate);
472+
delta = ktime_us_delta(next_measurement, ktime_get());
473+
if (delta > 0)
474+
usleep_range(delta, delta + 500);
475+
chan->last_measurement = ktime_get();
476+
}
499477

500478
ret = i2c_smbus_read_word_data(data->client, chan->reg);
501479
if (ret < 0)
@@ -606,21 +584,15 @@ static ssize_t vcnl4040_write_als_it(struct vcnl4000_data *data, int val)
606584
(*data->chip_spec->als_it_times)[0][1]),
607585
val);
608586

609-
mutex_lock(&data->vcnl4000_lock);
587+
guard(mutex)(&data->vcnl4000_lock);
610588

611589
ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
612590
if (ret < 0)
613-
goto out_unlock;
591+
return ret;
614592

615593
regval = FIELD_PREP(VCNL4040_ALS_CONF_IT, i);
616594
regval |= (ret & ~VCNL4040_ALS_CONF_IT);
617-
ret = i2c_smbus_write_word_data(data->client,
618-
VCNL4200_AL_CONF,
619-
regval);
620-
621-
out_unlock:
622-
mutex_unlock(&data->vcnl4000_lock);
623-
return ret;
595+
return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval);
624596
}
625597

626598
static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2)
@@ -660,20 +632,15 @@ static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val)
660632

661633
data->vcnl4200_ps.sampling_rate = ktime_set(0, val * 60 * NSEC_PER_USEC);
662634

663-
mutex_lock(&data->vcnl4000_lock);
635+
guard(mutex)(&data->vcnl4000_lock);
664636

665637
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
666638
if (ret < 0)
667-
goto out;
639+
return ret;
668640

669641
regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) |
670642
FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index);
671-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
672-
regval);
673-
674-
out:
675-
mutex_unlock(&data->vcnl4000_lock);
676-
return ret;
643+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval);
677644
}
678645

679646
static ssize_t vcnl4040_read_als_period(struct vcnl4000_data *data, int *val, int *val2)
@@ -721,20 +688,15 @@ static ssize_t vcnl4040_write_als_period(struct vcnl4000_data *data, int val, in
721688
break;
722689
}
723690

724-
mutex_lock(&data->vcnl4000_lock);
691+
guard(mutex)(&data->vcnl4000_lock);
725692

726693
ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
727694
if (ret < 0)
728-
goto out_unlock;
695+
return ret;
729696

730697
regval = FIELD_PREP(VCNL4040_ALS_CONF_PERS, i);
731698
regval |= (ret & ~VCNL4040_ALS_CONF_PERS);
732-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
733-
regval);
734-
735-
out_unlock:
736-
mutex_unlock(&data->vcnl4000_lock);
737-
return ret;
699+
return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval);
738700
}
739701

740702
static ssize_t vcnl4040_read_ps_period(struct vcnl4000_data *data, int *val, int *val2)
@@ -783,20 +745,15 @@ static ssize_t vcnl4040_write_ps_period(struct vcnl4000_data *data, int val, int
783745
}
784746
}
785747

786-
mutex_lock(&data->vcnl4000_lock);
748+
guard(mutex)(&data->vcnl4000_lock);
787749

788750
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
789751
if (ret < 0)
790-
goto out_unlock;
752+
return ret;
791753

792754
regval = FIELD_PREP(VCNL4040_CONF1_PS_PERS, i);
793755
regval |= (ret & ~VCNL4040_CONF1_PS_PERS);
794-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
795-
regval);
796-
797-
out_unlock:
798-
mutex_unlock(&data->vcnl4000_lock);
799-
return ret;
756+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval);
800757
}
801758

802759
static ssize_t vcnl4040_read_ps_oversampling_ratio(struct vcnl4000_data *data, int *val)
@@ -830,20 +787,15 @@ static ssize_t vcnl4040_write_ps_oversampling_ratio(struct vcnl4000_data *data,
830787
if (i >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
831788
return -EINVAL;
832789

833-
mutex_lock(&data->vcnl4000_lock);
790+
guard(mutex)(&data->vcnl4000_lock);
834791

835792
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
836793
if (ret < 0)
837-
goto out_unlock;
794+
return ret;
838795

839796
regval = FIELD_PREP(VCNL4040_PS_CONF3_MPS, i);
840797
regval |= (ret & ~VCNL4040_PS_CONF3_MPS);
841-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
842-
regval);
843-
844-
out_unlock:
845-
mutex_unlock(&data->vcnl4000_lock);
846-
return ret;
798+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval);
847799
}
848800

849801
static ssize_t vcnl4040_read_ps_calibbias(struct vcnl4000_data *data, int *val, int *val2)
@@ -878,20 +830,15 @@ static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val)
878830
if (i >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
879831
return -EINVAL;
880832

881-
mutex_lock(&data->vcnl4000_lock);
833+
guard(mutex)(&data->vcnl4000_lock);
882834

883835
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
884836
if (ret < 0)
885-
goto out_unlock;
837+
return ret;
886838

887839
regval = (ret & ~VCNL4040_PS_MS_LED_I);
888840
regval |= FIELD_PREP(VCNL4040_PS_MS_LED_I, i);
889-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
890-
regval);
891-
892-
out_unlock:
893-
mutex_unlock(&data->vcnl4000_lock);
894-
return ret;
841+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval);
895842
}
896843

897844
static int vcnl4000_read_raw(struct iio_dev *indio_dev,
@@ -1476,17 +1423,17 @@ static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
14761423
enum iio_event_direction dir,
14771424
bool state)
14781425
{
1479-
int ret = -EINVAL;
1426+
int ret;
14801427
u16 val, mask;
14811428
struct vcnl4000_data *data = iio_priv(indio_dev);
14821429

1483-
mutex_lock(&data->vcnl4000_lock);
1430+
guard(mutex)(&data->vcnl4000_lock);
14841431

14851432
switch (chan->type) {
14861433
case IIO_LIGHT:
14871434
ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
14881435
if (ret < 0)
1489-
goto out;
1436+
return ret;
14901437

14911438
mask = VCNL4040_ALS_CONF_INT_EN;
14921439
if (state)
@@ -1495,13 +1442,11 @@ static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
14951442
val = (ret & ~mask);
14961443

14971444
data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, val);
1498-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
1499-
val);
1500-
break;
1445+
return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val);
15011446
case IIO_PROXIMITY:
15021447
ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
15031448
if (ret < 0)
1504-
goto out;
1449+
return ret;
15051450

15061451
if (dir == IIO_EV_DIR_RISING)
15071452
mask = VCNL4040_PS_IF_AWAY;
@@ -1511,17 +1456,10 @@ static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
15111456
val = state ? (ret | mask) : (ret & ~mask);
15121457

15131458
data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val);
1514-
ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
1515-
val);
1516-
break;
1459+
return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val);
15171460
default:
1518-
break;
1461+
return -EINVAL;
15191462
}
1520-
1521-
out:
1522-
mutex_unlock(&data->vcnl4000_lock);
1523-
1524-
return ret;
15251463
}
15261464

15271465
static irqreturn_t vcnl4040_irq_thread(int irq, void *p)

0 commit comments

Comments
 (0)