@@ -3143,6 +3143,8 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
31433143static int gpio_chip_get_multiple (struct gpio_chip * gc ,
31443144 unsigned long * mask , unsigned long * bits )
31453145{
3146+ lockdep_assert_held (& gc -> gpiodev -> srcu );
3147+
31463148 if (gc -> get_multiple )
31473149 return gc -> get_multiple (gc , mask , bits );
31483150 if (gc -> get ) {
@@ -3173,6 +3175,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
31733175 struct gpio_array * array_info ,
31743176 unsigned long * value_bitmap )
31753177{
3178+ struct gpio_chip * gc ;
31763179 int ret , i = 0 ;
31773180
31783181 /*
@@ -3184,10 +3187,15 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
31843187 array_size <= array_info -> size &&
31853188 (void * )array_info == desc_array + array_info -> size ) {
31863189 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 ;
31883197
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 ,
31913199 value_bitmap );
31923200 if (ret )
31933201 return ret ;
@@ -3468,6 +3476,8 @@ static void gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
34683476static void gpio_chip_set_multiple (struct gpio_chip * gc ,
34693477 unsigned long * mask , unsigned long * bits )
34703478{
3479+ lockdep_assert_held (& gc -> gpiodev -> srcu );
3480+
34713481 if (gc -> set_multiple ) {
34723482 gc -> set_multiple (gc , mask , bits );
34733483 } else {
@@ -3485,6 +3495,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
34853495 struct gpio_array * array_info ,
34863496 unsigned long * value_bitmap )
34873497{
3498+ struct gpio_chip * gc ;
34883499 int i = 0 ;
34893500
34903501 /*
@@ -3496,14 +3507,19 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
34963507 array_size <= array_info -> size &&
34973508 (void * )array_info == desc_array + array_info -> size ) {
34983509 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 ;
35003517
35013518 if (!raw && !bitmap_empty (array_info -> invert_mask , array_size ))
35023519 bitmap_xor (value_bitmap , value_bitmap ,
35033520 array_info -> invert_mask , array_size );
35043521
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 );
35073523
35083524 i = find_first_zero_bit (array_info -> set_mask , array_size );
35093525 if (i == array_size )
@@ -4765,9 +4781,10 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
47654781{
47664782 struct gpio_desc * desc ;
47674783 struct gpio_descs * descs ;
4784+ struct gpio_device * gdev ;
47684785 struct gpio_array * array_info = NULL ;
4769- struct gpio_chip * gc ;
47704786 int count , bitmap_size ;
4787+ unsigned long dflags ;
47714788 size_t descs_size ;
47724789
47734790 count = gpiod_count (dev , con_id );
@@ -4788,16 +4805,16 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
47884805
47894806 descs -> desc [descs -> ndescs ] = desc ;
47904807
4791- gc = gpiod_to_chip (desc );
4808+ gdev = gpiod_to_gpio_device (desc );
47924809 /*
47934810 * If pin hardware number of array member 0 is also 0, select
47944811 * its chip as a candidate for fast bitmap processing path.
47954812 */
47964813 if (descs -> ndescs == 0 && gpio_chip_hwgpio (desc ) == 0 ) {
47974814 struct gpio_descs * array ;
47984815
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 );
48014818
48024819 array = krealloc (descs , descs_size +
48034820 struct_size (array_info , invert_mask , 3 * bitmap_size ),
@@ -4817,7 +4834,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
48174834
48184835 array_info -> desc = descs -> desc ;
48194836 array_info -> size = count ;
4820- array_info -> chip = gc ;
4837+ array_info -> gdev = gdev ;
48214838 bitmap_set (array_info -> get_mask , descs -> ndescs ,
48224839 count - descs -> ndescs );
48234840 bitmap_set (array_info -> set_mask , descs -> ndescs ,
@@ -4830,7 +4847,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
48304847 continue ;
48314848
48324849 /* Unmark array members which don't belong to the 'fast' chip */
4833- if (array_info -> chip != gc ) {
4850+ if (array_info -> gdev != gdev ) {
48344851 __clear_bit (descs -> ndescs , array_info -> get_mask );
48354852 __clear_bit (descs -> ndescs , array_info -> set_mask );
48364853 }
@@ -4853,9 +4870,10 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
48534870 array_info -> set_mask );
48544871 }
48554872 } else {
4873+ dflags = READ_ONCE (desc -> flags );
48564874 /* 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 ))
48594877 __clear_bit (descs -> ndescs ,
48604878 array_info -> set_mask );
48614879 /* Identify 'fast' pins which require invertion */
@@ -4867,7 +4885,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
48674885 if (array_info )
48684886 dev_dbg (dev ,
48694887 "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 ,
48714889 * array_info -> get_mask , * array_info -> set_mask ,
48724890 * array_info -> invert_mask );
48734891 return descs ;
0 commit comments