qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 1/3] Change qemu_set_irq() to return status infor


From: Gleb Natapov
Subject: [Qemu-devel] [PATCH v2 1/3] Change qemu_set_irq() to return status information.
Date: Tue, 08 Jul 2008 14:15:36 +0300
User-agent: StGIT/0.14.2

The return value is less then zero if interrupt is masked, zero if it
is known that interrupt is lost (due to coalescing) or greater then zero
if interrupt is delivered or was successfully queued for delivery by
interrupt controller. Device emulation can use this info as it pleases.
Included patch adds detection of interrupt coalescing into PIC and APIC
code for edge triggered interrupts.

Signed-off-by: Gleb Natapov <address@hidden>
---

 hw/apic.c          |  103 +++++++++++++++++++++++++++++++++-------------------
 hw/arm_gic.c       |    6 ++-
 hw/arm_pic.c       |    4 ++
 hw/arm_timer.c     |    4 +-
 hw/cbus.c          |   12 +++++-
 hw/esp.c           |    4 ++
 hw/etraxfs_pic.c   |   12 ++++--
 hw/fdc.c           |    4 ++
 hw/heathrow_pic.c  |    4 ++
 hw/i8259.c         |   19 +++++++---
 hw/ide.c           |    8 +++-
 hw/integratorcp.c  |    4 ++
 hw/irq.c           |   10 +++--
 hw/irq.h           |   35 ++++++++++++------
 hw/max7310.c       |    4 ++
 hw/mcf5206.c       |    4 ++
 hw/mcf_intc.c      |    6 ++-
 hw/mips_int.c      |    6 ++-
 hw/mpcore.c        |    4 ++
 hw/mst_fpga.c      |    4 ++
 hw/musicpal.c      |    4 ++
 hw/nseries.c       |    7 +++-
 hw/omap.h          |    2 +
 hw/omap1.c         |   44 +++++++++++++++++-----
 hw/omap2.c         |   12 +++++-
 hw/omap_dma.c      |    8 +++-
 hw/omap_mmc.c      |    4 ++
 hw/openpic.c       |    4 ++
 hw/palm.c          |    4 ++
 hw/pc.c            |    6 ++-
 hw/pc.h            |    2 +
 hw/pci.c           |    8 +++-
 hw/pcnet.c         |    4 ++
 hw/pl061.c         |    4 ++
 hw/pl190.c         |    4 ++
 hw/ppc.c           |   18 ++++++---
 hw/ppc4xx_devs.c   |    6 ++-
 hw/pxa2xx.c        |    4 ++
 hw/pxa2xx_gpio.c   |    6 ++-
 hw/pxa2xx_pcmcia.c |    6 ++-
 hw/pxa2xx_pic.c    |    4 ++
 hw/rc4030.c        |    4 ++
 hw/sbi.c           |    6 ++-
 hw/sharpsl.h       |    2 +
 hw/slavio_intctl.c |    8 +++-
 hw/sparc32_dma.c   |    4 ++
 hw/spitz.c         |   20 ++++++++--
 hw/ssd0323.c       |    4 ++
 hw/stellaris.c     |   10 ++++-
 hw/sun4c_intctl.c  |    4 ++
 hw/sun4m.c         |    7 +++-
 hw/tc6393xb.c      |    5 ++-
 hw/tusb6010.c      |    4 ++
 hw/twl92230.c      |    8 +++-
 hw/versatilepb.c   |    4 ++
 hw/zaurus.c        |    4 ++
 56 files changed, 354 insertions(+), 158 deletions(-)

diff --git a/hw/apic.c b/hw/apic.c
index 6fd0160..9bdaed2 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -101,7 +101,7 @@ static APICState *local_apics[MAX_APICS + 1];
 static int last_apic_id = 0;
 
 static void apic_init_ipi(APICState *s);
-static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
+static int apic_set_irq(APICState *s, int vector_num, int trigger_mode);
 static void apic_update_irq(APICState *s);
 
 /* Find first bit starting from msb. Return 0 if value = 0 */
@@ -166,6 +166,14 @@ static inline void reset_bit(uint32_t *tab, int index)
     tab[i] &= ~mask;
 }
 
+static inline int get_bit(uint32_t *tab, int index)
+{
+    int i, mask;
+    i = index >> 5;
+    mask = 1 << (index & 0x1f);
+    return !!(tab[i] & mask);
+}
+
 void apic_local_deliver(CPUState *env, int vector)
 {
     APICState *s = env->apic_state;
@@ -215,12 +223,13 @@ void apic_local_deliver(CPUState *env, int vector)
     }\
 }
 
-static void apic_bus_deliver(const uint32_t *deliver_bitmask,
+static int apic_bus_deliver(const uint32_t *deliver_bitmask,
                              uint8_t delivery_mode,
                              uint8_t vector_num, uint8_t polarity,
                              uint8_t trigger_mode)
 {
     APICState *apic_iter;
+    int ret = 0;
 
     switch (delivery_mode) {
         case APIC_DM_LOWPRI:
@@ -237,11 +246,12 @@ static void apic_bus_deliver(const uint32_t 
*deliver_bitmask,
                 if (d >= 0) {
                     apic_iter = local_apics[d];
                     if (apic_iter) {
-                        apic_set_irq(apic_iter, vector_num, trigger_mode);
+                        ret = apic_set_irq(apic_iter, vector_num, 
trigger_mode);
                     }
-                }
+                } else
+                    ret = 1;
             }
-            return;
+            return ret;
 
         case APIC_DM_FIXED:
             break;
@@ -249,29 +259,33 @@ static void apic_bus_deliver(const uint32_t 
*deliver_bitmask,
         case APIC_DM_SMI:
             foreach_apic(apic_iter, deliver_bitmask,
                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
-            return;
+            return 1;
 
         case APIC_DM_NMI:
             foreach_apic(apic_iter, deliver_bitmask,
                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
-            return;
+            return 1;
 
         case APIC_DM_INIT:
             /* normal INIT IPI sent to processors */
             foreach_apic(apic_iter, deliver_bitmask,
                          apic_init_ipi(apic_iter) );
-            return;
+            return 1;
 
         case APIC_DM_EXTINT:
             /* handled in I/O APIC code */
             break;
 
         default:
-            return;
+            return ret;
     }
 
+    /* if interrupt should be delivered to more then one apic report it as
+     * delivered if at least one apic accepts it */
     foreach_apic(apic_iter, deliver_bitmask,
-                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
+                 ret += apic_set_irq(apic_iter, vector_num, trigger_mode) );
+
+    return ret;
 }
 
 void cpu_set_apic_base(CPUState *env, uint64_t val)
@@ -361,14 +375,18 @@ static void apic_update_irq(APICState *s)
     cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
 }
 
-static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
+static int apic_set_irq(APICState *s, int vector_num, int trigger_mode)
 {
+    int ret = !get_bit(s->irr, vector_num);
+
     set_bit(s->irr, vector_num);
     if (trigger_mode)
         set_bit(s->tmr, vector_num);
     else
         reset_bit(s->tmr, vector_num);
     apic_update_irq(s);
+
+    return ret;
 }
 
 static void apic_eoi(APICState *s)
@@ -906,9 +924,8 @@ int apic_init(CPUState *env)
     return 0;
 }
 
-static void ioapic_service(IOAPICState *s)
+static int ioapic_service_one(IOAPICState *s, uint8_t pin)
 {
-    uint8_t i;
     uint8_t trig_mode;
     uint8_t vector;
     uint8_t delivery_mode;
@@ -919,34 +936,44 @@ static void ioapic_service(IOAPICState *s)
     uint8_t polarity;
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
 
+    mask = 1 << pin;
+    if (!(s->irr & mask))
+        return 1;
+    
+    entry = s->ioredtbl[pin];
+    if ((entry & APIC_LVT_MASKED))
+        return -1;
+
+    trig_mode = ((entry >> 15) & 1);
+    dest = entry >> 56;
+    dest_mode = (entry >> 11) & 1;
+    delivery_mode = (entry >> 8) & 7;
+    polarity = (entry >> 13) & 1;
+    if (trig_mode == APIC_TRIGGER_EDGE)
+        s->irr &= ~mask;
+    if (delivery_mode == APIC_DM_EXTINT)
+        vector = pic_read_irq(isa_pic);
+    else
+        vector = entry & 0xff;
+
+    apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
+    return apic_bus_deliver(deliver_bitmask, delivery_mode, vector, polarity,
+            trig_mode);
+}
+
+static void ioapic_service(IOAPICState *s)
+{
+    uint8_t i;
+
     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-        mask = 1 << i;
-        if (s->irr & mask) {
-            entry = s->ioredtbl[i];
-            if (!(entry & APIC_LVT_MASKED)) {
-                trig_mode = ((entry >> 15) & 1);
-                dest = entry >> 56;
-                dest_mode = (entry >> 11) & 1;
-                delivery_mode = (entry >> 8) & 7;
-                polarity = (entry >> 13) & 1;
-                if (trig_mode == APIC_TRIGGER_EDGE)
-                    s->irr &= ~mask;
-                if (delivery_mode == APIC_DM_EXTINT)
-                    vector = pic_read_irq(isa_pic);
-                else
-                    vector = entry & 0xff;
-
-                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
-                apic_bus_deliver(deliver_bitmask, delivery_mode,
-                                 vector, polarity, trig_mode);
-            }
-        }
+        ioapic_service_one(s, i);
     }
 }
 
