Page MenuHomeFreeBSD

gpio: implement bus_setup_intr and bus_teardown_intr
ClosedPublic

Authored by vexeduxr on Aug 27 2025, 10:33 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Oct 10, 4:06 PM
Unknown Object (File)
Fri, Oct 10, 10:11 AM
Unknown Object (File)
Fri, Oct 10, 10:11 AM
Unknown Object (File)
Fri, Oct 10, 3:42 AM
Unknown Object (File)
Thu, Oct 9, 1:02 AM
Unknown Object (File)
Wed, Oct 8, 4:21 AM
Unknown Object (File)
Thu, Sep 25, 1:58 PM
Unknown Object (File)
Mon, Sep 22, 12:59 AM
Subscribers

Details

Summary

Implement bus_setup_intr and bus_teardown_intr as bus_generic_setup_intr
and bus_generic_teardown_intr respectively for GPIO drivers that support
interrupts. This allows children to setup interrupts.

Reported by: Evgenii Ivanov <devivanov@proton.me>

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

I just found a similar problem with rockchip gpio. Implementing interrupt methods is not enough, we also need all the methods for resources. This led me to the idea that we could create a new class in which all these methods (interrupts and resources) would be implemented (by using bus_generic_<foo>), and then subclass all bus-like drivers from it. It's clean, simple, and saves a lot of lines...
@jhb, do you have any comments on this?

Which functions are giving you problems?
The resource handling is done by gpiobus, but bus_setup_intr and bus_teardown_intr need to get to nexus.

I expect we would need bus_activate_resource as it's called via bus_generic_rman_alloc_resource in gpiobus_alloc_resource.

It calls bus_activate_resource on the child device, which should just go through gpiobus' implementation, bus_generic_rman_activate_resource.

These are needed for cross-tree allocation of interrupts (and probably also pins). For example, in FDT, a device from another tree path, typically an I2C or SPI, may have its IRQ pin connected to GPIO.
A driver from another tree path can therefore use an GPIO based interrupt. These allocations are processed by the controller itself (due to FDT references), but by gpiobus.
@andrew is right, at least (de)activate_resource is necessary, but I'm not sure yet whether other resource list oriented methods are also needed.

These are needed for cross-tree allocation of interrupts (and probably also pins). For example, in FDT, a device from another tree path, typically an I2C or SPI, may have its IRQ pin connected to GPIO.
A driver from another tree path can therefore use an GPIO based interrupt. These allocations are processed by the controller itself (due to FDT references), but by gpiobus.

Sorry, I think I'm missing something. I don't see how the call can end up in the GPIO driver.
Take for example the following hierarchy:

├── gpio0
│   └── gpiobus0
└── rk_i2c0
    └── iicbus0
        └── dev0

And say dev0 has the following:

#interrupt-cells=<2>;
interrupt-parent = <&gpio>;
interrupts = <4 2>;

ofw_iicbus would call ofw_bus_intr_to_rl to get the pins into dev0's resource list. So when dev0 attempts to allocate a resource, it would end up in iicbus' bus_generic_rl_alloc_resource, which ends up doing BUS_ALLOC_RESOURCE(device_get_parent(bus), child, .... At that point, it's rk_i2c0's job to pass the call up to nexus.

@andrew is right, at least (de)activate_resource is necessary, but I'm not sure yet whether other resource list oriented methods are also needed.

Bump
Userspace GPIO interrupts are currently broken because of this. (after D51932)
I believe that we do need to implement the resource allocation functions too (for cross-tree consumers), just not on the GPIO controller.

This looks good to me.

This revision is now accepted and ready to land.Mon, Sep 29, 11:08 PM