Index: abi/include/abi/syscall.h
===================================================================
--- abi/include/abi/syscall.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ abi/include/abi/syscall.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -74,6 +74,7 @@
 	SYS_IPC_CONNECT_KBOX,
 	
-	SYS_EVENT_SUBSCRIBE,
-	SYS_EVENT_UNMASK,
+	SYS_IPC_EVENT_SUBSCRIBE,
+	SYS_IPC_EVENT_UNSUBSCRIBE,
+	SYS_IPC_EVENT_UNMASK,
 	
 	SYS_CAP_GRANT,
@@ -87,6 +88,7 @@
 	SYS_IOSPACE_ENABLE,
 	SYS_IOSPACE_DISABLE,
-	SYS_IRQ_REGISTER,
-	SYS_IRQ_UNREGISTER,
+	
+	SYS_IPC_IRQ_SUBSCRIBE,
+	SYS_IPC_IRQ_UNSUBSCRIBE,
 	
 	SYS_SYSINFO_GET_KEYS_SIZE,
Index: kernel/generic/include/ipc/event.h
===================================================================
--- kernel/generic/include/ipc/event.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/include/ipc/event.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -100,6 +100,7 @@
     sysarg_t, sysarg_t, sysarg_t);
 
-extern sysarg_t sys_event_subscribe(sysarg_t, sysarg_t);
-extern sysarg_t sys_event_unmask(sysarg_t);
+extern sysarg_t sys_ipc_event_subscribe(sysarg_t, sysarg_t);
+extern sysarg_t sys_ipc_event_unsubscribe(sysarg_t);
+extern sysarg_t sys_ipc_event_unmask(sysarg_t);
 
 #endif
Index: kernel/generic/include/ipc/irq.h
===================================================================
--- kernel/generic/include/ipc/irq.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/include/ipc/irq.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -47,5 +47,5 @@
 #include <adt/list.h>
 
-extern int ipc_irq_register(answerbox_t *, inr_t, devno_t, sysarg_t,
+extern int ipc_irq_subscribe(answerbox_t *, inr_t, devno_t, sysarg_t,
     irq_code_t *);
 
@@ -53,5 +53,5 @@
 extern void ipc_irq_top_half_handler(irq_t *);
 
-extern int ipc_irq_unregister(answerbox_t *, inr_t, devno_t);
+extern int ipc_irq_unsubscribe(answerbox_t *, inr_t, devno_t);
 extern void ipc_irq_cleanup(answerbox_t *);
 
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/include/ipc/sysipc.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -53,6 +53,7 @@
     unsigned int);
 extern sysarg_t sys_ipc_hangup(sysarg_t);
-extern sysarg_t sys_irq_register(inr_t, devno_t, sysarg_t, irq_code_t *);
-extern sysarg_t sys_irq_unregister(inr_t, devno_t);
+
+extern sysarg_t sys_ipc_irq_subscribe(inr_t, devno_t, sysarg_t, irq_code_t *);
+extern sysarg_t sys_ipc_irq_unsubscribe(inr_t, devno_t);
 
 #ifdef __32_BITS__
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/src/ipc/event.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -58,15 +58,15 @@
 }
 
-static event_t *evno2event(int evno, task_t *t)
+static event_t *evno2event(int evno, task_t *task)
 {
 	ASSERT(evno < EVENT_TASK_END);
-
+	
 	event_t *event;
-
+	
 	if (evno < EVENT_END)
 		event = &events[(event_type_t) evno];
 	else
-		event = &t->events[(event_task_type_t) evno - EVENT_END];
-
+		event = &task->events[(event_task_type_t) evno - EVENT_END];
+	
 	return event;
 }
@@ -86,5 +86,4 @@
 		event_initialize(evno2event(i, task));
 }
-
 
 /** Unsubscribe kernel events associated with an answerbox
@@ -260,5 +259,5 @@
 {
 	int res;
-
+	
 	spinlock_lock(&event->lock);
 	
@@ -277,4 +276,34 @@
 }
 
+/** Unsubscribe event notifications
+ *
+ * @param evno      Event type.
+ * @param answerbox Answerbox used to send the notifications to.
+ *
+ * @return EOK if the subscription was successful.
+ * @return EEXISTS if the notifications of the given type are
+ *         already subscribed.
+ *
+ */
+static int event_unsubscribe(event_t *event, answerbox_t *answerbox)
+{
+	int res;
+	
+	spinlock_lock(&event->lock);
+	
+	if (event->answerbox == answerbox) {
+		event->answerbox = NULL;
+		event->counter = 0;
+		event->imethod = 0;
+		event->masked = false;
+		res = EOK;
+	} else
+		res = ENOENT;
+	
+	spinlock_unlock(&event->lock);
+	
+	return res;
+}
+
 /** Unmask event notifications
  *
@@ -297,5 +326,5 @@
 }
 
-/** Event notification syscall wrapper
+/** Event notification subscription syscall wrapper
  *
  * @param evno    Event type to subscribe.
@@ -309,5 +338,5 @@
  *
  */
-sysarg_t sys_event_subscribe(sysarg_t evno, sysarg_t imethod)
+sysarg_t sys_ipc_event_subscribe(sysarg_t evno, sysarg_t imethod)
 {
 	if (evno >= EVENT_TASK_END)
@@ -316,4 +345,23 @@
 	return (sysarg_t) event_subscribe(evno2event(evno, TASK),
 	    (sysarg_t) imethod, &TASK->answerbox);
+}
+
+/** Event notification unsubscription syscall wrapper
+ *
+ * @param evno    Event type to unsubscribe.
+ *
+ * @return EOK on success.
+ * @return ELIMIT on unknown event type.
+ * @return ENOENT if the notification of the given type is not
+           subscribed.
+ *
+ */
+sysarg_t sys_ipc_event_unsubscribe(sysarg_t evno)
+{
+	if (evno >= EVENT_TASK_END)
+		return ELIMIT;
+	
+	return (sysarg_t) event_unsubscribe(evno2event(evno, TASK),
+	    &TASK->answerbox);
 }
 
@@ -331,5 +379,5 @@
  *
  */
-sysarg_t sys_event_unmask(sysarg_t evno)
+sysarg_t sys_ipc_event_unmask(sysarg_t evno)
 {
 	if (evno >= EVENT_TASK_END)
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/src/ipc/irq.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -36,5 +36,5 @@
  * @brief IRQ notification framework.
  *
- * This framework allows applications to register to receive a notification
+ * This framework allows applications to subscribe to receive a notification
  * when interrupt is detected. The application may provide a simple 'top-half'
  * handler as part of its registration, which can perform simple operations
@@ -42,6 +42,5 @@
  *
  * The structure of a notification message is as follows:
- * - IMETHOD: interface and method as registered by
- *            the SYS_IRQ_REGISTER syscall
+ * - IMETHOD: interface and method as set by the SYS_IPC_IRQ_SUBSCRIBE syscall
  * - ARG1: payload modified by a 'top-half' handler (scratch[1])
  * - ARG2: payload modified by a 'top-half' handler (scratch[2])
@@ -52,5 +51,5 @@
  *                  in multithreaded drivers)
  *