-void ioapic_set_irq(void *opaque, int vector, int level)
+int ioapic_set_irq(void *opaque, int vector, int level)
 {
     IOAPICState *s = opaque;
+    int ret = 1;
 
     if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
         uint32_t mask = 1 << vector;
@@ -956,7 +983,7 @@ void ioapic_set_irq(void *opaque, int vector, int level)
             /* level triggered */
             if (level) {
                 s->irr |= mask;
-                ioapic_service(s);
+                ioapic_service_one(s, vector);
             } else {
                 s->irr &= ~mask;
             }
@@ -964,10 +991,12 @@ void ioapic_set_irq(void *opaque, int vector, int level)
             /* edge triggered */
             if (level) {
                 s->irr |= mask;
-                ioapic_service(s);
+                ret = ioapic_service_one(s, vector);
             }
         }
     }
+
+    return ret;
 }
 
 static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 54e99f4..a0fc3f0 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -154,13 +154,13 @@ gic_set_pending_private(gic_state *s, int cpu, int irq)
 }
 
 /* Process a change in an external IRQ input.  */
-static void gic_set_irq(void *opaque, int irq, int level)
+static int gic_set_irq(void *opaque, int irq, int level)
 {
     gic_state *s = (gic_state *)opaque;
     /* The first external input line is internal interrupt 32.  */
     irq += 32;
     if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
-        return;
+        return 1;
 
     if (level) {
         GIC_SET_LEVEL(irq, ALL_CPU_MASK);
@@ -172,6 +172,8 @@ static void gic_set_irq(void *opaque, int irq, int level)
         GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
     }
     gic_update(s);
+
+    return 1;
 }
 
 static void gic_set_running_irq(gic_state *s, int cpu, int irq)
diff --git a/hw/arm_pic.c b/hw/arm_pic.c
index 1fe55b7..753a404 100644
--- a/hw/arm_pic.c
+++ b/hw/arm_pic.c
@@ -21,7 +21,7 @@ void irq_info(void)
 
 
 /* Input 0 is IRQ and input 1 is FIQ.  */
-static void arm_pic_cpu_handler(void *opaque, int irq, int level)
+static int arm_pic_cpu_handler(void *opaque, int irq, int level)
 {
     CPUState *env = (CPUState *)opaque;
     switch (irq) {
@@ -40,6 +40,8 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int 
level)
     default:
         cpu_abort(env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq);
     }
+
+    return 1;
 }
 
 qemu_irq *arm_pic_init_cpu(CPUState *env)
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 5150fe9..635c7e2 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -195,12 +195,12 @@ typedef struct {
 } sp804_state;
 
 /* Merge the IRQs from the two component devices.  */
-static void sp804_set_irq(void *opaque, int irq, int level)
+static int sp804_set_irq(void *opaque, int irq, int level)
 {
     sp804_state *s = (sp804_state *)opaque;
 
     s->level[irq] = level;
-    qemu_set_irq(s->irq, s->level[0] || s->level[1]);
+    return qemu_set_irq(s->irq, s->level[0] || s->level[1]);
 }
 
 static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
diff --git a/hw/cbus.c b/hw/cbus.c
index c84de05..28a62e0 100644
--- a/hw/cbus.c
+++ b/hw/cbus.c
@@ -97,7 +97,7 @@ static void cbus_cycle(struct cbus_priv_s *s)
     }
 }
 
-static void cbus_clk(void *opaque, int line, int level)
+static int cbus_clk(void *opaque, int line, int level)
 {
     struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;
 
@@ -112,16 +112,20 @@ static void cbus_clk(void *opaque, int line, int level)
     }
 
     s->clk = level;
+
+    return 1;
 }
 
-static void cbus_dat(void *opaque, int line, int level)
+static int cbus_dat(void *opaque, int line, int level)
 {
     struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;
 
     s->dat = level;
+
+    return 1;
 }
 
-static void cbus_sel(void *opaque, int line, int level)
+static int cbus_sel(void *opaque, int line, int level)
 {
     struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;
 
@@ -132,6 +136,8 @@ static void cbus_sel(void *opaque, int line, int level)
     }
 
     s->sel = level;
+
+    return 1;
 }
 
 struct cbus_s *cbus_init(qemu_irq dat)
diff --git a/hw/esp.c b/hw/esp.c
index 0a8b3e4..585754c 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -409,10 +409,12 @@ static void esp_reset(void *opaque)
     s->do_cmd = 0;
 }
 
-static void parent_esp_reset(void *opaque, int irq, int level)
+static int parent_esp_reset(void *opaque, int irq, int level)
 {
     if (level)
         esp_reset(opaque);
+
+    return 1;
 }
 
 static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index d145bec..0f7c8ed 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -144,7 +144,7 @@ void irq_info(void)
 {
 }
 
-static void irq_handler(void *opaque, int irq, int level)
+static int irq_handler(void *opaque, int irq, int level)
 {      
        struct fs_pic_state_t *fs = (void *)opaque;
        CPUState *env = fs->env;
@@ -186,9 +186,11 @@ static void irq_handler(void *opaque, int irq, int level)
                cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
                D(printf("%s reset irqs\n", __func__));
        }
+
+       return 1;
 }
 
-static void nmi_handler(void *opaque, int irq, int level)
+static int nmi_handler(void *opaque, int irq, int level)
 {      
        struct fs_pic_state_t *fs = (void *)opaque;
        CPUState *env = fs->env;
@@ -204,14 +206,16 @@ static void nmi_handler(void *opaque, int irq, int level)
                cpu_interrupt(env, CPU_INTERRUPT_NMI);
        else
                cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
+
+       return 1;
 }
 
-static void guru_handler(void *opaque, int irq, int level)
+static int guru_handler(void *opaque, int irq, int level)
 {      
        struct fs_pic_state_t *fs = (void *)opaque;
        CPUState *env = fs->env;
        cpu_abort(env, "%s unsupported exception\n", __func__);
-
+       return 1;
 }
 
 
diff --git a/hw/fdc.c b/hw/fdc.c
index cd00420..b212d89 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -713,7 +713,7 @@ static void fdctrl_external_reset(void *opaque)
     fdctrl_reset(s, 0);
 }
 
-static void fdctrl_handle_tc(void *opaque, int irq, int level)
+static int fdctrl_handle_tc(void *opaque, int irq, int level)
 {
     //fdctrl_t *s = opaque;
 
@@ -721,6 +721,8 @@ static void fdctrl_handle_tc(void *opaque, int irq, int 
level)
         // XXX
         FLOPPY_DPRINTF("TC pulsed\n");
     }
