Index: kernel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/include/drivers/fhc.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -45,7 +45,7 @@
 extern fhc_t *central_fhc;
 
-extern fhc_t *fhc_init(ofw_tree_node_t *node);
-extern void fhc_enable_interrupt(fhc_t *fhc, int inr);
-extern void fhc_clear_interrupt(fhc_t *fhc, int inr);
+extern fhc_t *fhc_init(ofw_tree_node_t *);
+extern void fhc_enable_interrupt(fhc_t *, int);
+extern void fhc_clear_interrupt(void *, int);
 
 #endif
Index: kernel/arch/sparc64/include/drivers/pci.h
===================================================================
--- kernel/arch/sparc64/include/drivers/pci.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/include/drivers/pci.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -52,6 +52,6 @@
 
 struct pci_operations {
-	void (* enable_interrupt)(pci_t *pci, int inr);
-	void (* clear_interrupt)(pci_t *pci, int inr);
+	void (* enable_interrupt)(pci_t *, int);
+	void (* clear_interrupt)(pci_t *, int);
 };
 
@@ -62,7 +62,7 @@
 };
 
-extern pci_t *pci_init(ofw_tree_node_t *node);
-extern void pci_enable_interrupt(pci_t *pci, int inr);
-extern void pci_clear_interrupt(pci_t *pci, int inr);
+extern pci_t *pci_init(ofw_tree_node_t *);
+extern void pci_enable_interrupt(pci_t *, int);
+extern void pci_clear_interrupt(void *, int);
 
 #endif
Index: kernel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/src/drivers/fhc.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -102,6 +102,7 @@
 }
 
