@@ -3143,6 +3143,8 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
3143
3143
static int gpio_chip_get_multiple (struct gpio_chip * gc ,
3144
3144
unsigned long * mask , unsigned long * bits )
3145
3145
{
3146
+ lockdep_assert_held (& gc -> gpiodev -> srcu );
3147
+
3146
3148
if (gc -> get_multiple )
3147
3149
return gc -> get_multiple (gc , mask , bits );
3148
3150
if (gc -> get ) {
@@ -3173,6 +3175,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
3173
3175
struct gpio_array * array_info ,
3174
3176
unsigned long * value_bitmap )
3175
3177
{
3178
+ struct gpio_chip * gc ;
3176
3179
int ret , i = 0 ;
3177
3180
3178
3181
/*
@@ -3184,10 +3187,15 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
3184
3187
array_size <= array_info -> size &&
3185
3188
(void * )array_info == desc_array + array_info -> size ) {
3186
3189
if (!can_sleep )
3187
- WARN_ON (array_info -> chip -> can_sleep );
3190
+ WARN_ON (array_info -> gdev -> can_sleep );
3191
+
3192
+ guard (srcu )(& array_info -> gdev -> srcu );
3193
+ gc = srcu_dereference (array_info -> gdev -> chip ,
3194
+ & array_info -> gdev -> srcu );
3195
+ if (!gc )
3196
+ return - ENODEV ;
3188
3197
3189
- ret = gpio_chip_get_multiple (array_info -> chip ,
3190
- array_info -> get_mask ,
3198
+ ret = gpio_chip_get_multiple (gc , array_info -> get_mask ,
3191
3199
value_bitmap );
3192
3200
if (ret )
3193
3201
return ret ;
@@ -3468,6 +3476,8 @@ static void gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
3468
3476
static void gpio_chip_set_multiple (struct gpio_chip * gc ,
3469
3477
unsigned long * mask , unsigned long * bits )
3470
3478
{
3479
+ lockdep_assert_held (& gc -> gpiodev -> srcu );
3480
+
3471
3481
if (gc -> set_multiple ) {
3472
3482
gc -> set_multiple (gc , mask , bits );
3473
3483
} else {
@@ -3485,6 +3495,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
3485
3495
struct gpio_array * array_info ,
3486
3496
unsigned long * value_bitmap )
3487
3497
{
3498
+ struct gpio_chip * gc ;
3488
3499
int i = 0 ;
3489
3500
3490
3501
/*
@@ -3496,14 +3507,19 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
3496
3507
array_size <= array_info -> size &&
3497
3508
(void * )array_info == desc_array + array_info -> size ) {
3498
3509
if (!can_sleep )
3499
- WARN_ON (array_info -> chip -> can_sleep );
3510
+ WARN_ON (array_info -> gdev -> can_sleep );
3511
+
3512
+ guard (srcu )(& array_info -> gdev -> srcu );
3513
+ gc = srcu_dereference (array_info -> gdev -> chip ,
3514
+ & array_info -> gdev -> srcu );
3515
+ if (!gc )
3516
+ return - ENODEV ;
3500
3517
3501
3518
if (!raw && !bitmap_empty (array_info -> invert_mask , array_size ))
3502
3519
bitmap_xor (value_bitmap , value_bitmap ,
3503
3520
array_info -> invert_mask , array_size );
3504
3521
3505
- gpio_chip_set_multiple (array_info -> chip , array_info -> set_mask ,
3506
- value_bitmap );
3522
+ gpio_chip_set_multiple (gc , array_info -> set_mask , value_bitmap );
3507
3523
3508
3524
i = find_first_zero_bit (array_info -> set_mask , array_size );
3509
3525
if (i == array_size )
@@ -4765,9 +4781,10 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4765
4781
{
4766
4782
struct gpio_desc * desc ;
4767
4783
struct gpio_descs * descs ;
4784
+ struct gpio_device * gdev ;
4768
4785
struct gpio_array * array_info = NULL ;
4769
- struct gpio_chip * gc ;
4770
4786
int count , bitmap_size ;
4787
+ unsigned long dflags ;
4771
4788
size_t descs_size ;
4772
4789
4773
4790
count = gpiod_count (dev , con_id );
@@ -4788,16 +4805,16 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4788
4805
4789
4806
descs -> desc [descs -> ndescs ] = desc ;
4790
4807
4791
- gc = gpiod_to_chip (desc );
4808
+ gdev = gpiod_to_gpio_device (desc );
4792
4809
/*
4793
4810
* If pin hardware number of array member 0 is also 0, select
4794
4811
* its chip as a candidate for fast bitmap processing path.
4795
4812
*/
4796
4813
if (descs -> ndescs == 0 && gpio_chip_hwgpio (desc ) == 0 ) {
4797
4814
struct gpio_descs * array ;
4798
4815
4799
- bitmap_size = BITS_TO_LONGS (gc -> ngpio > count ?
4800
- gc -> ngpio : count );
4816
+ bitmap_size = BITS_TO_LONGS (gdev -> ngpio > count ?
4817
+ gdev -> ngpio : count );
4801
4818
4802
4819
array = krealloc (descs , descs_size +
4803
4820
struct_size (array_info , invert_mask , 3 * bitmap_size ),
@@ -4817,7 +4834,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4817
4834
4818
4835
array_info -> desc = descs -> desc ;
4819
4836
array_info -> size = count ;
4820
- array_info -> chip = gc ;
4837
+ array_info -> gdev = gdev ;
4821
4838
bitmap_set (array_info -> get_mask , descs -> ndescs ,
4822
4839
count - descs -> ndescs );
4823
4840
bitmap_set (array_info -> set_mask , descs -> ndescs ,
@@ -4830,7 +4847,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4830
4847
continue ;
4831
4848
4832
4849
/* Unmark array members which don't belong to the 'fast' chip */
4833
- if (array_info -> chip != gc ) {
4850
+ if (array_info -> gdev != gdev ) {
4834
4851
__clear_bit (descs -> ndescs , array_info -> get_mask );
4835
4852
__clear_bit (descs -> ndescs , array_info -> set_mask );
4836
4853
}
@@ -4853,9 +4870,10 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4853
4870
array_info -> set_mask );
4854
4871
}
4855
4872
} else {
4873
+ dflags = READ_ONCE (desc -> flags );
4856
4874
/* Exclude open drain or open source from fast output */
4857
- if (gpiochip_line_is_open_drain ( gc , descs -> ndescs ) ||
4858
- gpiochip_line_is_open_source ( gc , descs -> ndescs ))
4875
+ if (test_bit ( FLAG_OPEN_DRAIN , & dflags ) ||
4876
+ test_bit ( FLAG_OPEN_SOURCE , & dflags ))
4859
4877
__clear_bit (descs -> ndescs ,
4860
4878
array_info -> set_mask );
4861
4879
/* Identify 'fast' pins which require invertion */
@@ -4867,7 +4885,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
4867
4885
if (array_info )
4868
4886
dev_dbg (dev ,
4869
4887
"GPIO array info: chip=%s, size=%d, get_mask=%lx, set_mask=%lx, invert_mask=%lx\n" ,
4870
- array_info -> chip -> label , array_info -> size ,
4888
+ array_info -> gdev -> label , array_info -> size ,
4871
4889
* array_info -> get_mask , * array_info -> set_mask ,
4872
4890
* array_info -> invert_mask );
4873
4891
return descs ;
0 commit comments