+
+    return 1;
 }
 
 /* XXX: may change if moved to bdrv */
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index dc2a30c..81657cf 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -135,7 +135,7 @@ static CPUReadMemoryFunc *pic_read[] = {
 };
 
 
-static void heathrow_pic_set_irq(void *opaque, int num, int level)
+static int heathrow_pic_set_irq(void *opaque, int num, int level)
 {
     HeathrowPICS *s = opaque;
     HeathrowPIC *pic;
@@ -159,6 +159,8 @@ static void heathrow_pic_set_irq(void *opaque, int num, int 
level)
         pic->levels &= ~irq_bit;
     }
     heathrow_pic_update(s);
+
+    return 1;
 }
 
 qemu_irq *heathrow_pic_init(int *pmem_index,
diff --git a/hw/i8259.c b/hw/i8259.c
index add6345..251d09c 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -72,9 +72,9 @@ static uint64_t irq_count[16];
 #endif
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
-static inline void pic_set_irq1(PicState *s, int irq, int level)
+static inline int pic_set_irq1(PicState *s, int irq, int level)
 {
-    int mask;
+    int mask, ret = 1;
     mask = 1 << irq;
     if (s->elcr & mask) {
         /* level triggered */
@@ -88,13 +88,18 @@ static inline void pic_set_irq1(PicState *s, int irq, int 
level)
     } else {
         /* edge triggered */
         if (level) {
-            if ((s->last_irr & mask) == 0)
+            if ((s->last_irr & mask) == 0) {
+                if((s->irr & mask))
+                    ret = 0;
                 s->irr |= mask;
+            }
             s->last_irr |= mask;
         } else {
             s->last_irr &= ~mask;
         }
     }
+
+    return (s->imr & mask) ? -1 : ret;
 }
 
 /* return the highest priority found in mask (highest = smallest
@@ -178,9 +183,10 @@ void pic_update_irq(PicState2 *s)
 int64_t irq_time[16];
 #endif
 
-static void i8259_set_irq(void *opaque, int irq, int level)
+static int i8259_set_irq(void *opaque, int irq, int level)
 {
     PicState2 *s = opaque;
+    int pic_ret, ioapic_ret = -1;
 
 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
     if (level != irq_level[irq]) {
@@ -199,11 +205,12 @@ static void i8259_set_irq(void *opaque, int irq, int 
level)
         irq_time[irq] = qemu_get_clock(vm_clock);
     }
 #endif
-    pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
+    pic_ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
     /* used for IOAPIC irqs */
     if (s->alt_irq_func)
-        s->alt_irq_func(s->alt_irq_opaque, irq, level);
+        ioapic_ret = s->alt_irq_func(s->alt_irq_opaque, irq, level);
     pic_update_irq(s);
+    return MAX(pic_ret, ioapic_ret);
 }
 
 /* acknowledge interrupt 'irq' */
diff --git a/hw/ide.c b/hw/ide.c
index 337621d..b8cfd11 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -3047,7 +3047,7 @@ static void cmd646_update_irq(PCIIDEState *d)
 }
 
 /* the PCI irq level is the logical OR of the two channels */
-static void cmd646_set_irq(void *opaque, int channel, int level)
+static int cmd646_set_irq(void *opaque, int channel, int level)
 {
     PCIIDEState *d = opaque;
     int irq_mask;
@@ -3058,6 +3058,8 @@ static void cmd646_set_irq(void *opaque, int channel, int 
level)
     else
         d->dev.config[MRDMODE] &= ~irq_mask;
     cmd646_update_irq(d);
+
+    return 1;
 }
 
 /* CMD646 PCI IDE controller */
@@ -3450,7 +3452,7 @@ static inline void md_interrupt_update(struct md_s *s)
                     !(s->opt & OPT_SRESET));
 }
 
-static void md_set_irq(void *opaque, int irq, int level)
+static int md_set_irq(void *opaque, int irq, int level)
 {
     struct md_s *s = (struct md_s *) opaque;
     if (level)
@@ -3459,6 +3461,8 @@ static void md_set_irq(void *opaque, int irq, int level)
         s->stat &= ~STAT_INT;
 
     md_interrupt_update(s);
+
+    return 1;
 }
 
 static void md_reset(struct md_s *s)
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 4ac7c0c..f21b873 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -290,7 +290,7 @@ static void icp_pic_update(icp_pic_state *s)
     qemu_set_irq(s->parent_fiq, flags != 0);
 }
 
-static void icp_pic_set_irq(void *opaque, int irq, int level)
+static int icp_pic_set_irq(void *opaque, int irq, int level)
 {
     icp_pic_state *s = (icp_pic_state *)opaque;
     if (level)
@@ -298,6 +298,8 @@ static void icp_pic_set_irq(void *opaque, int irq, int 
level)
     else
         s->level &= ~(1 << irq);
     icp_pic_update(s);
+
+    return 1;
 }
 
 static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
diff --git a/hw/irq.c b/hw/irq.c
index eca707d..78ece4c 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -30,12 +30,12 @@ struct IRQState {
     int n;
 };
 
-void qemu_set_irq(qemu_irq irq, int level)
+int qemu_set_irq(qemu_irq irq, int level)
 {
     if (!irq)
-        return;
+        return 1;
 
-    irq->handler(irq->opaque, irq->n, level);
+    return irq->handler(irq->opaque, irq->n, level);
 }
 
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
@@ -56,11 +56,11 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void 
*opaque, int n)
     return s;
 }
 
-static void qemu_notirq(void *opaque, int line, int level)
+static int qemu_notirq(void *opaque, int line, int level)
 {
     struct IRQState *irq = opaque;
 
-    irq->handler(irq->opaque, irq->n, !level);
+    return irq->handler(irq->opaque, irq->n, !level);
 }
 
 qemu_irq qemu_irq_invert(qemu_irq irq)
diff --git a/hw/irq.h b/hw/irq.h
index 0880ad2..53e5921 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -4,25 +4,38 @@
 /* Generic IRQ/GPIO pin infrastructure.  */
 
 /* FIXME: Rmove one of these.  */
-typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
-typedef void SetIRQFunc(void *opaque, int irq_num, int level);
-
-void qemu_set_irq(qemu_irq irq, int level);
-
-static inline void qemu_irq_raise(qemu_irq irq)
+/* 
+ * Negative return value indicates that interrupt is masked.
+ * Positive return value indicates that interrupt was delivered
+ * to at least one CPU or was queued in interrupt controller for
+ * delivery. If return value is greater then one it indicates the
+ * number of CPUs that handled the interrupt.
+ * Zero value indicates that interrupt was lost (due to coalescing
+ * for instance).
+ */
+typedef int (*qemu_irq_handler)(void *opaque, int n, int level);
+typedef int SetIRQFunc(void *opaque, int irq_num, int level);
+
+int qemu_set_irq(qemu_irq irq, int level);
+
+static inline int qemu_irq_raise(qemu_irq irq)
 {
-    qemu_set_irq(irq, 1);
+    return qemu_set_irq(irq, 1);
 }
 
-static inline void qemu_irq_lower(qemu_irq irq)
+static inline int qemu_irq_lower(qemu_irq irq)
 {
-    qemu_set_irq(irq, 0);
+    return qemu_set_irq(irq, 0);
 }
 
-static inline void qemu_irq_pulse(qemu_irq irq)
+static inline int qemu_irq_pulse(qemu_irq irq)
 {
-    qemu_set_irq(irq, 1);
+    int ret;
+
+    ret = qemu_set_irq(irq, 1);
     qemu_set_irq(irq, 0);
+
+    return ret;
 }
 
 /* Returns an array of N IRQs.  */
diff --git a/hw/max7310.c b/hw/max7310.c
index 2816611..a8e759f 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -177,7 +177,7 @@ static int max7310_load(QEMUFile *f, void *opaque, int 
version_id)
     return 0;
 }
 
