Index: uspace/lib/libdrv/generic/driver.c
===================================================================
--- uspace/lib/libdrv/generic/driver.c	(revision cfe7716bf85413141220c5c75d82d669b65455dc)
+++ uspace/lib/libdrv/generic/driver.c	(revision 7f8b5815070a70217f19184d31a4e8837c21346f)
@@ -55,7 +55,68 @@
 #include "driver.h"
 
+// driver structure 
+
 static driver_t *driver;
+
+// devices
+
 LIST_INITIALIZE(devices);
 FIBRIL_MUTEX_INITIALIZE(devices_mutex);
+
+// interrupts 
+
+static interrupt_context_list_t interrupt_contexts;
+
+static irq_cmd_t default_cmds[] = {
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t default_pseudocode = {
+	sizeof(default_cmds) / sizeof(irq_cmd_t),
+	default_cmds
+};
+
+
+static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
+{
+	int id = (int)IPC_GET_METHOD(*icall);
+	interrupt_context_t *ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
+	(*ctx->handler)(ctx->dev, iid, icall);	
+}
+
+int register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, irq_code_t *pseudocode)
+{
+	interrupt_context_t *ctx = create_interrupt_context();
+	
+	ctx->dev = dev;
+	ctx->irq = irq;
+	ctx->handler = handler;
+	
+	add_interrupt_context(&interrupt_contexts, ctx);
+	
+	if (NULL == pseudocode) {
+		pseudocode = &default_pseudocode;
+	}
+	
+	int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode);
+	if (0 != res) {
+		remove_interrupt_context(&interrupt_contexts, ctx);
+		delete_interrupt_context(ctx);
+	}
+	return res;	
+}
+
+int unregister_interrupt_handler(device_t *dev, int irq)
+{
+	interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, dev, irq);
+	int res = ipc_unregister_irq(irq, dev->handle);
+	if (NULL != ctx) {
+		remove_interrupt_context(&interrupt_contexts, ctx);
+		delete_interrupt_context(ctx);		
+	}
+	return res;
+}
 
 static void add_to_devices_list(device_t *dev)
@@ -283,4 +344,10 @@
 	driver = drv;
 
+	// initialize the list of interrupt contexts
+	init_interrupt_context_list(&interrupt_contexts);
+	
+	// set generic interrupt handler
+	async_set_interrupt_received(driver_irq_handler);
+	
 	// register driver by device manager with generic handler for incoming connections
 	devman_driver_register(driver->name, driver_connection);
Index: uspace/lib/libdrv/include/driver.h
===================================================================
--- uspace/lib/libdrv/include/driver.h	(revision cfe7716bf85413141220c5c75d82d669b65455dc)
+++ uspace/lib/libdrv/include/driver.h	(revision 7f8b5815070a70217f19184d31a4e8837c21346f)
@@ -37,4 +37,5 @@
 
 #include <adt/list.h>
+#include <ipc/ipc.h>
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
@@ -165,15 +166,4 @@
 // interrupts
 
-static irq_cmd_t default_cmds[] = {
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t default_pseudocode = {
-	sizeof(default_cmds) / sizeof(irq_cmd_t),
-	default_cmds
-};
-
 typedef void interrupt_handler_t(device_t *dev, ipc_callid_t iid, ipc_call_t *icall);
 
@@ -270,4 +260,7 @@
 }
 
+int register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, irq_code_t *pseudocode);
+int unregister_interrupt_handler(device_t *dev, int irq);
+
 #endif
 
Index: uspace/srv/drivers/serial/serial.c
===================================================================
--- uspace/srv/drivers/serial/serial.c	(revision cfe7716bf85413141220c5c75d82d669b65455dc)
+++ uspace/srv/drivers/serial/serial.c	(revision 7f8b5815070a70217f19184d31a4e8837c21346f)
@@ -267,4 +267,17 @@
 }
 
+static void serial_interrupt_handler(device_t *dev, ipc_callid_t iid, ipc_call_t *icall)
+{
+	// TODO 
+}
+
+static inline int serial_register_interrupt_handler(device_t *dev)
+{
+	serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
+	
+	return register_interrupt_handler(dev, data->irq, serial_interrupt_handler, NULL);
+	
+}
+
 static int serial_add_device(device_t *dev) 
 {
@@ -290,5 +303,8 @@
 	serial_initialize_port(dev);
 	
-	// TODO register interrupt handler
+	// register interrupt handler
+	if (0 != serial_register_interrupt_handler(dev)) {
+		
+	}
 	
 	// enable interrupt