- * Note on synchronization for ipc_irq_register(), ipc_irq_unregister(),
+ * Note on synchronization for ipc_irq_subscribe(), ipc_irq_unsubscribe(),
  * ipc_irq_cleanup() and IRQ handlers:
  *
@@ -289,5 +288,5 @@
 }
 
-/** Register an answerbox as a receiving end for IRQ notifications.
+/** Subscribe an answerbox as a receiving end for IRQ notifications.
  *
  * @param box     Receiving answerbox.
@@ -301,5 +300,5 @@
  *
  */
-int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno,
+int ipc_irq_subscribe(answerbox_t *box, inr_t inr, devno_t devno,
     sysarg_t imethod, irq_code_t *ucode)
 {
@@ -369,5 +368,5 @@
 }
 
-/** Unregister task from IRQ notification.
+/** Unsubscribe task from IRQ notification.
  *
  * @param box   Answerbox associated with the notification.
@@ -378,5 +377,5 @@
  *
  */
-int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
+int ipc_irq_unsubscribe(answerbox_t *box, inr_t inr, devno_t devno)
 {
 	sysarg_t key[] = {
@@ -432,5 +431,5 @@
  *
  * This function is effective because the answerbox contains
- * list of all irq_t structures that are registered to
+ * list of all irq_t structures that are subscribed to
  * send notifications to it.
  *
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/src/ipc/sysipc.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -736,8 +736,8 @@
  * @param ucode   Uspace pointer to the top-half pseudocode.
  *
- * @return EPERM or a return code returned by ipc_irq_register().
- *
- */
-sysarg_t sys_irq_register(inr_t inr, devno_t devno, sysarg_t imethod,
+ * @return EPERM or a return code returned by ipc_irq_subscribe().
+ *
+ */
+sysarg_t sys_ipc_irq_subscribe(inr_t inr, devno_t devno, sysarg_t imethod,
     irq_code_t *ucode)
 {
@@ -745,5 +745,5 @@
 		return EPERM;
 	
-	return ipc_irq_register(&TASK->answerbox, inr, devno, imethod, ucode);
+	return ipc_irq_subscribe(&TASK->answerbox, inr, devno, imethod, ucode);
 }
 
@@ -756,10 +756,10 @@
  *
  */
-sysarg_t sys_irq_unregister(inr_t inr, devno_t devno)
+sysarg_t sys_ipc_irq_unsubscribe(inr_t inr, devno_t devno)
 {
 	if (!(cap_get(TASK) & CAP_IRQ_REG))
 		return EPERM;
 	
-	ipc_irq_unregister(&TASK->answerbox, inr, devno);
+	ipc_irq_unsubscribe(&TASK->answerbox, inr, devno);
 	
 	return 0;
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ kernel/generic/src/syscall/syscall.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -165,6 +165,7 @@
 	
 	/* Event notification syscalls. */
-	(syshandler_t) sys_event_subscribe,
-	(syshandler_t) sys_event_unmask,
+	(syshandler_t) sys_ipc_event_subscribe,
+	(syshandler_t) sys_ipc_event_unsubscribe,
+	(syshandler_t) sys_ipc_event_unmask,
 	
 	/* Capabilities related syscalls. */
@@ -180,6 +181,7 @@
 	(syshandler_t) sys_iospace_enable,
 	(syshandler_t) sys_iospace_disable,
-	(syshandler_t) sys_irq_register,
-	(syshandler_t) sys_irq_unregister,
+	
+	(syshandler_t) sys_ipc_irq_subscribe,
+	(syshandler_t) sys_ipc_irq_unsubscribe,
 	
 	/* Sysinfo syscalls. */
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/app/kio/kio.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -39,5 +39,4 @@
 #include <as.h>
 #include <ddi.h>
-#include <event.h>
 #include <errno.h>
 #include <str_error.h>
@@ -149,5 +148,6 @@
  *
  */
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+static void kio_notification_handler(ipc_callid_t callid, ipc_call_t *call,
+    void *arg)
 {
 	/*
@@ -181,5 +181,5 @@
 		producer(kio_stored, kio + offset);
 	
-	event_unmask(EVENT_KIO);
+	async_event_unmask(EVENT_KIO);
 	fibril_mutex_unlock(&mtx);
 }
@@ -214,6 +214,5 @@
 	
 	prodcons_initialize(&pc);
-	async_set_interrupt_received(notification_received);
-	rc = event_subscribe(EVENT_KIO, 0);
+	rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
 	if (rc != EOK) {
 		fprintf(stderr, "%s: Unable to register kio notifications\n",
@@ -233,8 +232,8 @@
 		fprintf(stderr, "%s: Could not create input\n", NAME);
 		return ENOMEM;
-	}	
+	}
 
 	fibril_add_ready(fid);
-	event_unmask(EVENT_KIO);
+	async_event_unmask(EVENT_KIO);
 	kio_update();
 	
@@ -251,7 +250,7 @@
 		free(str);
 	}
- 
+
 	if (rc == ENOENT)
-		rc = EOK;	
+		rc = EOK;
 
 	return EOK;
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/app/trace/syscalls.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -65,5 +65,7 @@
     [SYS_IPC_HANGUP] = { "ipc_hangup",			1,	V_ERRNO },
 
-    [SYS_EVENT_SUBSCRIBE] = { "event_subscribe",	2,	V_ERRNO },
+    [SYS_IPC_EVENT_SUBSCRIBE] = { "ipc_event_subscribe",	2,	V_ERRNO },
+    [SYS_IPC_EVENT_UNSUBSCRIBE] = { "ipc_event_unsubscribe",	1,	V_ERRNO },
+    [SYS_IPC_EVENT_UNMASK] = { "ipc_event_unmask",	1,	V_ERRNO },
 
     [SYS_CAP_GRANT] = { "cap_grant",			2,	V_ERRNO },
@@ -71,6 +73,7 @@
     [SYS_PHYSMEM_MAP] = { "physmem_map",		4,	V_ERRNO },
     [SYS_IOSPACE_ENABLE] = { "iospace_enable",		1,	V_ERRNO },
-    [SYS_IRQ_REGISTER] = { "irq_register",	4,	V_ERRNO },
-    [SYS_IRQ_UNREGISTER] = { "irq_unregister",	2,	V_ERRNO },
+
+    [SYS_IPC_IRQ_SUBSCRIBE] = { "ipc_irq_subscribe",	4,	V_ERRNO },
+    [SYS_IPC_IRQ_UNSUBSCRIBE] = { "ipc_irq_unsubscribe",	2,	V_ERRNO },
 
     [SYS_SYSINFO_GET_VAL_TYPE] = { "sysinfo_get_val_type",		2,	V_INTEGER },
Index: uspace/drv/audio/sb16/main.c
===================================================================
--- uspace/drv/audio/sb16/main.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/audio/sb16/main.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -77,5 +77,5 @@
 }
 
-static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
+static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev)
 {
 	sb16_t *sb16_dev = ddf_dev_data_get(dev);
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/block/ahci/ahci.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -890,10 +890,10 @@
 /** AHCI interrupt handler.
  *
- * @param dev   DDF device structure.
  * @param iid   The IPC call id.
  * @param icall The IPC call structure.
- *
- */
-static void ahci_interrupt(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *icall)
+ * @param dev   DDF device structure.
+ *
+ */
+static void ahci_interrupt(ipc_callid_t iid, ipc_call_t *icall, ddf_dev_t *dev)
 {
 	ahci_dev_t *ahci = dev_ahci_dev(dev);
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -59,12 +59,13 @@
 /** IRQ handling callback, identifies device
  *
- * @param[in] dev DDF instance of the device to use.
  * @param[in] iid (Unused).
  * @param[in] call Pointer to the call that represents interrupt.
- */
-static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
+ * @param[in] dev DDF instance of the device to use.
+ *
+ */
+static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev)
 {
 	assert(dev);
-
+	
 	ohci_t *ohci = dev_to_ohci(dev);
 	if (!ohci) {
@@ -72,4 +73,5 @@
 		return;
 	}
+	
 	const uint16_t status = IPC_GET_ARG1(*call);
 	hc_interrupt(&ohci->hc, status);
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -151,5 +151,5 @@
 		return rc;
 	}
-
+	
 	irq_code_t irq_code = {
 		.rangecount = hc_irq_pio_range_count,
@@ -158,13 +158,13 @@
 		.cmds = irq_cmds
 	};
-
-        /* Register handler to avoid interrupt lockup */
-        rc = register_interrupt_handler(device, irq, handler, &irq_code);
-        if (rc != EOK) {
-    		usb_log_error("Failed to register interrupt handler: %s.\n",
-    		    str_error(rc));
-    		return rc;
-    	}
-
+	
+	/* Register handler to avoid interrupt lockup */
+	rc = register_interrupt_handler(device, irq, handler, &irq_code);
+	if (rc != EOK) {
+		usb_log_error("Failed to register interrupt handler: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	
 	return EOK;
 }
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -69,11 +69,13 @@
 /** IRQ handling callback, forward status from call to diver structure.
  *
- * @param[in] dev DDF instance of the device to use.
  * @param[in] iid (Unused).
  * @param[in] call Pointer to the call from kernel.
- */
-static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
+ * @param[in] dev DDF instance of the device to use.
+ *
+ */
+static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev)
 {
 	assert(dev);
+	
 	uhci_t *uhci = dev_to_uhci(dev);
 	if (!uhci) {
@@ -81,4 +83,5 @@
 		return;
 	}
+	
 	const uint16_t status = IPC_GET_ARG1(*call);
 	hc_interrupt(&uhci->hc, status);
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/char/i8042/i8042.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -64,9 +64,9 @@
 #define i8042_KBD_TRANSLATE  0x40  /* Use this to switch to XT scancodes */
 
-void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
+static void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
 
 /** Port function operations. */
 static ddf_dev_ops_t ops = {
-	.default_handler = default_handler,
+	.default_handler = default_handler
 };
 
@@ -123,11 +123,11 @@
  * Write new data to the corresponding buffer.
  *
- * @param dev  Device that caued the interrupt.
  * @param iid  Call id.
  * @param call pointerr to call data.
- *
- */
-static void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *call)
+ * @param dev  Device that caued the interrupt.
+ *
+ */
+static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call,
+    ddf_dev_t *dev)
 {
 	i8042_t *controller = dev_i8042(dev);
@@ -361,5 +361,5 @@
  *
  */
-void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
+static void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
 {
 	const sysarg_t method = IPC_GET_IMETHOD(*call);
Index: uspace/drv/char/i8042/i8042.h
===================================================================
--- uspace/drv/char/i8042/i8042.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/char/i8042/i8042.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -68,5 +68,5 @@
 } i8042_t;
 
-int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *);
+extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *);
 
 #endif
Index: uspace/drv/char/i8042/main.c
===================================================================
--- uspace/drv/char/i8042/main.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/char/i8042/main.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -157,5 +157,5 @@
 	 * interrupt storms when the default large stacks are used.
 	 */
-	async_set_interrupt_handler_stack_size(PAGE_SIZE);
+	async_set_notification_handler_stack_size(PAGE_SIZE);
 
 	return ddf_driver_main(&i8042_driver);
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/char/ns8250/ns8250.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -764,8 +764,9 @@
  * data and reading the line status register.
  *
- * @param dev		The serial port device.
- */
-static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *icall)
+ * @param dev The serial port device.
+ *
+ */
+static inline void ns8250_interrupt_handler(ipc_callid_t iid, ipc_call_t *icall,
+    ddf_dev_t *dev)
 {
 	ns8250_t *ns = dev_ns8250(dev);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/nic/e1k/e1k.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -1229,11 +1229,11 @@
 /** Handle device interrupt
  *
- * @param dev   E1000 device
  * @param iid   IPC call id
  * @param icall IPC call structure
- *
- */
-static void e1000_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *icall)
+ * @param dev   E1000 device
+ *
+ */
+static void e1000_interrupt_handler(ipc_callid_t iid, ipc_call_t *icall,
+    ddf_dev_t *dev)
 {
 	uint32_t icr = (uint32_t) IPC_GET_ARG2(*icall);
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -122,6 +122,5 @@
 };
 
-static void ne2k_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
-	ipc_call_t *call);
+static void ne2k_interrupt_handler(ipc_callid_t, ipc_call_t *, ddf_dev_t *);
 
 static int ne2k_register_interrupt(nic_t *nic_data)
@@ -240,9 +239,9 @@
 }
 