-static void max7310_gpio_set(void *opaque, int line, int level)
+static int max7310_gpio_set(void *opaque, int line, int level)
 {
     struct max7310_s *s = (struct max7310_s *) opaque;
     if (line >= sizeof(s->handler) / sizeof(*s->handler) || line  < 0)
@@ -187,6 +187,8 @@ static void max7310_gpio_set(void *opaque, int line, int 
level)
         s->level |= s->direction & (1 << line);
     else
         s->level &= ~(s->direction & (1 << line));
+
+    return 1;
 }
 
 /* MAX7310 is SMBus-compatible (can be used with only SMBus protocols),
diff --git a/hw/mcf5206.c b/hw/mcf5206.c
index 449ca12..79d9e8e 100644
--- a/hw/mcf5206.c
+++ b/hw/mcf5206.c
@@ -228,7 +228,7 @@ static void m5206_mbar_update(m5206_mbar_state *s)
     m68k_set_irq_level(s->env, level, vector);
 }
 
-static void m5206_mbar_set_irq(void *opaque, int irq, int level)
+static int m5206_mbar_set_irq(void *opaque, int irq, int level)
 {
     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
     if (level) {
@@ -237,6 +237,8 @@ static void m5206_mbar_set_irq(void *opaque, int irq, int 
level)
         s->ipr &= ~(1 << irq);
     }
     m5206_mbar_update(s);
+
+    return 1;
 }
 
 /* System Integration Module.  */
diff --git a/hw/mcf_intc.c b/hw/mcf_intc.c
index 4e99aeb..edca76f 100644
--- a/hw/mcf_intc.c
+++ b/hw/mcf_intc.c
@@ -106,16 +106,18 @@ static void mcf_intc_write(void *opaque, 
target_phys_addr_t addr, uint32_t val)
     mcf_intc_update(s);
 }
 
-static void mcf_intc_set_irq(void *opaque, int irq, int level)
+static int mcf_intc_set_irq(void *opaque, int irq, int level)
 {
     mcf_intc_state *s = (mcf_intc_state *)opaque;
     if (irq >= 64)
-        return;
+        return 1;
     if (level)
         s->ipr |= 1ull << irq;
     else
         s->ipr &= ~(1ull << irq);
     mcf_intc_update(s);
+
+    return 1;
 }
 
 static void mcf_intc_reset(mcf_intc_state *s)
diff --git a/hw/mips_int.c b/hw/mips_int.c
index ad48b4f..7e18e1b 100644
--- a/hw/mips_int.c
+++ b/hw/mips_int.c
@@ -18,12 +18,12 @@ void cpu_mips_update_irq(CPUState *env)
         cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
-static void cpu_mips_irq_request(void *opaque, int irq, int level)
+static int cpu_mips_irq_request(void *opaque, int irq, int level)
 {
     CPUState *env = (CPUState *)opaque;
 
     if (irq < 0 || irq > 7)
-        return;
+        return 1;
 
     if (level) {
         env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
@@ -31,6 +31,8 @@ static void cpu_mips_irq_request(void *opaque, int irq, int 
level)
         env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
     }
     cpu_mips_update_irq(env);
+
+    return 1;
 }
 
 void cpu_mips_irq_init_cpu(CPUState *env)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index d5b28fe..6e71081 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -293,7 +293,7 @@ static const int mpcore_irq_map[32] = {
     -1, -1, -1, -1,  9,  3, -1, -1,
 };
 
-static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
+static int mpcore_rirq_set_irq(void *opaque, int irq, int level)
 {
     mpcore_rirq_state *s = (mpcore_rirq_state *)opaque;
     int i;
@@ -307,6 +307,8 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int 
level)
             qemu_set_irq(s->cpuic[irq], level);
         }
     }
+
+    return 1;
 }
 
 qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq)
diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
index e2f0a9a..cebd076 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -62,7 +62,7 @@ mst_fpga_update_gpio(mst_irq_state *s)
        s->prev_level = level;
 }
 
-static void
+static int 
 mst_fpga_set_irq(void *opaque, int irq, int level)
 {
        mst_irq_state *s = (mst_irq_state *)opaque;
@@ -76,6 +76,8 @@ mst_fpga_set_irq(void *opaque, int irq, int level)
                s->intsetclr = 1u << irq;
                qemu_set_irq(s->parent[0], level);
        }
+
+       return 1;
 }
 
 
diff --git a/hw/musicpal.c b/hw/musicpal.c
index e4d8c89..c4a329c 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -951,7 +951,7 @@ static void mv88w8618_pic_update(mv88w8618_pic_state *s)
     qemu_set_irq(s->parent_irq, (s->level & s->enabled));
 }
 
-static void mv88w8618_pic_set_irq(void *opaque, int irq, int level)
+static int mv88w8618_pic_set_irq(void *opaque, int irq, int level)
 {
     mv88w8618_pic_state *s = opaque;
 
@@ -960,6 +960,8 @@ static void mv88w8618_pic_set_irq(void *opaque, int irq, 
int level)
     else
         s->level &= ~(1 << irq);
     mv88w8618_pic_update(s);
+
+    return 1;
 }
 
 static uint32_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset)
diff --git a/hw/nseries.c b/hw/nseries.c
index 725554d..0f2b47f 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -117,13 +117,14 @@ struct n800_s {
 #define N8X0_USB_ASYNC_CS              1
 #define N8X0_USB_SYNC_CS               4
 
-static void n800_mmc_cs_cb(void *opaque, int line, int level)
+static int n800_mmc_cs_cb(void *opaque, int line, int level)
 {
     /* TODO: this seems to actually be connected to the menelaus, to
      * which also both MMC slots connect.  */
     omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
 
     printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
+    return 1;
 }
 
 static void n8x0_gpio_setup(struct n800_s *s)
@@ -707,11 +708,13 @@ static void n8x0_cbus_setup(struct n800_s *s)
     cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
 }
 
-static void n8x0_usb_power_cb(void *opaque, int line, int level)
+static int n8x0_usb_power_cb(void *opaque, int line, int level)
 {
     struct n800_s *s = opaque;
 
     tusb6010_power(s->usb, level);
+
+    return 1;
 }
 
 static void n8x0_usb_setup(struct n800_s *s)
diff --git a/hw/omap.h b/hw/omap.h
index f7b3b1d..0f495d3 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -985,7 +985,7 @@ uint32_t omap_badwidth_read32(void *opaque, 
target_phys_addr_t addr);
 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
                 uint32_t value);
 
-void omap_mpu_wakeup(void *opaque, int irq, int req);
+int omap_mpu_wakeup(void *opaque, int irq, int req);
 
 # define OMAP_BAD_REG(paddr)           \
         fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n", \
diff --git a/hw/omap1.c b/hw/omap1.c
index 7dab6c8..2602724 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -152,7 +152,7 @@ static inline void omap_inth_update(struct 
omap_intr_handler_s *s, int is_fiq)
 #define INT_FALLING_EDGE       0
 #define INT_LOW_LEVEL          1
 
-static void omap_set_intr(void *opaque, int irq, int req)
+static int omap_set_intr(void *opaque, int irq, int req)
 {
     struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
     uint32_t rise;
@@ -176,10 +176,12 @@ static void omap_set_intr(void *opaque, int irq, int req)
         bank->irqs &= ~rise;
         bank->inputs &= ~(1 << n);
     }
+
+    return 1;
 }
 
 /* Simplified version with no edge detection */
-static void omap_set_intr_noedge(void *opaque, int irq, int req)
+static int omap_set_intr_noedge(void *opaque, int irq, int req)
 {
     struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
     uint32_t rise;
@@ -196,6 +198,8 @@ static void omap_set_intr_noedge(void *opaque, int irq, int 
req)
         }
     } else
         bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi;
+
+    return 1;
 }
 
 static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
@@ -734,13 +738,15 @@ static void omap_timer_tick(void *opaque)
     omap_timer_update(timer);
 }
 
-static void omap_timer_clk_update(void *opaque, int line, int on)
+static int omap_timer_clk_update(void *opaque, int line, int on)
 {
     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
 
     omap_timer_sync(timer);
     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
     omap_timer_update(timer);
+
+    return 1;
 }
 
 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
@@ -2558,7 +2564,7 @@ struct omap_mpuio_s {
     int clk;
 };
 
