Test a Linux kernel USB Device Controller driver with testusb

At Bootlin, we recently developed from scratch a new Linux driver for the USB Device Controller found in the Renesas RZ/N1 processor. This driver is already accepted upstream, is currently visible in linux-next and should hopefully be part of the upcoming Linux 6.3 release.

As part of developing this driver, we of course had to… test it! To test a USB Device Controller driver, the obvious idea that comes to mind is to use the available USB gadget drivers in the Linux kernel, to expose a USB mass-storage device, a USB network device, etc. However, these existing USB gadget drivers are not necessarily the best option for this kind of testing: they perform some more or less complex transfers and it can be difficult to find the root cause of an error using these gadget drivers.

Fortunately, a tool exists precisely to perform testing of USB transfers: this tool is called testusb, and it can be found directly in the Linux kernel source code in tools/usb/testusb.c. The tool is quite old and not very well known, but it proved to be very useful for our testing, so in this blog post we are sharing some details on how to use it.

Continue reading “Test a Linux kernel USB Device Controller driver with testusb”

Device Tree phandle: the C code point of view


In this blog post, we’ll discuss the phandle properties used in Device Tree. These properties are used to describe a relationship between components described in the Device Tree. Many blog posts describe this property from the Device Tree source point of view (you can for example have a look at https://elinux.org/Device_Tree_Mysteries#Phandle for details related to Device Tree source). In this blog post, we want to take a different approach, and discuss how to handle this type of property from the Linux kernel C code point of view.

Continue reading “Device Tree phandle: the C code point of view”

GPIO Aggregator, a virtual gpio chip

GPIOs are obviously widely used in embedded systems, and many of them are typically driven directly by Linux kernel drivers for interrupt lines, reset lines, or other control lines used to connect with various peripherals. However, a number of GPIOs are sometimes directly driven by user-space applications. Historically, the Linux kernel has provided a sysfs interface, in /sys/class/gpio to allow such direct control. But in recent years, this sysfs interface has been superseded by a new user-space interface based on /dev/gpiochip* character devices.

This new interface has numerous advantages over the previous /sys/class/gpio interface. However, one drawback is that it creates one device file per GPIO chip, which means that access rights are defined per GPIO chip, and not per GPIOs.

For this reason, in Linux 5.8, Geert Uytterhoeven has contributed the GPIO aggregator mechanism. It allows to group a number of GPIOs into a virtual GPIO chip, visible as an additional /dev/gpiochip*. Its documentation can be found in Documentation/admin-guide/gpio/gpio-aggregator.rst.

The list of GPIOs part of this new virtual GPIO chip is defined in the Device Tree. One other interesting thing is that, as any GPIO controler, the lines can be named, and then queried by user-space applications based on their name, using the libgpiod library.

Configuration and Device Tree description

To have GPIO Aggregator support in your kernel, simply configure


Add a gpio-aggregator node in your Device Tree source. For instance, the following DTS snippet declares an aggregator with several GPIO lines:

gpio-aggregator {
    pinctrl-names = "default";
    pinctrl-0 = <&gpio_pins>;
    compatible = "gpio-aggregator";

    gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>,
            <&gpio2 4 GPIO_ACTIVE_HIGH>,
            <&gpio1 28 GPIO_ACTIVE_HIGH>,
            <&gpio1 29 GPIO_ACTIVE_HIGH>,
            <&gpio2 0 GPIO_ACTIVE_HIGH>,
            <&gpio2 1 GPIO_ACTIVE_HIGH>,
            <&gpio3 8 GPIO_ACTIVE_HIGH>;

    gpio-line-names = "line_a", "line_b", "line_c", "line_d",
            "line_e", "line_f", "line_g";

In this example, line 4 of gpio controller gpio3 is used and is named “line_a”, line 4 of gpio controller gpio2 is used and is named “line_b”, and so on up to line 8 of gpio controler gpio3.

Usage from user-space

From userspace we can see the GPIO chip and its aggregated lines:

# gpioinfo
gpiochip6 - 7 lines:
    line 0: "line_a" unused input active-high
    line 1: "line_b" unused input active-high
    line 2: "line_c" unused input active-high
    line 3: "line_d" unused input active-high
    line 4: "line_e" unused input active-high
    line 5: "line_f" unused input active-high
    line 6: "line_g" unused input active-high

We can search a gpio chip and a line number by the line name:

# gpiofind 'line_b'
gpiochip6 1

We can access a GPIO line by its name

# gpioget $(gpiofind 'line_b')
# gpioset $(gpiofind 'line_e')=1
# gpioset $(gpiofind 'line_e')=0

We can change the GPIO chip device file ownership to allow user or group to access the attached lines:

# ls -al /dev/gpiochip*
crw------- 1 root root 254, 0 Jan 1 00:00 /dev/gpiochip0
crw------- 1 root root 254, 1 Jan 1 00:00 /dev/gpiochip1
crw------- 1 root root 254, 2 Jan 1 00:00 /dev/gpiochip2
crw------- 1 root root 254, 3 Jan 1 00:00 /dev/gpiochip3
crw------- 1 root root 254, 4 Jan 1 00:00 /dev/gpiochip4
crw------- 1 root root 254, 5 Jan 1 00:00 /dev/gpiochip5
crw------- 1 root root 254, 6 Jan 1 00:00 /dev/gpiochip6
# chown root:users /dev/gpiochip6
# chmod 660 /dev/gpiochip6
# ls -al /dev/gpiochip*
crw------- 1 root root 254, 0 Jan 1 00:00 /dev/gpiochip0
crw------- 1 root root 254, 1 Jan 1 00:00 /dev/gpiochip1
crw------- 1 root root 254, 2 Jan 1 00:00 /dev/gpiochip2
crw------- 1 root root 254, 3 Jan 1 00:00 /dev/gpiochip3
crw------- 1 root root 254, 4 Jan 1 00:00 /dev/gpiochip4
crw------- 1 root root 254, 5 Jan 1 00:00 /dev/gpiochip5
crw-rw---- 1 root users 254, 6 Jan 1 00:00 /dev/gpiochip6

The GPIO chip created by the aggregator can be retrieved from sysfs:

# ls -1 /sys/bus/platform/devices/gpio-aggregator/
# cat /sys/bus/platform/devices/gpio-aggregator/gpiochip6/dev


A GPIO Aggregator can be used to group a subset of GPIO lines, name them, access them by their names and manage access control to the virtual gpio chip created by the aggregator. On an embedded system, this can simplify the management and usage of individual GPIO lines.