-void ne2k_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
+void ne2k_interrupt_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev)
 {
 	nic_t *nic_data = DRIVER_DATA(dev);
 	ne2k_interrupt(nic_data, IRQ_GET_ISR(*call), IRQ_GET_TSR(*call));
-
+	
 	async_answer_0(iid, EOK);
 }
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/nic/rtl8139/driver.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -852,10 +852,11 @@
 /** Handle device interrupt
  *
- *  @param dev    The rtl8139 device
- *  @param iid    The IPC call id
- *  @param icall  The IPC call structure
- */
-static void rtl8139_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *icall)
+ * @param iid    The IPC call id
+ * @param icall  The IPC call structure
+ * @param dev    The rtl8139 device
+ *
+ */
+static void rtl8139_interrupt_handler(ipc_callid_t iid, ipc_call_t *icall,
+    ddf_dev_t *dev)
 {
 	assert(dev);
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/drv/nic/rtl8169/driver.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -76,6 +76,6 @@
 static int rtl8169_on_stopped(nic_t *nic_data);
 static void rtl8169_send_frame(nic_t *nic_data, void *data, size_t size);
-static void rtl8169_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *icall);
+static void rtl8169_irq_handler(ipc_callid_t iid, ipc_call_t *icall,
+    ddf_dev_t *dev);
 static inline int rtl8169_register_int_handler(nic_t *nic_data);
 static inline void rtl8169_get_hwaddr(rtl8169_t *rtl8169, nic_address_t *addr);
@@ -897,6 +897,6 @@
 }
 