-static void omap_mpuio_set(void *opaque, int line, int level)
+static int omap_mpuio_set(void *opaque, int line, int level)
 {
     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
     uint16_t prev = s->inputs;
@@ -2578,6 +2584,8 @@ static void omap_mpuio_set(void *opaque, int line, int 
level)
                 (s->event >> 1) == line)       /* PIN_SELECT */
             s->latch = s->inputs;
     }
+
+    return 1;
 }
 
 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
@@ -2749,13 +2757,15 @@ static void omap_mpuio_reset(struct omap_mpuio_s *s)
     s->clk = 1;
 }
 
-static void omap_mpuio_onoff(void *opaque, int line, int on)
+static int omap_mpuio_onoff(void *opaque, int line, int on)
 {
     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
 
     s->clk = on;
     if (on)
         omap_mpuio_kbd_update(s);
+
+    return 1;
 }
 
 struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
@@ -2824,7 +2834,7 @@ struct omap_gpio_s {
     uint16_t pins;
 };
 
-static void omap_gpio_set(void *opaque, int line, int level)
+static int omap_gpio_set(void *opaque, int line, int level)
 {
     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
     uint16_t prev = s->inputs;
@@ -2839,6 +2849,8 @@ static void omap_gpio_set(void *opaque, int line, int 
level)
         s->ints |= 1 << line;
         qemu_irq_raise(s->irq);
     }
+
+    return 1;
 }
 
 static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
@@ -3230,12 +3242,14 @@ static void omap_pwl_reset(struct omap_mpu_state_s *s)
     omap_pwl_update(s);
 }
 
-static void omap_pwl_clk_update(void *opaque, int line, int on)
+static int omap_pwl_clk_update(void *opaque, int line, int on)
 {
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
     s->pwl.clk = on;
     omap_pwl_update(s);
+
+    return 1;
 }
 
 static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
@@ -4294,7 +4308,7 @@ struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t 
base,
     return s;
 }
 
-static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
+static int omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
 {
     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
@@ -4302,9 +4316,11 @@ static void omap_mcbsp_i2s_swallow(void *opaque, int 
line, int level)
         s->rx_req = s->codec->in.len;
         omap_mcbsp_rx_newdata(s);
     }
+
+    return 1;
 }
 
-static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
+static int omap_mcbsp_i2s_start(void *opaque, int line, int level)
 {
     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
@@ -4312,6 +4328,8 @@ static void omap_mcbsp_i2s_start(void *opaque, int line, 
int level)
         s->tx_req = s->codec->out.size;
         omap_mcbsp_tx_newdata(s);
     }
+
+    return 1;
 }
 
 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
@@ -4442,12 +4460,14 @@ static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
     omap_badwidth_write8,
 };
 
-static void omap_lpg_clk_update(void *opaque, int line, int on)
+static int omap_lpg_clk_update(void *opaque, int line, int on)
 {
     struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
 
     s->clk = on;
     omap_lpg_update(s);
+
+    return 1;
 }
 
 struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
@@ -4582,12 +4602,14 @@ static void omap_setup_dsp_mapping(const struct 
omap_map_s *map)
     }
 }
 
-void omap_mpu_wakeup(void *opaque, int irq, int req)
+int omap_mpu_wakeup(void *opaque, int irq, int req)
 {
     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
     if (mpu->env->halted)
         cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
+
+    return 1;
 }
 
 static const struct dma_irq_map omap1_dma_irq_map[] = {
diff --git a/hw/omap2.c b/hw/omap2.c
index de42a53..eea83c9 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -191,7 +191,7 @@ static void omap_gp_timer_match(void *opaque)
     omap_gp_timer_intr(timer, GPT_MAT_IT);
 }
 
-static void omap_gp_timer_input(void *opaque, int line, int on)
+static int omap_gp_timer_input(void *opaque, int line, int on)
 {
     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
     int trigger;
@@ -219,15 +219,19 @@ static void omap_gp_timer_input(void *opaque, int line, 
int on)
         if (s->capt2 == s->capt_num ++)
             omap_gp_timer_intr(s, GPT_TCAR_IT);
     }
+
+    return 1;
 }
 
-static void omap_gp_timer_clk_update(void *opaque, int line, int on)
+static int omap_gp_timer_clk_update(void *opaque, int line, int on)
 {
     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
 
     omap_gp_timer_sync(timer);
     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
     omap_gp_timer_update(timer);
+
+    return 1;
 }
 
 static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
@@ -630,7 +634,7 @@ static inline void omap_gpio_module_int(struct omap2_gpio_s 
*s, int line)
     omap_gpio_module_wake(s, line);
 }
 
-static void omap_gpio_module_set(void *opaque, int line, int level)
+static int omap_gpio_module_set(void *opaque, int line, int level)
 {
     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
 
@@ -643,6 +647,8 @@ static void omap_gpio_module_set(void *opaque, int line, 
int level)
             omap_gpio_module_int(s, line);
         s->inputs &= ~(1 << line);
     }
+
+    return 1;
 }
 
 static void omap_gpio_module_reset(struct omap2_gpio_s *s)
diff --git a/hw/omap_dma.c b/hw/omap_dma.c
index 6c0bd82..698966a 100644
--- a/hw/omap_dma.c
+++ b/hw/omap_dma.c
@@ -1333,7 +1333,7 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = {
     omap_badwidth_write16,
 };
 
-static void omap_dma_request(void *opaque, int drq, int req)
+static int omap_dma_request(void *opaque, int drq, int req)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
     /* The request pins are level triggered in QEMU.  */
@@ -1344,9 +1344,11 @@ static void omap_dma_request(void *opaque, int drq, int 
req)
         }
     } else
         s->drq &= ~(1 << drq);
+
+    return 1;
 }
 
-static void omap_dma_clk_update(void *opaque, int line, int on)
+static int omap_dma_clk_update(void *opaque, int line, int on)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
 
@@ -1359,6 +1361,8 @@ static void omap_dma_clk_update(void *opaque, int line, 
int on)
         s->delay = 0;
         qemu_del_timer(s->tm);
     }
+
+    return 1;
 }
 
 static void omap_dma_setcaps(struct omap_dma_s *s)
diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c
index bc46edf..e4e3088 100644
--- a/hw/omap_mmc.c
+++ b/hw/omap_mmc.c
@@ -555,7 +555,7 @@ static CPUWriteMemoryFunc *omap_mmc_writefn[] = {
     omap_badwidth_write16,
 };
 
-static void omap_mmc_cover_cb(void *opaque, int line, int level)
+static int omap_mmc_cover_cb(void *opaque, int line, int level)
 {
     struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;
 
@@ -570,6 +570,8 @@ static void omap_mmc_cover_cb(void *opaque, int line, int 
level)
         qemu_set_irq(host->coverswitch, level);
         host->cdet_state = level;
     }
+
+    return 1;
 }
 
 struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
diff --git a/hw/openpic.c b/hw/openpic.c
index 32cf54e..51dc503 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -346,7 +346,7 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ)
     }
 }
 
-static void openpic_set_irq(void *opaque, int n_IRQ, int level)
+static int openpic_set_irq(void *opaque, int n_IRQ, int level)
 {
     openpic_t *opp = opaque;
     IRQ_src_t *src;
@@ -365,6 +365,8 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int 
level)
             src->pending = 1;
     }
     openpic_update_irq(opp, n_IRQ);
+
+    return 1;
 }
 
 static void openpic_reset (openpic_t *opp)
diff --git a/hw/palm.c b/hw/palm.c
index 9af0b13..837f9c6 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -138,7 +138,7 @@ static void palmte_button_event(void *opaque, int keycode)
                         !(keycode & 0x80));
 }
 
-static void palmte_onoff_gpios(void *opaque, int line, int level)
+static int palmte_onoff_gpios(void *opaque, int line, int level)
 {
     switch (line) {
     case 0:
@@ -163,6 +163,8 @@ static void palmte_onoff_gpios(void *opaque, int line, int 
level)
                         __FUNCTION__, line - 4, level ? "high" : "low");
         break;
     }
