On 8/6/23 17:09, Peter Maydell wrote:
On Wed, 31 May 2023 at 21:37, Philippe Mathieu-Daudé <phi...@linaro.org> wrote:
SysBus IRQ are *output* IRQs. As some sort of simplification
to avoid to forward it, IcpPitState misuses it as ARM timer
input IRQ. Fix that by using a simple IRQ forwarder handler.
Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
hw/timer/arm_timer.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
+static void icp_pit_fwd_irq(void *opaque, int n, int level)
+{
+ IntegratorPitState *s = opaque;
+
+ qemu_set_irq(s->irq[n], level);
+}
+
static void icp_pit_init(Object *obj)
{
static const uint32_t tmr_freq[] = {
@@ -402,9 +410,14 @@ static void icp_pit_init(Object *obj)
IntegratorPitState *s = INTEGRATOR_PIT(obj);
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+ qdev_init_gpio_in_named(DEVICE(obj), icp_pit_fwd_irq,
+ "timer-in", ARRAY_SIZE(s->timer));
+
for (unsigned i = 0; i < ARRAY_SIZE(s->timer); i++) {
s->timer[i] = arm_timer_new(tmr_freq[i], s->irq_in[i]);
- sysbus_init_irq(dev, &s->irq_in[i]);
+ sysbus_init_irq(dev, &s->irq[i]);
+ sysbus_connect_irq(dev, i,
+ qdev_get_gpio_in_named(DEVICE(obj), "timer-in", i));
}
This feels a bit clunky but I think it's what we have to do,
since the various _pass_ APIs for forwarding GPIOs and
IRQs from a container to an inner device only work with
an entire set of IRQs.
Indeed. sysbus_pass_irq() could resolve the last unused IRQ index
and amend starting at that index, but this doesn't seem a lot of
need for a such use (so far). We might consider it if we ever merge
sysbus IRQ API into qdev.
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Thanks!
Phil.