@@ -356,12 +356,44 @@ static ssize_t gpio_active_low_store(struct device *dev,
356
356
static DEVICE_ATTR (active_low , 0644 ,
357
357
gpio_active_low_show , gpio_active_low_store ) ;
358
358
359
+ static umode_t gpio_is_visible (struct kobject * kobj , struct attribute * attr ,
360
+ int n )
361
+ {
362
+ struct device * dev = container_of (kobj , struct device , kobj );
363
+ struct gpio_desc * desc = dev_get_drvdata (dev );
364
+ umode_t mode = attr -> mode ;
365
+ bool show_direction = test_bit (FLAG_SYSFS_DIR , & desc -> flags );
366
+
367
+ if (attr == & dev_attr_direction .attr ) {
368
+ if (!show_direction )
369
+ mode = 0 ;
370
+ } else if (attr == & dev_attr_edge .attr ) {
371
+ if (gpiod_to_irq (desc ) < 0 )
372
+ mode = 0 ;
373
+ if (!show_direction && test_bit (FLAG_IS_OUT , & desc -> flags ))
374
+ mode = 0 ;
375
+ }
376
+
377
+ return mode ;
378
+ }
379
+
359
380
static struct attribute * gpio_attrs [] = {
381
+ & dev_attr_direction .attr ,
382
+ & dev_attr_edge .attr ,
360
383
& dev_attr_value .attr ,
361
384
& dev_attr_active_low .attr ,
362
385
NULL ,
363
386
};
364
- ATTRIBUTE_GROUPS (gpio );
387
+
388
+ static const struct attribute_group gpio_group = {
389
+ .attrs = gpio_attrs ,
390
+ .is_visible = gpio_is_visible ,
391
+ };
392
+
393
+ static const struct attribute_group * gpio_groups [] = {
394
+ & gpio_group ,
395
+ NULL
396
+ };
365
397
366
398
/*
367
399
* /sys/class/gpio/gpiochipN/
@@ -550,8 +582,11 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
550
582
goto fail_unlock ;
551
583
}
552
584
553
- if (!desc -> chip -> direction_input || !desc -> chip -> direction_output )
554
- direction_may_change = false;
585
+ if (desc -> chip -> direction_input && desc -> chip -> direction_output &&
586
+ direction_may_change ) {
587
+ set_bit (FLAG_SYSFS_DIR , & desc -> flags );
588
+ }
589
+
555
590
spin_unlock_irqrestore (& gpio_lock , flags );
556
591
557
592
offset = gpio_chip_hwgpio (desc );
@@ -567,27 +602,10 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
567
602
goto fail_unlock ;
568
603
}
569
604
570
- if (direction_may_change ) {
571
- status = device_create_file (dev , & dev_attr_direction );
572
- if (status )
573
- goto fail_unregister_device ;
574
- }
575
-
576
- if (gpiod_to_irq (desc ) >= 0 && (direction_may_change ||
577
- !test_bit (FLAG_IS_OUT , & desc -> flags ))) {
578
- status = device_create_file (dev , & dev_attr_edge );
579
- if (status )
580
- goto fail_remove_attr_direction ;
581
- }
582
-
583
605
set_bit (FLAG_EXPORT , & desc -> flags );
584
606
mutex_unlock (& sysfs_lock );
585
607
return 0 ;
586
608
587
- fail_remove_attr_direction :
588
- device_remove_file (dev , & dev_attr_direction );
589
- fail_unregister_device :
590
- device_unregister (dev );
591
609
fail_unlock :
592
610
mutex_unlock (& sysfs_lock );
593
611
gpiod_dbg (desc , "%s: status %d\n" , __func__ , status );
@@ -711,6 +729,7 @@ void gpiod_unexport(struct gpio_desc *desc)
711
729
dev = class_find_device (& gpio_class , NULL , desc , match_export );
712
730
if (dev ) {
713
731
gpio_setup_irq (desc , dev , 0 );
732
+ clear_bit (FLAG_SYSFS_DIR , & desc -> flags );
714
733
clear_bit (FLAG_EXPORT , & desc -> flags );
715
734
} else
716
735
status = - ENODEV ;
@@ -719,8 +738,6 @@ void gpiod_unexport(struct gpio_desc *desc)
719
738
mutex_unlock (& sysfs_lock );
720
739
721
740
if (dev ) {
722
- device_remove_file (dev , & dev_attr_edge );
723
- device_remove_file (dev , & dev_attr_direction );
724
741
device_unregister (dev );
725
742
put_device (dev );
726
743
}
0 commit comments