-void fhc_clear_interrupt(fhc_t *fhc, int inr)
+void fhc_clear_interrupt(void *fhcp, int inr)
 {
+	fhc_t *fhc = (fhc_t *)fhcp;
 	ASSERT(fhc->uart_imap);
 
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -64,4 +64,6 @@
 	ofw_tree_property_t *prop;
 	const char *name;
+	cir_t cir;
+	void *cir_arg;
 	
 	name = ofw_tree_node_name(node);
@@ -110,5 +112,6 @@
 		}
 		if (!ofw_fhc_map_interrupt(node->parent,
-		    ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
+		    ((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
+		    &cir_arg)) {
 			printf("Failed to determine keyboard interrupt.\n");
 			return;
@@ -124,5 +127,6 @@
 		}
 		if (!ofw_ebus_map_interrupt(node->parent,
-		    ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
+		    ((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
+		    &cir_arg)) {
 			printf("Failed to determine keyboard interrupt.\n");
 			return;
@@ -147,10 +151,10 @@
 #ifdef CONFIG_Z8530
 	case KBD_Z8530:
-		z8530_init(devno, inr, vaddr);
+		z8530_init(devno, vaddr, inr, cir, cir_arg);
 		break;
 #endif
 #ifdef CONFIG_NS16550
 	case KBD_NS16550:
-		ns16550_init(devno, inr, (ioport_t)vaddr);
+		ns16550_init(devno, (ioport_t)vaddr, inr, cir, cir_arg);
 		break;
 #endif
Index: kernel/arch/sparc64/src/drivers/pci.c
===================================================================
--- kernel/arch/sparc64/src/drivers/pci.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -55,9 +55,9 @@
 #define OBIO_CIR(ino)	(OBIO_CIR_BASE + ((ino) & INO_MASK))
 
-static void obio_enable_interrupt(pci_t *pci, int inr);
-static void obio_clear_interrupt(pci_t *pci, int inr);
-
-static pci_t *pci_sabre_init(ofw_tree_node_t *node);
-static pci_t *pci_psycho_init(ofw_tree_node_t *node);
+static void obio_enable_interrupt(pci_t *, int);
+static void obio_clear_interrupt(pci_t *, int);
+
+static pci_t *pci_sabre_init(ofw_tree_node_t *);
+static pci_t *pci_psycho_init(ofw_tree_node_t *);
 
 /** PCI operations for Sabre model. */
@@ -209,6 +209,8 @@
 }
 
-void pci_clear_interrupt(pci_t *pci, int inr)
-{
+void pci_clear_interrupt(void *pcip, int inr)
+{
+	pci_t *pci = (pci_t *)pcip;
+
 	ASSERT(pci->op && pci->op->clear_interrupt);
 	pci->op->clear_interrupt(pci, inr);
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -80,4 +80,10 @@
 		 */
 		irq->handler(irq, irq->arg);
+		/*
+		 * See if there is a clear-interrupt-routine and call it.
+		 */
+		if (irq->cir) {
+			irq->cir(irq->cir_arg, irq->inr);
+		}
 		spinlock_unlock(&irq->lock);
 	} else if (data0 > config.base) {
@@ -99,5 +105,5 @@
 #ifdef CONFIG_DEBUG
 		printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
-			", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
+		    ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
 #endif
 	}
Index: kernel/genarch/include/kbd/ns16550.h
===================================================================
--- kernel/genarch/include/kbd/ns16550.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/include/kbd/ns16550.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -39,13 +39,14 @@
 
 #include <console/chardev.h> 
+#include <ddi/irq.h>
 #include <ipc/irq.h>
 
-extern void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr);
+extern void ns16550_init(devno_t, uintptr_t, inr_t, cir_t, void *);
 extern void ns16550_poll(void);
 extern void ns16550_grab(void);
 extern void ns16550_release(void);
-extern char ns16550_key_read(chardev_t *d);
+extern char ns16550_key_read(chardev_t *);
 extern irq_ownership_t ns16550_claim(void);
-extern void ns16550_irq_handler(irq_t *irq, void *arg, ...);
+extern void ns16550_irq_handler(irq_t *, void *, ...);
 
 #include <arch/types.h>
Index: kernel/genarch/include/kbd/z8530.h
===================================================================
--- kernel/genarch/include/kbd/z8530.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/include/kbd/z8530.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -40,15 +40,16 @@
 #include <console/chardev.h>
 #include <ipc/irq.h>
+#include <ddi/irq.h>
 
 extern bool z8530_belongs_to_kernel;
 
-extern void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr);
+extern void z8530_init(devno_t, uintptr_t, inr_t, cir_t, void *);
 extern void z8530_poll(void);
 extern void z8530_grab(void);
 extern void z8530_release(void);
 extern void z8530_interrupt(void);
-extern char z8530_key_read(chardev_t *d);
+extern char z8530_key_read(chardev_t *);
 extern irq_ownership_t z8530_claim(void);
-extern void z8530_irq_handler(irq_t *irq, void *arg, ...);
+extern void z8530_irq_handler(irq_t *, void *, ...);
 
 #endif
Index: kernel/genarch/include/ofw/ofw_tree.h
===================================================================
--- kernel/genarch/include/ofw/ofw_tree.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/include/ofw/ofw_tree.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -31,4 +31,5 @@
 
 #include <arch/types.h>
+#include <ddi/irq.h>
 #include <typedefs.h>
 
@@ -44,9 +45,9 @@
 	ofw_tree_node_t *child;
 
-	uint32_t node_handle;			/**< Old OpenFirmware node handle. */
-
-	char *da_name;				/**< Disambigued name. */
-
-	unsigned properties;			/**< Number of properties. */
+	uint32_t node_handle;		/**< Old OpenFirmware node handle. */
+
+	char *da_name;			/**< Disambigued name. */
+
+	unsigned properties;		/**< Number of properties. */
 	ofw_tree_property_t *property;
 	
@@ -106,5 +107,5 @@
 	uint32_t child_base;
 	uint32_t parent_space;
-	uint64_t parent_base;		/* group phys.mid and phys.lo together */
+	uint64_t parent_base;	/* group phys.mid and phys.lo together */
 	uint32_t size;
 } __attribute__ ((packed));
@@ -128,6 +129,6 @@
 
 struct ofw_pci_reg {
-	uint32_t space;			/* needs to be masked to obtain pure space id */
-	uint64_t addr;			/* group phys.mid and phys.lo together */
+	uint32_t space;		/* needs to be masked to obtain pure space id */
+	uint64_t addr;		/* group phys.mid and phys.lo together */
 	uint64_t size;
 } __attribute__ ((packed));
@@ -136,5 +137,5 @@
 struct ofw_pci_range {
 	uint32_t space;
-	uint64_t child_base;		/* group phys.mid and phys.lo together */
+	uint64_t child_base;	/* group phys.mid and phys.lo together */
 	uint64_t parent_base;
 	uint64_t size;
@@ -161,26 +162,40 @@
 typedef struct ofw_upa_reg ofw_upa_reg_t;
 
-extern void ofw_tree_init(ofw_tree_node_t *root);
+extern void ofw_tree_init(ofw_tree_node_t *);
 extern void ofw_tree_print(void);
-extern const char *ofw_tree_node_name(const ofw_tree_node_t *node);
-extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
-extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name);
-extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name);
-extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type);
-extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type);
-extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle);
-
-extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa);
-extern bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa);
-extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa);
-extern bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa);
-extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *node, ofw_sbus_reg_t *reg, uintptr_t *pa);
-extern bool ofw_upa_apply_ranges(ofw_tree_node_t *node, ofw_upa_reg_t *reg, uintptr_t *pa);
-
-extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out);
-
-extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr);
-extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr);
-extern bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr);
+extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
+extern ofw_tree_node_t *ofw_tree_lookup(const char *);
+extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *,
+    const char *);
+extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *);
+extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *,
+    const char *);
+extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
+    const char *);
+extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
+    uint32_t);
+
+extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
+    uintptr_t *);
+extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
+    uintptr_t *);
+extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
+    uintptr_t *);
+extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
+    uintptr_t *);
+extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
+    uintptr_t *);
+extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
+    uintptr_t *);
+
+extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
+    ofw_pci_reg_t *);
+
+extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
+    uint32_t, int *, cir_t *, void **);
+extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
+    uint32_t, int *, cir_t *, void **);
+extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
+    int, int *, cir_t *, void **);
 
 #endif
