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.


Reply via email to