+
+    return 1;
 }
 
 static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
diff --git a/hw/pc.c b/hw/pc.c
index 99df09d..4fa16f2 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -114,18 +114,20 @@ int cpu_get_pic_interrupt(CPUState *env)
     return intno;
 }
 
-static void pic_irq_request(void *opaque, int irq, int level)
+static int pic_irq_request(void *opaque, int irq, int level)
 {
     CPUState *env = first_cpu;
 
     if (!level)
-        return;
+        return 1;
 
     while (env) {
         if (apic_accept_pic_intr(env))
             apic_local_deliver(env, APIC_LINT0);
         env = env->next_cpu;
     }
+
+    return 1;
 }
 
 /* PC cmos mappings */
diff --git a/hw/pc.h b/hw/pc.h
index 0c98ff0..b789f98 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -47,7 +47,7 @@ int apic_accept_pic_intr(CPUState *env);
 void apic_local_deliver(CPUState *env, int vector);
 int apic_get_interrupt(CPUState *env);
 IOAPICState *ioapic_init(void);
-void ioapic_set_irq(void *opaque, int vector, int level);
+int ioapic_set_irq(void *opaque, int vector, int level);
 
 /* i8254.c */
 
diff --git a/hw/pci.c b/hw/pci.c
index bc55989..6d85ccb 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -47,7 +47,7 @@ struct PCIBus {
 };
 
 static void pci_update_mappings(PCIDevice *d);
-static void pci_set_irq(void *opaque, int irq_num, int level);
+static int pci_set_irq(void *opaque, int irq_num, int level);
 
 target_phys_addr_t pci_mem_base;
 static int pci_irq_index;
@@ -485,7 +485,7 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
 /* generic PCI irq support */
 
 /* 0 <= irq_num <= 3. level must be 0 or 1 */
-static void pci_set_irq(void *opaque, int irq_num, int level)
+static int pci_set_irq(void *opaque, int irq_num, int level)
 {
     PCIDevice *pci_dev = (PCIDevice *)opaque;
     PCIBus *bus;
@@ -493,7 +493,7 @@ static void pci_set_irq(void *opaque, int irq_num, int 
level)
 
     change = level - pci_dev->irq_state[irq_num];
     if (!change)
-        return;
+        return 1;
 
     pci_dev->irq_state[irq_num] = level;
     for (;;) {
@@ -505,6 +505,8 @@ static void pci_set_irq(void *opaque, int irq_num, int 
level)
     }
     bus->irq_count[irq_num] += change;
     bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
+
+    return 1;
 }
 
 /***********************************************************/
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 0d0bb87..fb64010 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -2012,10 +2012,12 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
 #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
 #include "sun4m.h"
 
-static void parent_lance_reset(void *opaque, int irq, int level)
+static int parent_lance_reset(void *opaque, int irq, int level)
 {
     if (level)
         pcnet_h_reset(opaque);
+
+    return 1;
 }
 
 static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
diff --git a/hw/pl061.c b/hw/pl061.c
index 6db5e39..09899e7 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -214,7 +214,7 @@ static void pl061_reset(pl061_state *s)
   s->cr = 0xff;
 }
 
-static void pl061_set_irq(void * opaque, int irq, int level)
+static int pl061_set_irq(void * opaque, int irq, int level)
 {
     pl061_state *s = (pl061_state *)opaque;
     uint8_t mask;
@@ -226,6 +226,8 @@ static void pl061_set_irq(void * opaque, int irq, int level)
             s->data |= mask;
         pl061_update(s);
     }
+
+    return 1;
 }
 
 static CPUReadMemoryFunc *pl061_readfn[] = {
diff --git a/hw/pl190.c b/hw/pl190.c
index 267c26b..ef5094c 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -56,7 +56,7 @@ static void pl190_update(pl190_state *s)
     qemu_set_irq(s->fiq, set);
 }
 
-static void pl190_set_irq(void *opaque, int irq, int level)
+static int pl190_set_irq(void *opaque, int irq, int level)
 {
     pl190_state *s = (pl190_state *)opaque;
 
@@ -65,6 +65,8 @@ static void pl190_set_irq(void *opaque, int irq, int level)
     else
         s->level &= ~(1u << irq);
     pl190_update(s);
+
+    return 1;
 }
 
 static void pl190_update_vectors(pl190_state *s)
diff --git a/hw/ppc.c b/hw/ppc.c
index fc92ab2..71aa1a4 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -56,7 +56,7 @@ static void ppc_set_irq (CPUState *env, int n_IRQ, int level)
 }
 
 /* PowerPC 6xx / 7xx internal IRQ controller */
-static void ppc6xx_set_irq (void *opaque, int pin, int level)
+static int ppc6xx_set_irq (void *opaque, int pin, int level)
 {
     CPUState *env = opaque;
     int cur_level;
@@ -165,13 +165,15 @@ static void ppc6xx_set_irq (void *opaque, int pin, int 
level)
                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
             }
 #endif
-            return;
+            return 1;
         }
         if (level)
             env->irq_input_state |= 1 << pin;
         else
             env->irq_input_state &= ~(1 << pin);
     }
+
+    return 1;
 }
 
 void ppc6xx_irq_init (CPUState *env)
@@ -182,7 +184,7 @@ void ppc6xx_irq_init (CPUState *env)
 
 #if defined(TARGET_PPC64)
 /* PowerPC 970 internal IRQ controller */
-static void ppc970_set_irq (void *opaque, int pin, int level)
+static int ppc970_set_irq (void *opaque, int pin, int level)
 {
     CPUState *env = opaque;
     int cur_level;
@@ -289,13 +291,15 @@ static void ppc970_set_irq (void *opaque, int pin, int 
level)
                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
             }
 #endif
-            return;
+            return 1;
         }
         if (level)
             env->irq_input_state |= 1 << pin;
         else
             env->irq_input_state &= ~(1 << pin);
     }
+
+    return 1;
 }
 
 void ppc970_irq_init (CPUState *env)
@@ -306,7 +310,7 @@ void ppc970_irq_init (CPUState *env)
 #endif /* defined(TARGET_PPC64) */
 
 /* PowerPC 40x internal IRQ controller */
-static void ppc40x_set_irq (void *opaque, int pin, int level)
+static int ppc40x_set_irq (void *opaque, int pin, int level)
 {
     CPUState *env = opaque;
     int cur_level;
@@ -408,13 +412,15 @@ static void ppc40x_set_irq (void *opaque, int pin, int 
level)
                 fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
             }
 #endif
-            return;
+            return 1;
         }
         if (level)
             env->irq_input_state |= 1 << pin;
         else
             env->irq_input_state &= ~(1 << pin);
     }
+
+    return 1;
 }
 
 void ppc40x_irq_init (CPUState *env)
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index f9143dd..051a0a2 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -359,7 +359,7 @@ static void ppcuic_trigger_irq (ppcuic_t *uic)
     }
 }
 
-static void ppcuic_set_irq (void *opaque, int irq_num, int level)
+static int ppcuic_set_irq (void *opaque, int irq_num, int level)
 {
     ppcuic_t *uic;
     uint32_t mask, sr;
@@ -375,7 +375,7 @@ static void ppcuic_set_irq (void *opaque, int irq_num, int 
level)
     }
 #endif
     if (irq_num < 0 || irq_num > 31)
-        return;
+        return 1;
     sr = uic->uicsr;
 
     /* Update status register */
@@ -401,6 +401,8 @@ static void ppcuic_set_irq (void *opaque, int irq_num, int 
level)
 #endif
     if (sr != uic->uicsr)
         ppcuic_trigger_irq(uic);
+
+    return 1;
 }
 
 static target_ulong dcr_read_uic (void *opaque, int dcrn)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index fd663d9..0cbea16 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2016,7 +2016,7 @@ static struct pxa2xx_fir_s 
*pxa2xx_fir_init(target_phys_addr_t base,
     return s;
 }
 
-static void pxa2xx_reset(void *opaque, int line, int level)
+static int pxa2xx_reset(void *opaque, int line, int level)
 {
     struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
 
@@ -2024,6 +2024,8 @@ static void pxa2xx_reset(void *opaque, int line, int 
level)
         cpu_reset(s->env);
         /* TODO: reset peripherals */
     }