Index: kernel/genarch/src/kbd/ns16550.c
===================================================================
--- kernel/genarch/src/kbd/ns16550.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/src/kbd/ns16550.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -108,9 +108,12 @@
 /** Initialize ns16550.
  *
- * @param devno Device number.
- * @param inr Interrupt number.
- * @param vaddr Virtual address of device's registers.
- */
-void ns16550_init(devno_t devno, inr_t inr, ioport_t port)
+ * @param devno		Device number.
+ * @param port		Virtual/IO address of device's registers.
+ * @param inr		Interrupt number.
+ * @param cir		Clear interrupt function.
+ * @param cir_arg	First argument to cir.
+ */
+void
+ns16550_init(devno_t devno, ioport_t port, inr_t inr, cir_t cir, void *cir_arg)
 {
 	chardev_initialize("ns16550_kbd", &kbrd, &ops);
@@ -125,4 +128,6 @@
 	ns16550_irq.claim = ns16550_claim;
 	ns16550_irq.handler = ns16550_irq_handler;
+	ns16550_irq.cir = cir;
+	ns16550_irq.cir_arg = cir_arg;
 	irq_register(&ns16550_irq);
 	
Index: kernel/genarch/src/kbd/z8530.c
===================================================================
--- kernel/genarch/src/kbd/z8530.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/src/kbd/z8530.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -44,5 +44,4 @@
 #include <arch/interrupt.h>
 #include <arch/drivers/kbd.h>
-#include <arch/drivers/fhc.h>
 #include <cpu.h>
 #include <arch/asm.h>
@@ -84,10 +83,12 @@
 	z8530_write_a(&z8530, WR0, WR0_TX_IP_RST);
 
-	z8530_write_a(&z8530, WR1, WR1_IARCSC);		/* interrupt on all characters */
+	/* interrupt on all characters */
+	z8530_write_a(&z8530, WR1, WR1_IARCSC);
 
 	/* 8 bits per character and enable receiver */
 	z8530_write_a(&z8530, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
 	
-	z8530_write_a(&z8530, WR9, WR9_MIE);		/* Master Interrupt Enable. */
+	/* Master Interrupt Enable. */
+	z8530_write_a(&z8530, WR9, WR9_MIE);
 	
 	spinlock_lock(&z8530_irq.lock);
@@ -109,5 +110,6 @@
 
 /** Initialize z8530. */
-void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr)
+void
+z8530_init(devno_t devno, uintptr_t vaddr, inr_t inr, cir_t cir, void *cir_arg)
 {
 	chardev_initialize("z8530_kbd", &kbrd, &ops);
@@ -122,4 +124,6 @@
 	z8530_irq.claim = z8530_claim;
 	z8530_irq.handler = z8530_irq_handler;
+	z8530_irq.cir = cir;
+	z8530_irq.cir_arg = cir_arg;
 	irq_register(&z8530_irq);
 
@@ -198,16 +202,8 @@
 void z8530_irq_handler(irq_t *irq, void *arg, ...)
 {
-	/*
-	 * So far, we know we got this interrupt through the FHC.
-	 * Since we don't have enough documentation about the FHC
-	 * and because the interrupt looks like level sensitive,
-	 * we cannot handle it by scheduling one of the level
-	 * interrupt traps. Process the interrupt directly.
-	 */
 	if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
 		ipc_irq_send_notif(irq);
 	else
 		z8530_interrupt();
-	fhc_clear_interrupt(central_fhc, irq->inr);
 }
 
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/src/ofw/ebus.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -45,5 +45,6 @@
 
 /** Apply EBUS ranges to EBUS register. */
-bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
+bool
+ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
 {
 	ofw_tree_property_t *prop;
@@ -63,9 +64,11 @@
 		if (reg->space != range[i].child_space)
 			continue;
-		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
+		if (overlaps(reg->addr, reg->size, range[i].child_base,
+		    range[i].size)) {
 			ofw_pci_reg_t pci_reg;
 			
 			pci_reg.space = range[i].parent_space;
-			pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base);
+			pci_reg.addr = range[i].parent_base +
+			    (reg->addr - range[i].child_base);
 			pci_reg.size = reg->size;
 			
@@ -77,5 +80,7 @@
 }
 
-bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr)
+bool
+ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg,
+    uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
 {
 	ofw_tree_property_t *prop;
@@ -105,6 +110,6 @@
 	unsigned int i;
 	for (i = 0; i < count; i++) {
-		if ((intr_map[i].space == space) && (intr_map[i].addr == addr)
-			&& (intr_map[i].intr == intr))
+		if ((intr_map[i].space == space) &&
+		    (intr_map[i].addr == addr) && (intr_map[i].intr == intr))
 			goto found;
 	}
@@ -114,8 +119,10 @@
 	/*
 	 * We found the device that functions as an interrupt controller
-	 * for the interrupt. We also found partial mapping from interrupt to INO.
+	 * for the interrupt. We also found partial mapping from interrupt to
+	 * INO.
 	 */
 
-	controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
+	controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"),
+	    intr_map[i].controller_handle);
 	if (!controller)
 		return false;
@@ -131,5 +138,6 @@
 	 * Let the PCI do the next step in mapping the interrupt.
 	 */
-	if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr))
+	if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino,
+	    inr, cir, cir_arg))
 		return false;
 
