Index: kernel/generic/include/ipc/irq.h
===================================================================
--- kernel/generic/include/ipc/irq.h	(revision 4d6629f35433100ab954e68c6ed4fc9bf24accb1)
+++ kernel/generic/include/ipc/irq.h	(revision 9306cd7e0e7b284355e39923f665d3acad4b3bdf)
@@ -53,5 +53,4 @@
 extern int ipc_irq_subscribe(answerbox_t *, inr_t, sysarg_t, irq_code_t *);
 extern int ipc_irq_unsubscribe(answerbox_t *, int);
-extern void ipc_irq_cleanup(answerbox_t *);
 
 /*
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 4d6629f35433100ab954e68c6ed4fc9bf24accb1)
+++ kernel/generic/src/ipc/ipc.c	(revision 9306cd7e0e7b284355e39923f665d3acad4b3bdf)
@@ -828,6 +828,8 @@
 	event_cleanup_answerbox(&TASK->answerbox);
 	
-	/* Disconnect all connected irqs */
-	ipc_irq_cleanup(&TASK->answerbox);
+	/* Disconnect all connected IRQs */
+	for_each_cap_current(cap, CAP_TYPE_IRQ) {
+		ipc_irq_unsubscribe(&TASK->answerbox, cap->handle);
+	}
 	
 	/* Disconnect all phones connected to our regular answerbox */
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 4d6629f35433100ab954e68c6ed4fc9bf24accb1)
+++ kernel/generic/src/ipc/irq.c	(revision 9306cd7e0e7b284355e39923f665d3acad4b3bdf)
@@ -329,6 +329,5 @@
 	cap_t *cap = cap_get_current(handle, CAP_TYPE_ALLOCATED);
 	assert(cap);
-	cap->type = CAP_TYPE_IRQ;
-
+	
 	irq_t *irq = &cap->irq;
 	irq_initialize(irq);
@@ -344,5 +343,5 @@
 	/*
 	 * Enlist the IRQ structure in the uspace IRQ hash table and the
-	 * answerbox's list.
+	 * answerbox's list and make the IRQ capability valid.
 	 */
 	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
@@ -350,4 +349,5 @@
 	irq_spinlock_lock(&box->irq_lock, false);
 	
+	cap->type = CAP_TYPE_IRQ;
 	hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
 	list_append(&irq->notif_cfg.link, &box->irq_list);
@@ -370,9 +370,15 @@
 int ipc_irq_unsubscribe(answerbox_t *box, int handle)
 {
+	irq_spinlock_lock(&TASK->lock, true);
 	cap_t *cap = cap_get_current(handle, CAP_TYPE_IRQ);
-	if (!cap)
+	if (!cap) {
+		irq_spinlock_unlock(&TASK->lock, true);
 		return ENOENT;
+	}
+	cap->type = CAP_TYPE_ALLOCATED;
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	irq_t *irq = &cap->irq;
-
+	
 	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
 	irq_spinlock_lock(&irq->lock, false);
@@ -398,62 +404,4 @@
 	
 	return EOK;
-}
-
-/** Disconnect all IRQ notifications from an answerbox.
- *
- * This function is effective because the answerbox contains list of all irq_t
- * structures that are subscribed to send notifications to it.
- *
- * @param box Answerbox for which we want to carry out the cleanup.
- *
- */
-void ipc_irq_cleanup(answerbox_t *box)
-{
-loop:
-	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-	irq_spinlock_lock(&box->irq_lock, false);
-	
-	while (!list_empty(&box->irq_list)) {
-		DEADLOCK_PROBE_INIT(p_irqlock);
-		
-		irq_t *irq = list_get_instance(list_first(&box->irq_list), irq_t,
-		    notif_cfg.link);
-		
-		if (!irq_spinlock_trylock(&irq->lock)) {
-			/*
-			 * Avoid deadlock by trying again.
-			 */
-			irq_spinlock_unlock(&box->irq_lock, false);
-			irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-			DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
-			goto loop;
-		}
-		
-		assert(irq->notif_cfg.answerbox == box);
-		
-		/* Unlist from the answerbox. */
-		list_remove(&irq->notif_cfg.link);
-		
-		/* Remove from the hash table. */
-		hash_table_remove_item(&irq_uspace_hash_table, &irq->link);
-		
-		/*
-		 * Release both locks so that we can free the IRQ code.
-		 */
-		irq_spinlock_unlock(&box->irq_lock, false);
-		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
-		
-		code_free(irq->notif_cfg.code);
-		
-		// XXX: what to do about the irq capability? The task is in
-		// clean-up anyway.
-		
-		/* Reacquire both locks before taking another round. */
-		irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
-		irq_spinlock_lock(&box->irq_lock, false);
-	}
-	
-	irq_spinlock_unlock(&box->irq_lock, false);
-	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 }
 