+
+    return 1;
 }
 
 /* Initialise a PXA270 integrated chip (ARM based core).  */
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index e3a30bc..3295f8d 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -87,7 +87,7 @@ static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
     0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
 };
 
-static void pxa2xx_gpio_set(void *opaque, int line, int level)
+static int pxa2xx_gpio_set(void *opaque, int line, int level)
 {
     struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
     int bank;
@@ -95,7 +95,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level)
 
     if (line >= s->lines) {
         printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
-        return;
+        return 1;
     }
 
     bank = line >> 5;
@@ -117,6 +117,8 @@ static void pxa2xx_gpio_set(void *opaque, int line, int 
level)
     /* Wake-up GPIOs */
     if (s->cpu_env->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank]))
         cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
+
+    return 1;
 }
 
 static void pxa2xx_gpio_handler_update(struct pxa2xx_gpio_info_s *s) {
diff --git a/hw/pxa2xx_pcmcia.c b/hw/pxa2xx_pcmcia.c
index 1e96ee4..84f27dd 100644
--- a/hw/pxa2xx_pcmcia.c
+++ b/hw/pxa2xx_pcmcia.c
@@ -130,13 +130,13 @@ static CPUWriteMemoryFunc *pxa2xx_pcmcia_io_writefn[] = {
     pxa2xx_pcmcia_io_write,
 };
 
-static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
+static int pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
 {
     struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
     if (!s->irq)
-        return;
+        return 1;
 
-    qemu_set_irq(s->irq, level);
+    return qemu_set_irq(s->irq, level);
 }
 
 struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base)
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index a3611b8..0328f24 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -68,7 +68,7 @@ static void pxa2xx_pic_update(void *opaque)
 
 /* Note: Here level means state of the signal on a pin, not
  * IRQ/FIQ distinction as in PXA Developer Manual.  */
-static void pxa2xx_pic_set_irq(void *opaque, int irq, int level)
+static int pxa2xx_pic_set_irq(void *opaque, int irq, int level)
 {
     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
     int int_set = (irq >= 32);
@@ -80,6 +80,8 @@ static void pxa2xx_pic_set_irq(void *opaque, int irq, int 
level)
         s->int_pending[int_set] &= ~(1 << irq);
 
     pxa2xx_pic_update(opaque);
+
+    return 1;
 }
 
 static inline uint32_t pxa2xx_pic_highest(struct pxa2xx_pic_state_s *s) {
diff --git a/hw/rc4030.c b/hw/rc4030.c
index bf440db..245118d 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -420,7 +420,7 @@ static void update_jazz_irq(rc4030State *s)
         qemu_irq_lower(s->jazz_bus_irq);
 }
 
-static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
+static int rc4030_irq_jazz_request(void *opaque, int irq, int level)
 {
     rc4030State *s = opaque;
 
@@ -431,6 +431,8 @@ static void rc4030_irq_jazz_request(void *opaque, int irq, 
int level)
     }
 
     update_jazz_irq(s);
+
+    return 1;
 }
 
 static void rc4030_periodic_timer(void *opaque)
diff --git a/hw/sbi.c b/hw/sbi.c
index 8d264f1..0e767e5 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -52,12 +52,14 @@ static void sbi_check_interrupts(void *opaque)
 {
 }
 
-static void sbi_set_irq(void *opaque, int irq, int level)
+static int sbi_set_irq(void *opaque, int irq, int level)
 {
+    return 1;
 }
 
-static void sbi_set_timer_irq_cpu(void *opaque, int cpu, int level)
+static int sbi_set_timer_irq_cpu(void *opaque, int cpu, int level)
 {
+    return 1;
 }
 
 static uint32_t sbi_mem_readl(void *opaque, target_phys_addr_t addr)
diff --git a/hw/sharpsl.h b/hw/sharpsl.h
index 184aae6..2054017 100644
--- a/hw/sharpsl.h
+++ b/hw/sharpsl.h
@@ -12,7 +12,7 @@
 /* zaurus.c */
 struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu,
                 int instance, target_phys_addr_t target_base);
-void scoop_gpio_set(void *opaque, int line, int level);
+int scoop_gpio_set(void *opaque, int line, int level);
 qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s);
 void scoop_gpio_out_set(struct scoop_info_s *s, int line,
                 qemu_irq handler);
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index 6a5d505..dec137b 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -284,7 +284,7 @@ static void slavio_check_interrupts(void *opaque)
  * "irq" here is the bit number in the system interrupt register to
  * separate serial and keyboard interrupts sharing a level.
  */
-static void slavio_set_irq(void *opaque, int irq, int level)
+static int slavio_set_irq(void *opaque, int irq, int level)
 {
     SLAVIO_INTCTLState *s = opaque;
     uint32_t mask = 1 << irq;
@@ -305,9 +305,11 @@ static void slavio_set_irq(void *opaque, int irq, int 
level)
         }
         slavio_check_interrupts(s);
     }
+
+    return 1;
 }
 
-static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
+static int slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
 {
     SLAVIO_INTCTLState *s = opaque;
 
@@ -322,6 +324,8 @@ static void slavio_set_timer_irq_cpu(void *opaque, int cpu, 
int level)
     }
 
     slavio_check_interrupts(s);
+
+    return 1;
 }
 
 static void slavio_intctl_save(QEMUFile *f, void *opaque)
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index c69b559..8b9fda6 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -116,7 +116,7 @@ void ledma_memory_write(void *opaque, target_phys_addr_t 
addr,
     }
 }
 
-static void dma_set_irq(void *opaque, int irq, int level)
+static int dma_set_irq(void *opaque, int irq, int level)
 {
     DMAState *s = opaque;
     if (level) {
@@ -128,6 +128,8 @@ static void dma_set_irq(void *opaque, int irq, int level)
         DPRINTF("Lower IRQ\n");
         qemu_irq_lower(s->irq);
     }
+
+    return 1;
 }
 
 void espdma_memory_read(void *opaque, uint8_t *buf, int len)
diff --git a/hw/spitz.c b/hw/spitz.c
index fef557a..076317e 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -261,7 +261,7 @@ static void spitz_keyboard_sense_update(struct 
spitz_keyboard_s *s)
     s->sense_state = sense;
 }
 
-static void spitz_keyboard_strobe(void *opaque, int line, int level)
+static int spitz_keyboard_strobe(void *opaque, int line, int level)
 {
     struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
 
@@ -270,6 +270,8 @@ static void spitz_keyboard_strobe(void *opaque, int line, 
int level)
     else
         s->strobe_state &= ~(1 << line);
     spitz_keyboard_sense_update(s);
+
+    return 1;
 }
 
 static void spitz_keyboard_keydown(struct spitz_keyboard_s *s, int keycode)
@@ -621,7 +623,7 @@ static void corgi_ssp_write(void *opaque, uint32_t value)
         max111x_write(max1111, value);
 }
 
-static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
+static int corgi_ssp_gpio_cs(void *opaque, int line, int level)
 {
     switch (line) {
     case 0:
@@ -634,6 +636,8 @@ static void corgi_ssp_gpio_cs(void *opaque, int line, int 
level)
         max_en = !level;
         break;
     }
+
+    return 1;
 }
 
 #define MAX1111_BATT_VOLT      1
@@ -729,13 +733,15 @@ static void spitz_microdrive_attach(struct pxa2xx_state_s 
*cpu)
 #define SPITZ_GPIO_WM  5
 
 #ifdef HAS_AUDIO
-static void spitz_wm8750_addr(void *opaque, int line, int level)
+static int spitz_wm8750_addr(void *opaque, int line, int level)
 {
     i2c_slave *wm = (i2c_slave *) opaque;
     if (level)
         i2c_set_slave_address(wm, SPITZ_WM_ADDRH);
     else
         i2c_set_slave_address(wm, SPITZ_WM_ADDRL);
+
+    return 1;
 }
 #endif
 