-static void rtl8169_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
-    ipc_call_t *icall)
+static void rtl8169_irq_handler(ipc_callid_t iid, ipc_call_t *icall,
+    ddf_dev_t *dev)
 {
 	assert(dev);
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/Makefile	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -110,4 +110,5 @@
 	generic/iplink_srv.c \
 	generic/irc.c \
+	generic/irq.c \
 	generic/ieee_double.c \
 	generic/power_of_ten.c \
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/generic/async.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -101,4 +101,6 @@
 #undef LIBC_ASYNC_C_
 
+#include <ipc/irq.h>
+#include <ipc/event.h>
 #include <futex.h>
 #include <fibril.h>
@@ -116,5 +118,4 @@
 #include "private/libc.h"
 
-
 /** Session data */
 struct async_sess {
@@ -242,4 +243,18 @@
 	async_client_conn_t cfibril;
 } connection_t;
+
+/* Notification data */
+typedef struct {
+	ht_link_t link;
+	
+	/** Notification method */
+	sysarg_t imethod;
+	
+	/** Notification handler */
+	async_notification_handler_t handler;
+	
+	/** Notification data */
+	void *data;
+} notification_t;
 
 /** Identifier of the incoming connection handled by the current fibril. */
@@ -335,20 +350,6 @@
 }
 
-/** Default fibril function that gets called to handle interrupt notifications.
- *
- * This function is defined as a weak symbol - to be redefined in user code.
- *
- * @param callid Hash of the incoming call.
- * @param call   Data of the incoming call.
- * @param arg    Local argument.
- *
- */
-static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
-{
-}
-
 static async_client_conn_t client_connection = default_client_connection;
-static async_interrupt_handler_t interrupt_received = default_interrupt_received;
-static size_t interrupt_handler_stksz = FIBRIL_DFLT_STK_SIZE;
+static size_t notification_handler_stksz = FIBRIL_DFLT_STK_SIZE;
 
 /** Setter for client_connection function pointer.
@@ -363,21 +364,11 @@
 }
 
-/** Setter for interrupt_received function pointer.
- *
- * @param intr Function that will implement a new interrupt
- *             notification fibril.
- */
-void async_set_interrupt_received(async_interrupt_handler_t intr)
-{
-	interrupt_received = intr;
-}
-
-/** Set the stack size for the interrupt handler notification fibrils.
+/** Set the stack size for the notification handler notification fibrils.
  *
  * @param size Stack size in bytes.
  */
