Index: kernel/genarch/src/kbd/z8530.c
===================================================================
--- kernel/genarch/src/kbd/z8530.c	(revision 36db5ac1d5864f5e63a519565d7d97f7fc18c184)
+++ kernel/genarch/src/kbd/z8530.c	(revision 0b414b5bfb083f200dcb33bd41d7b8a75f79142e)
@@ -39,5 +39,4 @@
 #include <genarch/kbd/scanc.h>
 #include <genarch/kbd/scanc_sun.h>
-#include <arch/drivers/fhc.h>
 #include <arch/drivers/z8530.h>
 #include <arch/interrupt.h>
@@ -107,12 +106,4 @@
 	
 	z8530_write_a(WR9, WR9_MIE);		/* Master Interrupt Enable. */
-	
-	/*
-	 * We need to initialize the FireHose Controller,
-	 * to which is this z8530 attached. Otherwise
-	 * interrupts generated by the z8530 would not
-	 * be forwarded to the CPU.
-	 */
-	fhc_init();
 }
 
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision 36db5ac1d5864f5e63a519565d7d97f7fc18c184)
+++ kernel/genarch/src/ofw/ebus.c	(revision 0b414b5bfb083f200dcb33bd41d7b8a75f79142e)
@@ -40,4 +40,5 @@
 #include <func.h>
 #include <panic.h>
+#include <debug.h>
 #include <macros.h>
 
@@ -74,4 +75,50 @@
 }
 
+bool ofw_ebus_map_interrupts(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *ino)
+{
+	ofw_tree_property_t *prop;
+	ofw_tree_node_t *controller;
+	
+	prop = ofw_tree_getprop(node, "interrupt-map");
+	if (!prop || !prop->value)
+		return false;
+
+	ofw_ebus_intr_map_t *intr_map = prop->value;
+	count_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
+	
+	ASSERT(count);
+	
+	prop = ofw_tree_getprop(node, "interrupt-map-mask");
+	if (!prop || !prop->value)
+		return false;
+	
+	ofw_ebus_intr_mask_t *intr_mask = prop->value;
+	
+	ASSERT(prop->size == sizeof(ofw_ebus_intr_mask_t));
+	
+	uint32_t space = reg->space & intr_mask->space_mask;
+	uint32_t addr = reg->addr & intr_mask->addr_mask;
+	uint32_t intr = interrupt & intr_mask->intr_mask;
+	
+	int i;
+	for (i = 0; i < count; i++) {
+		if ((intr_map[i].space == space) && (intr_map[i].addr == addr)
+			&& (intr_map[i].intr == intr))
+			goto found;
+	}
+	return false;
+
+found:
+	/*
+	 * We found the device that functions as an interrupt controller
+	 * for the interrupt. We also found mapping from interrupt to INO.
+	 */
+
+	controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
+	
+	*ino = intr_map[i].controller_ino;
+	return true;
+}
+
 /** @}
  */
Index: kernel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision 36db5ac1d5864f5e63a519565d7d97f7fc18c184)
+++ kernel/genarch/src/ofw/fhc.c	(revision 0b414b5bfb083f200dcb33bd41d7b8a75f79142e)
@@ -37,4 +37,5 @@
 
 #include <genarch/ofw/ofw_tree.h>
+#include <arch/drivers/fhc.h>
 #include <arch/memstr.h>
 #include <func.h>
@@ -109,4 +110,24 @@
 }
 
+bool ofw_fhc_map_interrupts(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *ino)
+{
+	fhc_t *fhc = NULL;
+	if (!node->device) {
+		fhc = fhc_init(node);
+		if (!fhc)
+			return false;
+		node->device = fhc;
+		central_fhc = fhc;
+	}
+	
+	/*
+	 * The interrupt controller for the interrupt is the FHC itself.
+	 */
+	fhc_enable_interrupt(fhc, interrupt);
+	
+	*ino = interrupt;
+	return true;
+}
+
 /** @}
  */