@@ -774,7 +780,7 @@ static void spitz_akita_i2c_setup(struct pxa2xx_state_s 
*cpu)
 
 /* Other peripherals */
 
-static void spitz_out_switch(void *opaque, int line, int level)
+static int spitz_out_switch(void *opaque, int line, int level)
 {
     switch (line) {
     case 0:
@@ -799,6 +805,8 @@ static void spitz_out_switch(void *opaque, int line, int 
level)
         spitz_adc_temp_on(opaque, line, level);
         break;
     }
+
+    return 1;
 }
 
 #define SPITZ_SCP_LED_GREEN            1
@@ -846,11 +854,13 @@ static void spitz_scoop_gpio_setup(struct pxa2xx_state_s 
*cpu,
 
 static int spitz_hsync;
 
-static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
+static int spitz_lcd_hsync_handler(void *opaque, int line, int level)
 {
     struct pxa2xx_state_s *cpu = (struct pxa2xx_state_s *) opaque;
     qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_HSYNC], spitz_hsync);
     spitz_hsync ^= 1;
+
+    return 1;
 }
 
 static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots)
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index e496fe7..9b0e45e 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -268,11 +268,13 @@ static void ssd0323_invalidate_display(void * opaque)
 }
 
 /* Command/data input.  */
-static void ssd0323_cd(void *opaque, int n, int level)
+static int ssd0323_cd(void *opaque, int n, int level)
 {
     ssd0323_state *s = (ssd0323_state *)opaque;
     DPRINTF("%s mode\n", level ? "Data" : "Command");
     s->mode = level ? SSD0323_DATA : SSD0323_CMD;
+
+    return 1;
 }
 
 static void ssd0323_save(QEMUFile *f, void *opaque)
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 999cb50..c1c1ddb 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -980,12 +980,12 @@ static void stellaris_adc_update(stellaris_adc_state *s)
     qemu_set_irq(s->irq, level);
 }
 
-static void stellaris_adc_trigger(void *opaque, int irq, int level)
+static int stellaris_adc_trigger(void *opaque, int irq, int level)
 {
     stellaris_adc_state *s = (stellaris_adc_state *)opaque;
 
     if ((s->actss & 1) == 0) {
-        return;
+        return 1;
     }
 
     /* Some applications use the ADC as a random number source, so introduce
@@ -995,6 +995,8 @@ static void stellaris_adc_trigger(void *opaque, int irq, 
int level)
     stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7));
     s->ris |= 1;
     stellaris_adc_update(s);
+
+    return 1;
 }
 
 static void stellaris_adc_reset(stellaris_adc_state *s)
@@ -1221,11 +1223,13 @@ typedef struct {
     int current_dev;
 } stellaris_ssi_bus_state;
 
-static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
+static int stellaris_ssi_bus_select(void *opaque, int irq, int level)
 {
     stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
 
     s->current_dev = level;
+
+    return 1;
 }
 
 static int stellaris_ssi_bus_xfer(void *opaque, int val)
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index 88cd4a5..462f62c 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -146,7 +146,7 @@ static void sun4c_check_interrupts(void *opaque)
 /*
  * "irq" here is the bit number in the system interrupt register
  */
-static void sun4c_set_irq(void *opaque, int irq, int level)
+static int sun4c_set_irq(void *opaque, int irq, int level)
 {
     Sun4c_INTCTLState *s = opaque;
     uint32_t mask = 1 << irq;
@@ -165,6 +165,8 @@ static void sun4c_set_irq(void *opaque, int irq, int level)
         }
         sun4c_check_interrupts(s);
     }
+
+    return 1;
 }
 
 static void sun4c_intctl_save(QEMUFile *f, void *opaque)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 899e2d5..5452299 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -293,7 +293,7 @@ void cpu_check_irqs(CPUState *env)
     }
 }
 
-static void cpu_set_irq(void *opaque, int irq, int level)
+static int cpu_set_irq(void *opaque, int irq, int level)
 {
     CPUState *env = opaque;
 
@@ -307,10 +307,13 @@ static void cpu_set_irq(void *opaque, int irq, int level)
         env->pil_in &= ~(1 << irq);
         cpu_check_irqs(env);
     }
+
+    return 1;
 }
 
-static void dummy_cpu_set_irq(void *opaque, int irq, int level)
+static int dummy_cpu_set_irq(void *opaque, int irq, int level)
 {
+    return 1;
 }
 
 static void *slavio_misc;
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 6db6dcb..0b10bcb 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -78,16 +78,17 @@ qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s)
     return s->gpio_in;
 }
 
-static void tc6393xb_gpio_set(void *opaque, int line, int level)
+static int tc6393xb_gpio_set(void *opaque, int line, int level)
 {
 //    struct tc6393xb_s *s = opaque;
 
     if (line > TC6393XB_GPIOS) {
         printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
-        return;
+        return 1;
     }
 
     // FIXME: how does the chip reflect the GPIO input level change?
+    return 1;
 }
 
 void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index 8318c46..75fc29a 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -682,7 +682,7 @@ static void tusb_power_tick(void *opaque)
     }
 }
 
-static void tusb_musb_core_intr(void *opaque, int source, int level)
+static int tusb_musb_core_intr(void *opaque, int source, int level)
 {
     struct tusb_s *s = (struct tusb_s *) opaque;
     uint16_t otg_status = s->otg_status;
@@ -729,6 +729,8 @@ static void tusb_musb_core_intr(void *opaque, int source, 
int level)
         tusb_intr_update(s);
         break;
     }
+
+    return 1;
 }
 
 struct tusb_s *tusb6010_init(qemu_irq intr)
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 8fad969..6cd84c5 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -195,16 +195,18 @@ static inline int from_bcd(uint8_t val)
     return ((val >> 4) * 10) + (val & 0x0f);
 }
 
-static void menelaus_gpio_set(void *opaque, int line, int level)
+static int menelaus_gpio_set(void *opaque, int line, int level)
 {
     struct menelaus_s *s = (struct menelaus_s *) opaque;
 
     /* No interrupt generated */
     s->inputs &= ~(1 << line);
     s->inputs |= level << line;
+
+    return 1;
 }
 
-static void menelaus_pwrbtn_set(void *opaque, int line, int level)
+static int menelaus_pwrbtn_set(void *opaque, int line, int level)
 {
     struct menelaus_s *s = (struct menelaus_s *) opaque;
 
@@ -213,6 +215,8 @@ static void menelaus_pwrbtn_set(void *opaque, int line, int 
level)
         menelaus_update(s);
     }
     s->pwrbtn_state = level;
+
+    return 1;
 }
 
 #define MENELAUS_REV           0x01
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index bfbc031..ae6218e 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -49,7 +49,7 @@ static void vpb_sic_update_pic(vpb_sic_state *s)
     }
 }
 
-static void vpb_sic_set_irq(void *opaque, int irq, int level)
+static int vpb_sic_set_irq(void *opaque, int irq, int level)
 {
     vpb_sic_state *s = (vpb_sic_state *)opaque;
     if (level)
@@ -59,6 +59,8 @@ static void vpb_sic_set_irq(void *opaque, int irq, int level)
     if (s->pic_enable & (1u << irq))
         qemu_set_irq(s->parent[irq], level);
     vpb_sic_update(s);
+
+    return 1;
 }
 
 static uint32_t vpb_sic_read(void *opaque, target_phys_addr_t offset)
diff --git a/hw/zaurus.c b/hw/zaurus.c
index 7b8f152..ec1040b 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -166,7 +166,7 @@ CPUWriteMemoryFunc *scoop_writefn[] = {
     scoop_writeb,
 };
 
-void scoop_gpio_set(void *opaque, int line, int level)
+int scoop_gpio_set(void *opaque, int line, int level)
 {
     struct scoop_info_s *s = (struct scoop_info_s *) s;
 
@@ -174,6 +174,8 @@ void scoop_gpio_set(void *opaque, int line, int level)
         s->gpio_level |= (1 << line);
     else
         s->gpio_level &= ~(1 << line);
+
+    return 1;
 }
 
 qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]