-void async_set_interrupt_handler_stack_size(size_t size)
-{
-	interrupt_handler_stksz = size;
+void async_set_notification_handler_stack_size(size_t size)
+{
+	notification_handler_stksz = size;
 }
 
@@ -399,10 +390,13 @@
 static hash_table_t client_hash_table;
 static hash_table_t conn_hash_table;
+static hash_table_t notification_hash_table;
 static LIST_INITIALIZE(timeout_list);
 
-static size_t client_key_hash(void *k)
-{
-	task_id_t key = *(task_id_t*)k;
-	return key;
+static sysarg_t notification_avail = 0;
+
+static size_t client_key_hash(void *key)
+{
+	task_id_t in_task_id = *(task_id_t *) key;
+	return in_task_id;
 }
 
@@ -413,11 +407,10 @@
 }
 
-static bool client_key_equal(void *k, const ht_link_t *item)
-{
-	task_id_t key = *(task_id_t*)k;
+static bool client_key_equal(void *key, const ht_link_t *item)
+{
+	task_id_t in_task_id = *(task_id_t *) key;
 	client_t *client = hash_table_get_inst(item, client_t, link);
-	return key == client->in_task_id;
-}
-
+	return in_task_id == client->in_task_id;
+}
 
 /** Operations for the client hash table. */
@@ -439,6 +432,6 @@
 static size_t conn_key_hash(void *key)
 {
-	sysarg_t in_phone_hash  = *(sysarg_t*)key;
-	return in_phone_hash ;
+	sysarg_t in_phone_hash = *(sysarg_t *) key;
+	return in_phone_hash;
 }
 
@@ -451,9 +444,8 @@
 static bool conn_key_equal(void *key, const ht_link_t *item)
 {
-	sysarg_t in_phone_hash = *(sysarg_t*)key;
+	sysarg_t in_phone_hash = *(sysarg_t *) key;
 	connection_t *conn = hash_table_get_inst(item, connection_t, link);
 	return (in_phone_hash == conn->in_phone_hash);
 }
-
 
 /** Operations for the connection hash table. */
@@ -462,4 +454,34 @@
 	.key_hash = conn_key_hash,
 	.key_equal = conn_key_equal,
+	.equal = NULL,
+	.remove_callback = NULL
+};
+
+static size_t notification_key_hash(void *key)
+{
+	sysarg_t id = *(sysarg_t *) key;
+	return id;
+}
+
+static size_t notification_hash(const ht_link_t *item)
+{
+	notification_t *notification =
+	    hash_table_get_inst(item, notification_t, link);
+	return notification_key_hash(&notification->imethod);
+}
+
+static bool notification_key_equal(void *key, const ht_link_t *item)
+{
+	sysarg_t id = *(sysarg_t *) key;
+	notification_t *notification =
+	    hash_table_get_inst(item, notification_t, link);
+	return id == notification->imethod;
+}
+
+/** Operations for the notification hash table. */
+static hash_table_ops_t notification_hash_table_ops = {
+	.hash = notification_hash,
+	.key_hash = notification_key_hash,
+	.key_equal = notification_key_equal,
 	.equal = NULL,
 	.remove_callback = NULL
@@ -511,12 +533,11 @@
 	futex_down(&async_futex);
 	
-	ht_link_t *hlp = hash_table_find(&conn_hash_table, &call->in_phone_hash);
-	
-	if (!hlp) {
+	ht_link_t *link = hash_table_find(&conn_hash_table, &call->in_phone_hash);
+	if (!link) {
 		futex_up(&async_futex);
 		return false;
 	}
 	
-	connection_t *conn = hash_table_get_inst(hlp, connection_t, link);
+	connection_t *conn = hash_table_get_inst(link, connection_t, link);
 	
 	msg_t *msg = malloc(sizeof(*msg));
@@ -553,5 +574,6 @@
  *
  * When a notification arrives, a fibril with this implementing function is
- * created. It calls interrupt_received() and does the final cleanup.
+ * created. It calls the corresponding notification handler and does the final
+ * cleanup.
  *
  * @param arg Message structure pointer.
@@ -565,5 +587,22 @@
 	
 	msg_t *msg = (msg_t *) arg;
-	interrupt_received(msg->callid, &msg->call);
+	async_notification_handler_t handler = NULL;
+	void *data = NULL;
+	
+	futex_down(&async_futex);
+	
+	ht_link_t *link = hash_table_find(&notification_hash_table,
+	    &IPC_GET_IMETHOD(msg->call));
+	if (link) {
+		notification_t *notification =
+		    hash_table_get_inst(link, notification_t, link);
+		handler = notification->handler;
+		data = notification->data;
+	}
+	
+	futex_up(&async_futex);
+	
+	if (handler)
+		handler(msg->callid, &msg->call, data);
 	
 	free(msg);
@@ -571,5 +610,5 @@
 }
 
-/** Process interrupt notification.
+/** Process notification.
  *
  * A new fibril is created which would process the notification.
@@ -598,5 +637,5 @@
 	
 	fid_t fid = fibril_create_generic(notification_fibril, msg,
-	    interrupt_handler_stksz);
+	    notification_handler_stksz);
 	if (fid == 0) {
 		free(msg);
@@ -609,4 +648,145 @@
 	futex_up(&async_futex);
 	return true;
+}
+
+/** Subscribe to IRQ notification.
+ *
+ * @param inr     IRQ number.
+ * @param devno   Device number of the device generating inr.
+ * @param handler Notification handler.
+ * @param data    Notification handler client data.
+ * @param ucode   Top-half pseudocode handler.
+ *
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_irq_subscribe(int inr, int devno,
+    async_notification_handler_t handler, void *data, const irq_code_t *ucode)
+{
+	notification_t *notification =
+	    (notification_t *) malloc(sizeof(notification_t));
+	if (!notification)
+		return ENOMEM;
+	
+	futex_down(&async_futex);
+	
+	sysarg_t imethod = notification_avail;
+	notification_avail++;
+	
+	notification->imethod = imethod;
+	notification->handler = handler;
+	notification->data = data;
+	
+	hash_table_insert(&notification_hash_table, &notification->link);
+	
+	futex_up(&async_futex);
+	
+	return ipc_irq_subscribe(inr, devno, imethod, ucode);
+}
+
+/** Unsubscribe from IRQ notification.
+ *
+ * @param inr     IRQ number.
+ * @param devno   Device number of the device generating inr.
+ *
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_irq_unsubscribe(int inr, int devno)
+{
+	// TODO: Remove entry from hash table
+	//       to avoid memory leak
+	
+	return ipc_irq_unsubscribe(inr, devno);
+}
+
+/** Subscribe to event notifications.
+ *
+ * @param evno    Event type to subscribe.
+ * @param handler Notification handler.
+ * @param data    Notification handler client data.
+ *
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_event_subscribe(event_type_t evno,
+    async_notification_handler_t handler, void *data)
+{
+	notification_t *notification =
+	    (notification_t *) malloc(sizeof(notification_t));
+	if (!notification)
+		return ENOMEM;
+	
+	futex_down(&async_futex);
+	
+	sysarg_t imethod = notification_avail;
+	notification_avail++;
+	
+	notification->imethod = imethod;
+	notification->handler = handler;
+	notification->data = data;
+	
+	hash_table_insert(&notification_hash_table, &notification->link);
+	
+	futex_up(&async_futex);
+	
+	return ipc_event_subscribe(evno, imethod);
+}
+
+/** Subscribe to task event notifications.
+ *
+ * @param evno    Event type to subscribe.
+ * @param handler Notification handler.
+ * @param data    Notification handler client data.
+ *
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_event_task_subscribe(event_task_type_t evno,
+    async_notification_handler_t handler, void *data)
+{
+	notification_t *notification =
+	    (notification_t *) malloc(sizeof(notification_t));
+	if (!notification)
+		return ENOMEM;
+	
+	futex_down(&async_futex);
+	
+	sysarg_t imethod = notification_avail;
+	notification_avail++;
+	
+	notification->imethod = imethod;
+	notification->handler = handler;
+	notification->data = data;
+	
+	hash_table_insert(&notification_hash_table, &notification->link);
+	
+	futex_up(&async_futex);
+	
+	return ipc_event_task_subscribe(evno, imethod);
+}
+
+/** Unmask event notifications.
+ *
+ * @param evno Event type to unmask.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int async_event_unmask(event_type_t evno)
+{
+	return ipc_event_unmask(evno);
+}
+
+/** Unmask task event notifications.
+ *
+ * @param evno Event type to unmask.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int async_event_task_unmask(event_task_type_t evno)
+{
+	return ipc_event_task_unmask(evno);
 }
 
@@ -702,7 +882,7 @@
 
 	futex_down(&async_futex);
-	ht_link_t *lnk = hash_table_find(&client_hash_table, &client_id);
-	if (lnk) {
-		client = hash_table_get_inst(lnk, client_t, link);
+	ht_link_t *link = hash_table_find(&client_hash_table, &client_id);
+	if (link) {
+		client = hash_table_get_inst(link, client_t, link);
 		atomic_inc(&client->refcnt);
 	} else if (create) {
@@ -1106,4 +1286,8 @@
 	
 	if (!hash_table_create(&conn_hash_table, 0, 0, &conn_hash_table_ops))
+		abort();
+	
+	if (!hash_table_create(&notification_hash_table, 0, 0,
+	    &notification_hash_table_ops))
 		abort();
 	
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/generic/ddi.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -312,33 +312,4 @@
 }
 
-/** Register IRQ notification.
- *
- * @param inr    IRQ number.
- * @param devno  Device number of the device generating inr.
- * @param method Use this method for notifying me.
- * @param ucode  Top-half pseudocode handler.
- *
- * @return Value returned by the kernel.
- *
- */
-int irq_register(int inr, int devno, int method, const irq_code_t *ucode)
-{
-	return __SYSCALL4(SYS_IRQ_REGISTER, inr, devno, method,
-	    (sysarg_t) ucode);
-}
-
-/** Unregister IRQ notification.
- *
- * @param inr   IRQ number.
- * @param devno Device number of the device generating inr.
- *
- * @return Value returned by the kernel.
- *
- */
-int irq_unregister(int inr, int devno)
-{
-	return __SYSCALL2(SYS_IRQ_UNREGISTER, inr, devno);
-}
-
 /** @}
  */
Index: uspace/lib/c/generic/event.c
===================================================================
--- uspace/lib/c/generic/event.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/generic/event.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -38,7 +38,7 @@
 
 #include <libc.h>
-#include <event.h>
+#include <ipc/event.h>
 
-/** Subscribe event notifications.
+/** Subscribe to event notifications.
  *
  * @param evno    Event type to subscribe.
@@ -48,14 +48,46 @@
  *
  */
-int event_subscribe(event_type_t evno, sysarg_t imethod)
+int ipc_event_subscribe(event_type_t evno, sysarg_t imethod)
 {
-	return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
+	return __SYSCALL2(SYS_IPC_EVENT_SUBSCRIBE, (sysarg_t) evno,
 	    (sysarg_t) imethod);
 }
 
-int event_task_subscribe(event_task_type_t evno, sysarg_t imethod)
+/** Subscribe to task event notifications.
+ *
+ * @param evno    Event type to subscribe.
+ * @param imethod Use this interface and method for notifying me.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_event_task_subscribe(event_task_type_t evno, sysarg_t imethod)
 {
-	return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
+	return __SYSCALL2(SYS_IPC_EVENT_SUBSCRIBE, (sysarg_t) evno,
 	    (sysarg_t) imethod);
+}
+
+/** Unsubscribe from event notifications.
+ *
+ * @param evno    Event type to unsubscribe.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_event_unsubscribe(event_type_t evno)
+{
+	return __SYSCALL1(SYS_IPC_EVENT_UNSUBSCRIBE, (sysarg_t) evno);
+}
+
+/** Unsubscribe from task event notifications.
+ *
+ * @param evno    Event type to unsubscribe.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_event_task_unsubscribe(event_task_type_t evno)
+{
+	return __SYSCALL1(SYS_IPC_EVENT_UNSUBSCRIBE, (sysarg_t) evno);
 }
 
@@ -67,12 +99,19 @@
  *
  */
-int event_unmask(event_type_t evno)
+int ipc_event_unmask(event_type_t evno)
 {
-	return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
+	return __SYSCALL1(SYS_IPC_EVENT_UNMASK, (sysarg_t) evno);
 }
 
-int event_task_unmask(event_task_type_t evno)
+/** Unmask task event notifications.
+ *
+ * @param evno Event type to unmask.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_event_task_unmask(event_task_type_t evno)
 {
-	return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
+	return __SYSCALL1(SYS_IPC_EVENT_UNMASK, (sysarg_t) evno);
 }
 
Index: uspace/lib/c/generic/irq.c
===================================================================
--- uspace/lib/c/generic/irq.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ uspace/lib/c/generic/irq.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/irq.h>
+#include <libc.h>
+
+/** Subscribe to IRQ notification.
+ *
+ * @param inr    IRQ number.
+ * @param devno  Device number of the device generating inr.
+ * @param method Use this method for notifying me.
+ * @param ucode  Top-half pseudocode handler.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_irq_subscribe(int inr, int devno, sysarg_t method,
+    const irq_code_t *ucode)
+{
+	return __SYSCALL4(SYS_IPC_IRQ_SUBSCRIBE, inr, devno, method,
+	    (sysarg_t) ucode);
+}
+
+/** Unsubscribe from IRQ notification.
+ *
+ * @param inr   IRQ number.
+ * @param devno Device number of the device generating inr.
+ *
+ * @return Value returned by the kernel.
+ *
+ */
+int ipc_irq_unsubscribe(int inr, int devno)
+{
+	return __SYSCALL2(SYS_IPC_IRQ_UNSUBSCRIBE, inr, devno);
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/include/async.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -46,4 +46,6 @@
 #include <stdbool.h>
 #include <task.h>
+#include <abi/ddi/irq.h>
+#include <abi/ipc/event.h>
 
 typedef ipc_callid_t aid_t;
@@ -62,6 +64,7 @@
 typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *, void *);
 
-/** Interrupt handler */
-typedef void (*async_interrupt_handler_t)(ipc_callid_t, ipc_call_t *);
+/** Notification handler */
+typedef void (*async_notification_handler_t)(ipc_callid_t, ipc_call_t *,
+    void *);
 
 /** Exchange management style
@@ -155,6 +158,18 @@
 
 extern void async_set_client_connection(async_client_conn_t);
-extern void async_set_interrupt_received(async_interrupt_handler_t);
-extern void async_set_interrupt_handler_stack_size(size_t);
+extern void async_set_notification_handler_stack_size(size_t);
+
+extern int async_irq_subscribe(int, int, async_notification_handler_t, void *,
+    const irq_code_t *);
+extern int async_irq_unsubscribe(int, int);
+
+extern int async_event_subscribe(event_type_t, async_notification_handler_t,
+    void *);
+extern int async_event_task_subscribe(event_task_type_t,
+    async_notification_handler_t, void *);
+extern int async_event_unsubscribe(event_type_t);
+extern int async_event_task_unsubscribe(event_task_type_t);
+extern int async_event_unmask(event_type_t);
+extern int async_event_task_unmask(event_task_type_t);
 
 /*
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/c/include/ddi.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -130,7 +130,4 @@
 }
 
-extern int irq_register(int, int, int, const irq_code_t *);
-extern int irq_unregister(int, int);
-
 #endif
 
Index: pace/lib/c/include/event.h
===================================================================
--- uspace/lib/c/include/event.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_EVENT_H_
-#define LIBC_EVENT_H_
-
-#include <abi/ipc/event.h>
-#include <libarch/types.h>
-
-extern int event_subscribe(event_type_t, sysarg_t);
-extern int event_task_subscribe(event_task_type_t, sysarg_t);
-extern int event_unmask(event_type_t);
-extern int event_task_unmask(event_task_type_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/ipc/event.h
===================================================================
--- uspace/lib/c/include/ipc/event.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ uspace/lib/c/include/ipc/event.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_EVENT_H_
+#define LIBC_IPC_EVENT_H_
+
+#include <abi/ipc/event.h>
+#include <libarch/types.h>
+
+extern int ipc_event_subscribe(event_type_t, sysarg_t);
+extern int ipc_event_task_subscribe(event_task_type_t, sysarg_t);
+extern int ipc_event_unsubscribe(event_type_t);
+extern int ipc_event_task_unsubscribe(event_task_type_t);
+extern int ipc_event_unmask(event_type_t);
+extern int ipc_event_task_unmask(event_task_type_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/irq.h
===================================================================
--- uspace/lib/c/include/ipc/irq.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
+++ uspace/lib/c/include/ipc/irq.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_IRQ_H_
+#define LIBC_IPC_IRQ_H_
+
+#include <sys/types.h>
+#include <abi/ddi/irq.h>
+
+extern int ipc_irq_subscribe(int, int, sysarg_t, const irq_code_t *);
+extern int ipc_irq_unsubscribe(int, int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/drv/generic/driver.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -951,7 +951,4 @@
 	driver = drv;
 	
-	/* Initialize interrupt module */
-	interrupt_init();
-	
 	/*
 	 * Register driver with device manager using generic handler for
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/drv/generic/interrupt.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -44,20 +44,4 @@
 #include "private/driver.h"
 
-static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall);
-static interrupt_context_t *create_interrupt_context(void);
-static void delete_interrupt_context(interrupt_context_t *ctx);
-static void init_interrupt_context_list(interrupt_context_list_t *list);
-static void add_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx);
-static void remove_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx);
-static interrupt_context_t *find_interrupt_context_by_id(
-    interrupt_context_list_t *list, int id);
-static interrupt_context_t *find_interrupt_context(
-    interrupt_context_list_t *list, ddf_dev_t *dev, int irq);
-
-/** Interrupts */
-static interrupt_context_list_t interrupt_contexts;
-
 static irq_cmd_t default_cmds[] = {
 	{
@@ -73,132 +57,14 @@
 };
 
-void interrupt_init(void)
-{
-	/* Initialize the list of interrupt contexts. */
-	init_interrupt_context_list(&interrupt_contexts);
-	
-	/* Set generic interrupt handler. */
-	async_set_interrupt_received(driver_irq_handler);
-}
-
-static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
-{
-	int id = (int)IPC_GET_IMETHOD(*icall);
-	interrupt_context_t *ctx;
-	
-	ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
-	if (ctx != NULL && ctx->handler != NULL)
-		(*ctx->handler)(ctx->dev, iid, icall);
-}
-
-static interrupt_context_t *create_interrupt_context(void)
-{
-	interrupt_context_t *ctx;
-	
-	ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
-	if (ctx != NULL)
-		memset(ctx, 0, sizeof(interrupt_context_t));
-	
-	return ctx;
-}
-
-static void delete_interrupt_context(interrupt_context_t *ctx)
-{
-	if (ctx != NULL)
-		free(ctx);
-}
-
-static void init_interrupt_context_list(interrupt_context_list_t *list)
-{
-	memset(list, 0, sizeof(interrupt_context_list_t));
-	fibril_mutex_initialize(&list->mutex);
-	list_initialize(&list->contexts);
-}
-
-static void add_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	ctx->id = list->curr_id++;
-	list_append(&ctx->link, &list->contexts);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-static void remove_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	list_remove(&ctx->link);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-static interrupt_context_t *find_interrupt_context_by_id(
-    interrupt_context_list_t *list, int id)
-{
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link, interrupt_context_t, ctx) {
-		if (ctx->id == id) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-static interrupt_context_t *find_interrupt_context(
-    interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
-{
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link, interrupt_context_t, ctx) {
-		if (ctx->irq == irq && ctx->dev == dev) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-
 int register_interrupt_handler(ddf_dev_t *dev, int irq,
     interrupt_handler_t *handler, const 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 (pseudocode == NULL)
-		pseudocode = &default_pseudocode;
-	
-	int res = irq_register(irq, dev->handle, ctx->id, pseudocode);
-	if (res != EOK) {
-		remove_interrupt_context(&interrupt_contexts, ctx);
-		delete_interrupt_context(ctx);
-	}
-	
-	return res;
+	return async_irq_subscribe(irq, dev->handle,
+	    (async_notification_handler_t) handler, dev, pseudocode);
 }
 
 int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
 {
-	interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
-	    dev, irq);
-	int res = irq_unregister(irq, dev->handle);
-	
-	if (ctx != NULL) {
-		remove_interrupt_context(&interrupt_contexts, ctx);
-		delete_interrupt_context(ctx);
-	}
-	
-	return res;
+	return async_irq_unsubscribe(irq, dev->handle);
 }
 
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -49,21 +49,6 @@
  */
 
-typedef void interrupt_handler_t(ddf_dev_t *, ipc_callid_t, ipc_call_t *);
+typedef void interrupt_handler_t(ipc_callid_t, ipc_call_t *, ddf_dev_t *);
 
-typedef struct interrupt_context {
-	int id;
-	ddf_dev_t *dev;
-	int irq;
-	interrupt_handler_t *handler;
-	link_t link;
-} interrupt_context_t;
-
-typedef struct interrupt_context_list {
-	int curr_id;
-	list_t contexts;
-	fibril_mutex_t mutex;
-} interrupt_context_list_t;
-
-extern void interrupt_init(void);
 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
     const irq_code_t *);
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/input/input.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -54,5 +54,4 @@
 #include <io/keycode.h>
 #include <loc.h>
-#include <event.h>
 #include <str_error.h>
 #include "layout.h"
@@ -358,5 +357,6 @@
 }
 
-static void kconsole_event_received(ipc_callid_t callid, ipc_call_t *call)
+static void kconsole_event_handler(ipc_callid_t callid, ipc_call_t *call,
+    void *arg)
 {
 	if (IPC_GET_ARG1(*call)) {
@@ -772,6 +772,5 @@
 	
 	/* Receive kernel notifications */
-	async_set_interrupt_received(kconsole_event_received);
-	rc = event_subscribe(EVENT_KCONSOLE, 0);
+	rc = async_event_subscribe(EVENT_KCONSOLE, kconsole_event_handler, NULL);
 	if (rc != EOK)
 		printf("%s: Failed to register kconsole notifications (%s)\n",
Index: uspace/srv/hid/input/port/msim.c
===================================================================
--- uspace/srv/hid/input/port/msim.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/input/port/msim.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -78,5 +78,8 @@
 };
 
-static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
+{
+	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
+}
 
 static int msim_port_init(kbd_dev_t *kdev)
@@ -94,6 +97,6 @@
 	msim_ranges[0].base = paddr;
 	msim_cmds[0].addr = (void *) paddr;
-	async_set_interrupt_received(msim_irq_handler);
-	irq_register(inr, device_assign_devno(), 0, &msim_kbd);
+	async_irq_subscribe(inr, device_assign_devno(), msim_irq_handler, NULL,
+	    &msim_kbd);
 	
 	return 0;
@@ -105,9 +108,4 @@
 }
 
-static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
-}
-
 /** @}
  */
Index: uspace/srv/hid/input/port/ns16550.c
===================================================================
--- uspace/srv/hid/input/port/ns16550.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/input/port/ns16550.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -107,14 +107,21 @@
 };
 
-static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static uintptr_t ns16550_physical;
+static kbd_dev_t *kbd_dev;
+static sysarg_t inr;
 
-static uintptr_t ns16550_physical;
-
-static kbd_dev_t *kbd_dev;
+static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
+{
+	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
+	
+	if (irc_service) {
+		async_exch_t *exch = async_exchange_begin(irc_sess);
+		async_msg_1(exch, IRC_CLEAR_INTERRUPT, inr);
+		async_exchange_end(exch);
+	}
+}
 
 static int ns16550_port_init(kbd_dev_t *kdev)
 {
-	void *vaddr;
-	
 	kbd_dev = kdev;
 	
@@ -128,5 +135,4 @@
 		return -1;
 	
-	sysarg_t inr;
 	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
 		return -1;
@@ -136,7 +142,8 @@
 	ns16550_kbd.cmds[3].addr = (void *) (ns16550_physical + RBR_REG);
 	
-	async_set_interrupt_received(ns16550_irq_handler);
-	irq_register(inr, device_assign_devno(), inr, &ns16550_kbd);
+	async_irq_subscribe(inr, device_assign_devno(), ns16550_irq_handler, NULL,
+	    &ns16550_kbd);
 	
+	void *vaddr;
 	return pio_enable((void *) ns16550_physical, 8, &vaddr);
 }
@@ -147,15 +154,4 @@
 }
 
