@@ -21,6 +21,7 @@ typedef struct GPIO_CHIP_INSTANCE_
21
21
const GPIO_CHIP_T * chip ;
22
22
const char * name ;
23
23
const char * dtnode ;
24
+ int mem_fd ;
24
25
void * priv ;
25
26
uint64_t phys_addr ;
26
27
unsigned num_gpios ;
@@ -409,6 +410,7 @@ int gpiolib_init(void)
409
410
const GPIO_CHIP_T * chip ;
410
411
GPIO_CHIP_INSTANCE_T * inst ;
411
412
char pathbuf [FILENAME_MAX ];
413
+ char gpiomem_idx [4 ];
412
414
const char * dtpath = "/proc/device-tree" ;
413
415
const char * p ;
414
416
char * alias = NULL , * names , * end , * compatible ;
@@ -442,10 +444,12 @@ int gpiolib_init(void)
442
444
for (i = 0 ; ; i ++ )
443
445
{
444
446
sprintf (pathbuf , "gpio%d" , i );
447
+ sprintf (gpiomem_idx , "%d" , i );
445
448
alias = dt_read_prop ("/aliases" , pathbuf , NULL );
446
449
if (!alias && i == 0 )
447
450
{
448
451
alias = dt_read_prop ("/aliases" , "gpio" , NULL );
452
+ gpiomem_idx [0 ] = 0 ;
449
453
}
450
454
if (!alias )
451
455
break ;
@@ -481,6 +485,8 @@ int gpiolib_init(void)
481
485
return -1 ;
482
486
}
483
487
488
+ sprintf (pathbuf , "/dev/gpiomem%s" , gpiomem_idx );
489
+ inst -> mem_fd = open (pathbuf , O_RDWR |O_SYNC );
484
490
}
485
491
486
492
gpio_base = 0 ;
@@ -636,12 +642,10 @@ int gpiolib_init_by_name(const char *name)
636
642
637
643
int gpiolib_mmap (void )
638
644
{
639
- int mem_fd ;
645
+ int pagesize = getpagesize ();
646
+ int mem_fd = -1 ;
640
647
unsigned i ;
641
648
642
- if ((mem_fd = open ("/dev/mem" , O_RDWR |O_SYNC ) ) < 0 )
643
- return errno ;
644
-
645
649
for (i = 0 ; i < num_gpio_chips ; i ++ )
646
650
{
647
651
GPIO_CHIP_INSTANCE_T * inst ;
@@ -653,21 +657,39 @@ int gpiolib_mmap(void)
653
657
inst = & gpio_chips [i ];
654
658
chip = inst -> chip ;
655
659
656
- align = inst -> phys_addr & 0xffff ;
657
- gpio_map = mmap (
658
- NULL , /* Any address in our space will do */
659
- chip -> size + align , /* Map length */
660
- PROT_READ | PROT_WRITE , /* Enable reading & writing */
661
- MAP_SHARED , /* Shared with other processes */
662
- mem_fd , /* File to map */
663
- inst -> phys_addr - align /* Offset to GPIO peripheral */
664
- );
660
+ align = inst -> phys_addr & (pagesize - 1 );
665
661
666
- if (gpio_map == MAP_FAILED )
662
+ if (inst -> mem_fd >= 0 )
667
663
{
668
- close (mem_fd );
669
- return errno ;
664
+ gpio_map = mmap (
665
+ NULL , /* Any address in our space will do */
666
+ chip -> size + align , /* Map length */
667
+ PROT_READ | PROT_WRITE , /* Enable reading & writing */
668
+ MAP_SHARED , /* Shared with other processes */
669
+ inst -> mem_fd , /* File to map */
670
+ 0 /* Offset to GPIO peripheral */
671
+ );
670
672
}
673
+ else
674
+ {
675
+ if (mem_fd < 0 )
676
+ {
677
+ mem_fd = open ("/dev/mem" , O_RDWR |O_SYNC );
678
+ if (mem_fd < 0 )
679
+ return errno ;
680
+ }
681
+ gpio_map = mmap (
682
+ NULL , /* Any address in our space will do */
683
+ chip -> size + align , /* Map length */
684
+ PROT_READ | PROT_WRITE , /* Enable reading & writing */
685
+ MAP_SHARED , /* Shared with other processes */
686
+ mem_fd , /* File to map */
687
+ inst -> phys_addr - align /* Offset to GPIO peripheral */
688
+ );
689
+ }
690
+
691
+ if (gpio_map == MAP_FAILED )
692
+ return errno ;
671
693
672
694
new_priv = chip -> interface -> gpio_probe_instance (inst -> priv ,
673
695
(void * )((char * )gpio_map + align ));
0 commit comments