From: Ruslan Ruslichenko <[email protected]> Implement the FDTGenericIntc interface for the Remote Port GPIO device.
This enables the device to be recognized as an interrupt controller when instantiated via the fdt-generic framework. It allows other devices defined in the Device Tree to connect their interrupt lines to this GPIO controller using standard FDT properties (e.g., 'interrupts' and 'interrupt-parent'). The implementation maps the interrupt specifier from the Device Tree cells to the corresponding internal GPIO input line based on the configured cell offset. Signed-off-by: Edgar E. Iglesias <[email protected]> Signed-off-by: Takahiro Nakata <[email protected]> Signed-off-by: Ruslan Ruslichenko <[email protected]> --- hw/core/remote-port-gpio.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/core/remote-port-gpio.c b/hw/core/remote-port-gpio.c index b9bdbcc5a5..c17a65f63a 100644 --- a/hw/core/remote-port-gpio.c +++ b/hw/core/remote-port-gpio.c @@ -19,6 +19,8 @@ #include "hw/core/irq.h" #include "trace.h" +#include "hw/core/fdt_generic_util.h" + #include "hw/core/remote-port.h" #include "hw/core/remote-port-proto.h" #include "hw/core/remote-port-gpio.h" @@ -153,14 +155,34 @@ static Property rp_properties[] = { DEFINE_PROP_BOOL("posted-updates", RemotePortGPIO, posted_updates, true), }; +static int rp_fdt_get_irq(FDTGenericIntc *obj, qemu_irq *irqs, + uint32_t *cells, int ncells, int max, + Error **errp) +{ + RemotePortGPIO *s = REMOTE_PORT_GPIO(obj); + + if (cells[s->cell_offset_irq_num] >= s->num_gpios) { + error_setg(errp, "RP-GPIO was setup for %u interrupts: index %" + PRIu32 " requested", s->num_gpios, + cells[s->cell_offset_irq_num]); + return 0; + } + + (*irqs) = qdev_get_gpio_in(DEVICE(obj), cells[s->cell_offset_irq_num]); + return 1; +}; + static void rp_gpio_class_init(ObjectClass *oc, const void *data) { RemotePortDeviceClass *rpdc = REMOTE_PORT_DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); + FDTGenericIntcClass *fgic = FDT_GENERIC_INTC_CLASS(oc); + rpdc->ops[RP_CMD_interrupt] = rp_gpio_interrupt; dc->legacy_reset = rp_gpio_reset; dc->realize = rp_gpio_realize; device_class_set_props_n(dc, rp_properties, ARRAY_SIZE(rp_properties)); + fgic->get_irq = rp_fdt_get_irq; } static const TypeInfo rp_info = { @@ -171,6 +193,7 @@ static const TypeInfo rp_info = { .class_init = rp_gpio_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_REMOTE_PORT_DEVICE }, + { TYPE_FDT_GENERIC_INTC }, { }, }, }; -- 2.43.0