Index: kernel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/src/ofw/fhc.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -110,5 +110,7 @@
 }
 
-bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr)
+bool
+ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg,
+    uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
 {
 	fhc_t *fhc = NULL;
@@ -127,4 +129,6 @@
 	
 	*inr = interrupt;
+	*cir = fhc_clear_interrupt;
+	*cir_arg = fhc;
 	return true;
 }
Index: kernel/genarch/src/ofw/pci.c
===================================================================
--- kernel/genarch/src/ofw/pci.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/genarch/src/ofw/pci.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -50,5 +50,6 @@
 #define PCI_IGN			0x1f
 
-bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
+bool
+ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
 {
 	ofw_tree_property_t *prop;
@@ -69,8 +70,11 @@
 	
 	for (i = 0; i < ranges; i++) {
-		if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK))
+		if ((reg->space & PCI_SPACE_MASK) !=
+		    (range[i].space & PCI_SPACE_MASK))
 			continue;
-		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
-			*pa = range[i].parent_base + (reg->addr - range[i].child_base);
+		if (overlaps(reg->addr, reg->size, range[i].child_base,
+		    range[i].size)) {
+			*pa = range[i].parent_base +
+			    (reg->addr - range[i].child_base);
 			return true;
 		}
@@ -80,5 +84,7 @@
 }
 
-bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out)
+bool
+ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg,
+    ofw_pci_reg_t *out)
 {
 	if (reg->space & PCI_ABS_MASK) {
@@ -104,5 +110,6 @@
 	
 	for (i = 0; i < assigned_addresses; i++) {
-		if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) {
+		if ((assigned_address[i].space & PCI_REG_MASK) ==
+		    (reg->space & PCI_REG_MASK)) {
 			out->space = assigned_address[i].space;
 			out->addr = reg->addr + assigned_address[i].addr;
@@ -120,5 +127,7 @@
  * to a PCI bridge.
  */
-bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr)
+bool
+ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino,
+    int *inr, cir_t *cir, void **cir_arg)
 {
 	pci_t *pci = node->device;
@@ -133,4 +142,6 @@
 
 	*inr = (PCI_IGN << IGN_SHIFT) | ino;
+	*cir = pci_clear_interrupt;
+	*cir_arg = pci;
 
 	return true;
Index: kernel/generic/include/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/generic/include/ddi/irq.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -84,4 +84,7 @@
 typedef void (* irq_handler_t)(struct irq *irq, void *arg, ...);
 
+/** Type for function used to clear the interrupt. */
+typedef void (* cir_t)(void *arg, inr_t inr);
+
 /** IPC notification config structure.
  *
@@ -145,4 +148,9 @@
 	void *arg;
 
+	/** Clear interrupt routine. */
+	cir_t cir;
+	/** First argument to the clear interrupt routine. */
+	void *cir_arg;
+
 	/** Notification configuration structure. */
 	ipc_notif_cfg_t notif_cfg; 
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision dfd77382ed9624f5671e5680cd92fad49f395b3a)
+++ kernel/generic/src/ddi/irq.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -146,4 +146,6 @@
 	irq->handler = NULL;
 	irq->arg = NULL;
+	irq->cir = NULL;
+	irq->cir_arg = NULL;
 	irq->notif_cfg.notify = false;
 	irq->notif_cfg.answerbox = NULL;
