From 3d495b084c760bc1439ee32201e80391e2641f82 Mon Sep 17 00:00:00 2001 From: Kaspar Giger Date: Sat, 6 Sep 2025 23:07:35 +0200 Subject: [PATCH] sysfs: retain support even on older kernels The ioctl-gpio driver was declared a prerequisite of the sysfs-gpio driver. But since on older Linux kernels (earlier than 5.10) the GPIO v2 interface is not yet available. Therefore, the ioctl-gpio driver is not available for such systems. To still support the sysfs access for those make the ioctl-gpio driver independent of the sysfs-gpio driver. Note: the ioctl-gpio driver is still attempted to load. --- gpioioctl/gpio.go | 11 ++++++++--- sysfs/gpio.go | 4 ++-- sysfs/gpio_test.go | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/gpioioctl/gpio.go b/gpioioctl/gpio.go index c4bbcaad..bd2119a6 100644 --- a/gpioioctl/gpio.go +++ b/gpioioctl/gpio.go @@ -415,7 +415,12 @@ func newGPIOChip(path string) (*GPIOChip, error) { line_info.offset = uint32(line) err := ioctl_gpio_v2_line_info(chip.fd, &line_info) if err != nil { - log.Println("newGPIOChip get line info", err) + // older kernels don't support the GPIO v2 API. In this case the above syscall returns an EINVAL + // error. That's ok, in this case just don't continue accessing this GPIO chip with this interface + // any further. + if err.Error() == "invalid argument" { + return nil, nil + } return nil, fmt.Errorf("reading line info: %w", err) } line := newGPIOLine(uint32(line), string(line_info.name[:]), string(line_info.consumer[:]), chip.fd) @@ -616,9 +621,9 @@ func (d *driverGPIO) Init() (bool, error) { var chip *GPIOChip for _, item := range items { chip, err = newGPIOChip(item) - if err == nil { + if chip != nil && err == nil { chips = append(chips, chip) - } else { + } else if err != nil { log.Println("gpioioctl.driverGPIO.Init() Error", err) } } diff --git a/sysfs/gpio.go b/sysfs/gpio.go index a776ca89..f33341a1 100644 --- a/sysfs/gpio.go +++ b/sysfs/gpio.go @@ -431,11 +431,11 @@ func (d *driverGPIO) String() string { } func (d *driverGPIO) Prerequisites() []string { - return []string{"ioctl-gpio"} + return nil } func (d *driverGPIO) After() []string { - return nil + return []string{"ioctl-gpio"} } // Init initializes GPIO sysfs handling code. diff --git a/sysfs/gpio_test.go b/sysfs/gpio_test.go index 32e1538d..e8204a05 100644 --- a/sysfs/gpio_test.go +++ b/sysfs/gpio_test.go @@ -204,7 +204,7 @@ func TestPin_readInt(t *testing.T) { } func TestGPIODriver(t *testing.T) { - if len((&driverGPIO{}).Prerequisites()) != 1 { + if len((&driverGPIO{}).Prerequisites()) != 0 { t.Fatal("unexpected GPIO prerequisites") } }