-static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
-	
-	if (irc_service) {
-		async_exch_t *exch = async_exchange_begin(irc_sess);
-		async_msg_1(exch, IRC_CLEAR_INTERRUPT, IPC_GET_IMETHOD(*call));
-		async_exchange_end(exch);
-	}
-}
-
 /**
  * @}
Index: uspace/srv/hid/input/port/pl050.c
===================================================================
--- uspace/srv/hid/input/port/pl050.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/input/port/pl050.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -101,5 +101,8 @@
 };
 
-static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
+{
+	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
+}
 
 static int pl050_port_init(kbd_dev_t *kdev)
@@ -119,6 +122,6 @@
 		return -1;
 	
-	async_set_interrupt_received(pl050_irq_handler);
-	irq_register(inr, device_assign_devno(), 0, &pl050_kbd);
+	async_irq_subscribe(inr, device_assign_devno(), pl050_irq_handler, NULL,
+	    &pl050_kbd);
 	
 	return 0;
@@ -130,9 +133,4 @@
 }
 
-static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
-}
-
 /**
  * @}
Index: uspace/srv/hid/remcons/remcons.c
===================================================================
--- uspace/srv/hid/remcons/remcons.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/remcons/remcons.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -40,5 +40,4 @@
 #include <str_error.h>
 #include <loc.h>
-#include <event.h>
 #include <io/keycode.h>
 #include <align.h>
Index: uspace/srv/hid/remcons/user.c
===================================================================
--- uspace/srv/hid/remcons/user.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/remcons/user.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -38,5 +38,4 @@
 #include <str_error.h>
 #include <loc.h>
-#include <event.h>
 #include <io/keycode.h>
 #include <align.h>
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -72,5 +72,5 @@
 static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall,
     void *arg);
-static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *);
 static void s3c24xx_ts_pen_down(s3c24xx_ts_t *ts);
 static void s3c24xx_ts_pen_up(s3c24xx_ts_t *ts);
@@ -138,6 +138,6 @@
 	    (void *) ts->paddr, inr);
 
-	async_set_interrupt_received(s3c24xx_ts_irq_handler);
-	irq_register(inr, device_assign_devno(), 0, &ts_irq_code);
+	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_ts_irq_handler,
+	    NULL, &ts_irq_code);
 
 	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
@@ -204,5 +204,6 @@
 
 /** Handle touchscreen interrupt */
