Setting default GPIO value in device tree

We would like to set the default value of GPIO in the device tree with option to override the set value when the system is booted using for example gpiod lib. Main purpose of using the device tree to set the GPIO is that we would like to turn on the LED during booting. If there are any better alternatives than device tree, then please do tell.

Currently we tried to set the default value with the following entry in apq8096-db820c.dtsi:

led {
    gpios = <&msmgpio 122 GPIO_ACTIVE_HIGH>;
};

but the LED was not turned on during boot. Next we tried using the gpio-leds driver:

led {
    compatible = "gpio-leds";
    client1 {
        label = "client1_gpio";
        gpios = <&msmgpio 122 GPIO_ACTIVE_HIGH>;
        default-state = "on";
    };
};

but this took a hold of the GPIO and when we tried controlling the said LED via gpiod we got the following error:

Traceback (most recent call last):
  File "led_test.py", line 7, in <module>
    pin.request(consumer="gpio_led_test", type=gpiod.LINE_REQ_DIR_OUT)
OSError: [Errno 16] Device or resource busy

It works with the sysfs interface (e.g echo 1 > /sys/class/leds/led1/brightness) , but it’s deprecated. Any ideas on what to try are welcome

Why deprecated? A led can be both controlled by the kernel when a trigger is set or manually by user via this brightness pseudo-file. So it looks like a valid solution.

AFAIK there is no proper way to initialize a gpio at boot time without requesting it from a kernel driver, and so preventing user mode access… but you can always unbind the gpio-led device from it’s driver once booted.

Try setting the gpio early in init.

Why deprecated?

We were referring to this, gpiod uses the new chardev ABI.

AFAIK there is no proper way to initialize a gpio at boot time without requesting it from a kernel driver

So this essentially means that you cannot initialize the GPIO without specifying it to a specific kernel driver, in this example gpio-leds kernel driver?

but you can always unbind the gpio-led device from it’s driver once booted.

How can one do that?

Try setting the gpio early in init.

@doitright id you mean doing this via a script in /etc/init.d? Could you please be more specific

Yes, old gpio sysfs interface is deprecated and you should use chardev, via e.g. libgpiod to control gpio from userspace. But… the ‘led’ sysfs interface is not deprecated (if your ‘device’ is actually a led).

Kernel is driving devices specified in the devicetree, if no device depends on that gpio (not selected by any node), it will not use it or initialize it, that’s it. You can always play with things like gpio-hog trick (cf https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt), but then you’ll not be able to control it from user-mode.

As doitright said, why not initializing it early from init? You want to drive this gpio from user, so what is the point of doing it from kernel if you don’t use it from kernel? sure the gpio could be toggled a bit sooner… but in that case why not even doing that toggling in bootloader…

Every driver has ‘unbind’ file in sysfs directory that you can use to unbind devices, so something like:

cd /sys/bus/platform/drivers/leds-gpio
echo soc:led > unbind

But I don’t recommend that solution anyway.

I think yes (or even from initrd if ou have one, a simple script that sets the gpio (e.g. using gpioset).

As doitright said, why not initializing it early from init? You want to drive this gpio from user, so what is the point of doing it from kernel if you don’t use it from kernel? sure the gpio could be toggled a bit sooner… but in that case why not even doing that toggling in bootloader…

We automatically assumed that toggling the GPIO would be faster from the kernel than from init.d, but we didn’t actually test the delay between the two solutions… Thanks for the recommended solutions!