@@ -147,10 +147,24 @@ struct bmc150_accel_chip_info {
147
147
const struct bmc150_scale_info scale_table [4 ];
148
148
};
149
149
150
+ struct bmc150_accel_interrupt {
151
+ const struct bmc150_accel_interrupt_info * info ;
152
+ atomic_t users ;
153
+ };
154
+
155
+ enum bmc150_accel_interrupt_id {
156
+ BMC150_ACCEL_INT_DATA_READY ,
157
+ BMC150_ACCEL_INT_ANY_MOTION ,
158
+ BMC150_ACCEL_INT_WATERMARK ,
159
+ BMC150_ACCEL_INTERRUPTS ,
160
+ };
161
+
150
162
struct bmc150_accel_data {
151
163
struct i2c_client * client ;
164
+ struct bmc150_accel_interrupt interrupts [BMC150_ACCEL_INTERRUPTS ];
152
165
struct iio_trigger * dready_trig ;
153
166
struct iio_trigger * motion_trig ;
167
+ atomic_t active_intr ;
154
168
struct mutex mutex ;
155
169
s16 buffer [8 ];
156
170
u8 bw_bits ;
@@ -421,7 +435,7 @@ static const struct bmc150_accel_interrupt_info {
421
435
u8 map_bitmask ;
422
436
u8 en_reg ;
423
437
u8 en_bitmask ;
424
- } bmc150_accel_interrupts [] = {
438
+ } bmc150_accel_interrupts [BMC150_ACCEL_INTERRUPTS ] = {
425
439
{ /* data ready interrupt */
426
440
.map_reg = BMC150_ACCEL_REG_INT_MAP_1 ,
427
441
.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA ,
@@ -438,12 +452,30 @@ static const struct bmc150_accel_interrupt_info {
438
452
},
439
453
};
440
454
441
- static int bmc150_accel_set_interrupt (struct bmc150_accel_data * data ,
442
- const struct bmc150_accel_interrupt_info * info ,
455
+ static void bmc150_accel_interrupts_setup (struct iio_dev * indio_dev ,
456
+ struct bmc150_accel_data * data )
457
+ {
458
+ int i ;
459
+
460
+ for (i = 0 ; i < BMC150_ACCEL_INTERRUPTS ; i ++ )
461
+ data -> interrupts [i ].info = & bmc150_accel_interrupts [i ];
462
+ }
463
+
464
+ static int bmc150_accel_set_interrupt (struct bmc150_accel_data * data , int i ,
443
465
bool state )
444
466
{
467
+ struct bmc150_accel_interrupt * intr = & data -> interrupts [i ];
468
+ const struct bmc150_accel_interrupt_info * info = intr -> info ;
445
469
int ret ;
446
470
471
+ if (state ) {
472
+ if (atomic_inc_return (& intr -> users ) > 1 )
473
+ return 0 ;
474
+ } else {
475
+ if (atomic_dec_return (& intr -> users ) > 0 )
476
+ return 0 ;
477
+ }
478
+
447
479
/*
448
480
* We will expect the enable and disable to do operation in
449
481
* in reverse order. This will happen here anyway as our
@@ -493,27 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data,
493
525
goto out_fix_power_state ;
494
526
}
495
527
528
+ if (state )
529
+ atomic_inc (& data -> active_intr );
530
+ else
531
+ atomic_dec (& data -> active_intr );
532
+
496
533
return 0 ;
497
534
498
535
out_fix_power_state :
499
536
bmc150_accel_set_power_state (data , false);
500
537
return ret ;
501
538
}
502
539
503
- static int bmc150_accel_setup_any_motion_interrupt (
504
- struct bmc150_accel_data * data ,
505
- bool status )
506
- {
507
- return bmc150_accel_set_interrupt (data , & bmc150_accel_interrupts [1 ],
508
- status );
509
- }
510
-
511
- static int bmc150_accel_setup_new_data_interrupt (struct bmc150_accel_data * data ,
512
- bool status )
513
- {
514
- return bmc150_accel_set_interrupt (data , & bmc150_accel_interrupts [0 ],
515
- status );
516
- }
517
540
518
541
static int bmc150_accel_set_scale (struct bmc150_accel_data * data , int val )
519
542
{
@@ -753,13 +776,8 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
753
776
754
777
mutex_lock (& data -> mutex );
755
778
756
- if (!state && data -> motion_trigger_on ) {
757
- data -> ev_enable_state = 0 ;
758
- mutex_unlock (& data -> mutex );
759
- return 0 ;
760
- }
761
-
762
- ret = bmc150_accel_setup_any_motion_interrupt (data , state );
779
+ ret = bmc150_accel_set_interrupt (data , BMC150_ACCEL_INT_ANY_MOTION ,
780
+ state );
763
781
if (ret < 0 ) {
764
782
mutex_unlock (& data -> mutex );
765
783
return ret ;
@@ -996,19 +1014,16 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig,
996
1014
}
997
1015
}
998
1016
999
- if (!state && data -> ev_enable_state && data -> motion_trigger_on ) {
1000
- data -> motion_trigger_on = false;
1001
- mutex_unlock (& data -> mutex );
1002
- return 0 ;
1003
- }
1004
-
1005
1017
if (data -> motion_trig == trig ) {
1006
1018
ret = bmc150_accel_update_slope (data );
1007
1019
if (!ret )
1008
- ret = bmc150_accel_setup_any_motion_interrupt (data ,
1009
- state );
1020
+ ret = bmc150_accel_set_interrupt (data ,
1021
+ BMC150_ACCEL_INT_ANY_MOTION ,
1022
+ state );
1010
1023
} else {
1011
- ret = bmc150_accel_setup_new_data_interrupt (data , state );
1024
+ ret = bmc150_accel_set_interrupt (data ,
1025
+ BMC150_ACCEL_INT_DATA_READY ,
1026
+ state );
1012
1027
}
1013
1028
if (ret < 0 ) {
1014
1029
mutex_unlock (& data -> mutex );
@@ -1206,6 +1221,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
1206
1221
return ret ;
1207
1222
}
1208
1223
1224
+ bmc150_accel_interrupts_setup (indio_dev , data );
1225
+
1209
1226
data -> dready_trig = devm_iio_trigger_alloc (& client -> dev ,
1210
1227
"%s-dev%d" ,
1211
1228
indio_dev -> name ,
@@ -1321,8 +1338,7 @@ static int bmc150_accel_resume(struct device *dev)
1321
1338
struct bmc150_accel_data * data = iio_priv (indio_dev );
1322
1339
1323
1340
mutex_lock (& data -> mutex );
1324
- if (data -> dready_trigger_on || data -> motion_trigger_on ||
1325
- data -> ev_enable_state )
1341
+ if (atomic_read (& data -> active_intr ))
1326
1342
bmc150_accel_set_mode (data , BMC150_ACCEL_SLEEP_MODE_NORMAL , 0 );
1327
1343
mutex_unlock (& data -> mutex );
1328
1344
0 commit comments