-static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call,
+    void *arg)
 {
 	ts_updn_t updn;
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -55,5 +55,5 @@
 static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static int cuda_init(void);
-static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg);
 
 static void cuda_irq_listen(void);
@@ -282,6 +282,6 @@
 	cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;
 	cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
-	async_set_interrupt_received(cuda_irq_handler);
-	irq_register(10, device_assign_devno(), 0, &cuda_irq_code);
+	async_irq_subscribe(10, device_assign_devno(), cuda_irq_handler, NULL,
+	    &cuda_irq_code);
 
 	/* Enable SR interrupt. */
@@ -295,5 +295,5 @@
 }
 
-static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg)
 {
 	uint8_t rbuf[CUDA_RCV_BUF_SIZE];
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -68,9 +68,8 @@
 static s3c24xx_uart_t *uart;
 
-static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall,
-    void *arg);
-static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-static int s3c24xx_uart_init(s3c24xx_uart_t *uart);
-static void s3c24xx_uart_sendb(s3c24xx_uart_t *uart, uint8_t byte);
+static void s3c24xx_uart_connection(ipc_callid_t, ipc_call_t *, void *);
+static void s3c24xx_uart_irq_handler(ipc_callid_t, ipc_call_t *, void *);
+static int s3c24xx_uart_init(s3c24xx_uart_t *);
+static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t);
 
 int main(int argc, char *argv[])
