Search code examples
linux-kernellinux-device-drivergpio

How do I use new `gpiod_export()` in the kernel space


In the kernel v4.14, we exported GPIOs from a kernel driver using the code below. After which, I could see all of the exported GPIOs in the user space with cat /sys/kernel/debug/gpio

static struct gpio ct_gen2_gpios[] __initdata = {
    {22, GPIOF_OUT_INIT_LOW, "gpo1" },
    {23, GPIOF_OUT_INIT_LOW, "gpo0" },
...
}
    gpio_request_array(my_gpios, ARRAY_SIZE(y_gpios));
    for (i = 0; i < ARRAY_SIZE(y_gpios); i++) {
        gpio_export(ct_gen2_gpios[i].gpio, 1);  // THIS NO LONGER EXPORTS
    }

In the kernel v5.10, the legacy gpio.h is deprecated and this code no longer exports the gpios. I see the new

int gpiod_export(struct gpio_desc *desc, bool direction_may_change);

struct gpio_desc {
    struct gpio_device  *gdev;
    unsigned long       flags;

    /* Connection label */
    const char      *label;
    /* Name of the GPIO */
    const char      *name;
[...]
};

but I can't find any examples of how to get or create the struct gpio_desc, specifically the struct gpio_device *gdev field.

How do I correctly export the GPIOs using the new descriptor interface?


Solution

  • In the new code you must not use the legacy API. When converted to a new one, you can have a descriptor with help of the gpiod_get() family of calls, which may be issued at the ->probe() stage in your driver.

    Here is the example of the existing driver in the Linux kernel.

    Moreoever, the sysfs interface mustn't be used. I would suggest you to go away from calling even that function in your code.

    Note, that legacy gpio_export has been removed. This is pending change for v6.4-rc1.

    Last but not least, this shows why upstreaming the code is important rather than having it in your sandbox only.