Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 07d4271f2d0447f764d751ed8f95104f720791d2)
+++ kernel/generic/src/ipc/ipc.c	(revision 2df21755623b239a0d57f0639a0bfcf636cd3d5b)
@@ -71,4 +71,5 @@
 static slab_cache_t *answerbox_cache;
 
+slab_cache_t *irq_cache = NULL;
 slab_cache_t *phone_cache = NULL;
 
@@ -87,14 +88,15 @@
 	call->callerbox = NULL;
 	call->buffer = NULL;
-}
-
-static void call_destroy(void *arg)
-{
-	call_t *call = (call_t *) arg;
+	kobject_initialize(&call->kobject, KOBJECT_TYPE_CALL);
+}
+
+static void call_destroy(kobject_t *arg)
+{
+	call_t *call = call_from_kobject(arg);
 
 	if (call->buffer)
 		free(call->buffer);
 	if (call->caller_phone)
-		kobject_put(call->caller_phone->kobject);
+		kobject_put(&call->caller_phone->kobject);
 	slab_free(call_cache, call);
 }
@@ -114,19 +116,9 @@
 call_t *ipc_call_alloc(void)
 {
-	// TODO: Allocate call and kobject in single allocation
-
 	call_t *call = slab_alloc(call_cache, FRAME_ATOMIC);
 	if (!call)
 		return NULL;
 
-	kobject_t *kobj = kobject_alloc(0);
-	if (!kobj) {
-		slab_free(call_cache, call);
-		return NULL;
-	}
-
 	_ipc_call_init(call);
-	kobject_initialize(kobj, KOBJECT_TYPE_CALL, call);
-	call->kobject = kobj;
 
 	return call;
@@ -181,5 +173,5 @@
 	if (!connected) {
 		/* We still have phone->kobject's reference; drop it */
-		kobject_put(phone->kobject);
+		kobject_put(&phone->kobject);
 	}
 
@@ -201,5 +193,5 @@
 	atomic_store(&phone->active_calls, 0);
 	phone->label = 0;
-	phone->kobject = NULL;
+	kobject_initialize(&phone->kobject, KOBJECT_TYPE_PHONE);
 }
 
@@ -294,5 +286,5 @@
 		/* This is a forgotten call and call->sender is not valid. */
 		spinlock_unlock(&call->forget_lock);
-		kobject_put(call->kobject);
+		kobject_put(&call->kobject);
 		return;
 	} else {
@@ -352,5 +344,5 @@
 
 	call->caller_phone = phone;
-	kobject_add_ref(phone->kobject);
+	kobject_add_ref(&phone->kobject);
 
 	if (preforget) {
@@ -362,5 +354,5 @@
 		else
 			atomic_inc(&caller->answerbox.active_calls);
-		kobject_add_ref(phone->kobject);
+		kobject_add_ref(&phone->kobject);
 		call->sender = caller;
 		call->active = true;
@@ -479,5 +471,5 @@
 
 		/* Drop the answerbox reference */
-		kobject_put(phone->kobject);
+		kobject_put(&phone->kobject);
 
 		call_t *call = phone->hangup_call;
@@ -581,5 +573,5 @@
 		atomic_dec(&request->caller_phone->active_calls);
 		atomic_dec(&box->active_calls);
-		kobject_put(request->caller_phone->kobject);
+		kobject_put(&request->caller_phone->kobject);
 	} else if (!list_empty(&box->calls)) {
 		/* Count received call */
@@ -697,5 +689,5 @@
 			task_release(phone->caller);
 
-			kobject_put(phone->kobject);
+			kobject_put(&phone->kobject);
 
 			/* Must start again */
@@ -704,5 +696,5 @@
 
 		mutex_unlock(&phone->lock);
-		kobject_put(phone->kobject);
+		kobject_put(&phone->kobject);
 	}
 
@@ -728,5 +720,5 @@
 	 * must hold a reference to it.
 	 */
-	kobject_add_ref(call->kobject);
+	kobject_add_ref(&call->kobject);
 
 	spinlock_unlock(&call->forget_lock);
@@ -735,9 +727,9 @@
 	atomic_dec(&call->caller_phone->active_calls);
 	atomic_dec(&TASK->answerbox.active_calls);
-	kobject_put(call->caller_phone->kobject);
+	kobject_put(&call->caller_phone->kobject);
 
 	SYSIPC_OP(request_forget, call);
 
-	kobject_put(call->kobject);
+	kobject_put(&call->kobject);
 }
 
@@ -777,5 +769,5 @@
 static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
 {
-	ipc_phone_hangup(cap->kobject->phone);
+	ipc_phone_hangup(phone_from_kobject(cap->kobject));
 	kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
 	    KOBJECT_TYPE_PHONE);
@@ -798,5 +790,5 @@
 		SYSIPC_OP(answer_process, call);
 
-		kobject_put(call->kobject);
+		kobject_put(&call->kobject);
 
 		/*
@@ -892,4 +884,6 @@
 	answerbox_cache = slab_cache_create("answerbox_t", sizeof(answerbox_t),
 	    0, NULL, NULL, 0);
+	irq_cache = slab_cache_create("irq_t", sizeof(irq_kobject_t),
+	    0, NULL, NULL, 0);
 }
 
@@ -927,5 +921,5 @@
 static bool print_task_phone_cb(cap_t *cap, void *arg)
 {
-	phone_t *phone = cap->kobject->phone;
+	phone_t *phone = phone_from_kobject(cap->kobject);
 
 	mutex_lock(&phone->lock);