@@ -150,7 +149,10 @@
 }
 
-static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	(void) iid; (void) call;
+static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call,
+    void *arg)
+{
+	(void) iid;
+	(void) call;
+	(void) arg;
 
 	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
@@ -192,7 +194,6 @@
 	    (void *) uart->paddr, inr);
 
-	async_set_interrupt_received(s3c24xx_uart_irq_handler);
-
-	irq_register(inr, device_assign_devno(), 0, &uart_irq_code);
+	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_uart_irq_handler,
+	    NULL, &uart_irq_code);
 
 	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
Index: uspace/srv/klog/klog.c
===================================================================
--- uspace/srv/klog/klog.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/klog/klog.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -40,5 +40,4 @@
 #include <as.h>
 #include <ddi.h>
-#include <event.h>
 #include <errno.h>
 #include <str_error.h>
@@ -193,5 +192,6 @@
  *
  */
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+static void klog_notification_received(ipc_callid_t callid, ipc_call_t *call,
+    void *arg)
 {
 	/*
@@ -205,5 +205,5 @@
 	producer();
 	
-	event_unmask(EVENT_KLOG);
+	async_event_unmask(EVENT_KLOG);
 	fibril_mutex_unlock(&mtx);
 }
@@ -229,6 +229,5 @@
 	
 	prodcons_initialize(&pc);
-	async_set_interrupt_received(notification_received);
-	rc = event_subscribe(EVENT_KLOG, 0);
+	rc = async_event_subscribe(EVENT_KLOG, klog_notification_received, NULL);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR,
@@ -245,5 +244,5 @@
 	
 	fibril_add_ready(fid);
-	event_unmask(EVENT_KLOG);
+	async_event_unmask(EVENT_KLOG);
 	
 	fibril_mutex_lock(&mtx);
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/taskmon/taskmon.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -40,5 +40,4 @@
 #include <sys/typefmt.h>
 #include <task.h>
-#include <event.h>
 #include <ipc/corecfg.h>
 #include <loc.h>
@@ -53,5 +52,5 @@
 static void corecfg_client_conn(ipc_callid_t , ipc_call_t *, void *);
 
-static void fault_event(ipc_callid_t callid, ipc_call_t *call)
+static void fault_event(ipc_callid_t callid, ipc_call_t *call, void *arg)
 {
 	const char *fname;
@@ -143,5 +142,5 @@
 	write_core_files = false;
 #endif
-	if (event_subscribe(EVENT_FAULT, 0) != EOK) {
+	if (async_event_subscribe(EVENT_FAULT, fault_event, NULL) != EOK) {
 		printf("%s: Error registering fault notifications.\n", NAME);
 		return -1;
@@ -165,5 +164,4 @@
 	}
 	
-	async_set_interrupt_received(fault_event);
 	task_retval(0);
 	async_manager();
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 83f29e06f0558fb99a9004d9bc2d11c188ba5687)
+++ uspace/srv/vfs/vfs.c	(revision 88205440caa3e827197cd095139acca02b989d5e)
@@ -38,6 +38,4 @@
 #include <vfs/vfs.h>
 #include <ipc/services.h>
-#include <abi/ipc/event.h>
-#include <event.h>
 #include <ns.h>
 #include <async.h>
@@ -53,8 +51,4 @@
 #define NAME  "vfs"
 
-enum {
-	VFS_TASK_STATE_CHANGE
-};
-
 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
@@ -145,17 +139,11 @@
 }
 
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+static void notification_handler(ipc_callid_t callid, ipc_call_t *call, void *arg)
 {
-	switch (IPC_GET_IMETHOD(*call)) {
-	case VFS_TASK_STATE_CHANGE:
-		if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
-			vfs_pass_handle(
-			    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
-			    IPC_GET_ARG5(*call)), call->in_task_id,
-			    (int) IPC_GET_ARG2(*call));
-		break;
-	default:
-		break;
-	}
+	if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
+		vfs_pass_handle(
+		    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
+		    IPC_GET_ARG5(*call)), call->in_task_id,
+		    (int) IPC_GET_ARG2(*call));
 }
 
@@ -196,8 +184,8 @@
 
 	/*
-	 * Set notification handler and subscribe to notifications.
-	 */
-	async_set_interrupt_received(notification_received);
-	event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
+	 * Subscribe to notifications.
+	 */
+	async_event_task_subscribe(EVENT_TASK_STATE_CHANGE, notification_handler,
+	    NULL);
 	
 	/*
