Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -36,6 +36,6 @@
 #include <bitops.h>
 #include <ddi.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
-#include <irc.h>
 #include <stdio.h>
 #include <errno.h>
@@ -257,5 +257,5 @@
 	ddf_msg(LVL_NOTE, "range0.base=%zu", hdaudio_irq_pio_ranges[0].base);
 
-	rc = irc_enable_interrupt(res.irqs.irqs[0]);
+	rc = hw_res_enable_interrupt(hda->parent_sess, res.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/block/ahci/ahci.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -36,7 +36,7 @@
 #include <ddf/interrupt.h>
 #include <ddf/log.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <pci_dev_iface.h>
-#include <irc.h>
 #include <ahci_iface.h>
 #include "ahci.h"
@@ -1192,5 +1192,6 @@
 	}
 	
-	int rc = irc_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
+	int rc = hw_res_enable_interrupt(ahci->parent_sess,
+	    hw_res_parsed.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enable interupt.");
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/bus/isa/isa.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -115,24 +115,47 @@
 }
 
-static int isa_fun_enable_interrupt(ddf_fun_t *fnode, int irq)
-{
-	isa_fun_t *fun = isa_fun(fnode);
+static bool isa_fun_owns_interrupt(isa_fun_t *fun, int irq)
+{
 	const hw_resource_list_t *res = &fun->hw_resources;
-	bool found;
 
 	/* Check that specified irq really belongs to the function */
-	found = false;
 	for (size_t i = 0; i < res->count; ++i) {
 		if (res->resources[i].type == INTERRUPT &&
 		    res->resources[i].res.interrupt.irq == irq) {
-			found = true;
-			break;
-		}
-	}
-
-	if (!found)
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int isa_fun_enable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	isa_fun_t *fun = isa_fun(fnode);
+
+	if (!isa_fun_owns_interrupt(fun, irq))
 		return EINVAL;
 
 	return irc_enable_interrupt(irq);
+}
+
+static int isa_fun_disable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	isa_fun_t *fun = isa_fun(fnode);
+
+	if (!isa_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_disable_interrupt(irq);
+}
+
+static int isa_fun_clear_interrupt(ddf_fun_t *fnode, int irq)
+{
+	isa_fun_t *fun = isa_fun(fnode);
+
+	if (!isa_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_clear_interrupt(irq);
 }
 
@@ -185,4 +208,6 @@
 	.get_resource_list = isa_fun_get_resources,
 	.enable_interrupt = isa_fun_enable_interrupt,
+	.disable_interrupt = isa_fun_disable_interrupt,
+	.clear_interrupt = isa_fun_clear_interrupt,
 	.dma_channel_setup = isa_fun_setup_dma,
 	.dma_channel_remain = isa_fun_remain_dma,
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -99,24 +99,47 @@
 }
 
+static int pciintel_fun_owns_interrupt(pci_fun_t *fun, int irq)
+{
+	size_t i;
+	hw_resource_list_t *res = &fun->hw_resources;
+	
+	for (i = 0; i < res->count; i++) {
+		if (res->resources[i].type == INTERRUPT &&
+		    res->resources[i].res.interrupt.irq == irq) {
+			return true;
+		}
+	}
+	
+	return false;
+}
+
 static int pciintel_enable_interrupt(ddf_fun_t *fnode, int irq)
 {
-	pci_fun_t *dev_data = pci_fun(fnode);
-	
-	size_t i;
-	hw_resource_list_t *res = &dev_data->hw_resources;
-	bool found = false;
-	
-	found = false;
-	for (i = 0; i < res->count; i++) {
-		if (res->resources[i].type == INTERRUPT) {
-			found = true;
-			break;
-		}
-	}
-	
-	if (!found)
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
 		return EINVAL;
-	
+
 	return irc_enable_interrupt(irq);
+}
+
+static int pciintel_disable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_disable_interrupt(irq);
+}
+
+static int pciintel_clear_interrupt(ddf_fun_t *fnode, int irq)
+{
+	pci_fun_t *fun = pci_fun(fnode);
+	
+	if (!pciintel_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_clear_interrupt(irq);
 }
 
@@ -188,4 +211,6 @@
 	.get_resource_list = &pciintel_get_resources,
 	.enable_interrupt = &pciintel_enable_interrupt,
+	.disable_interrupt = &pciintel_disable_interrupt,
+	.clear_interrupt = &pciintel_clear_interrupt,
 };
 
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/char/ns8250/ns8250.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -55,5 +55,4 @@
 #include <ops/char_dev.h>
 
-#include <irc.h>
 #include <device/hw_res.h>
 #include <ipc/serial_ctl.h>
@@ -154,4 +153,6 @@
 	/** DDF function node */
 	ddf_fun_t *fun;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O registers **/
 	ns8250_regs_t *regs;
@@ -382,5 +383,4 @@
 static int ns8250_dev_initialize(ns8250_t *ns)
 {
-	async_sess_t *parent_sess;
 	int ret = EOK;
 	
@@ -390,15 +390,6 @@
 	memset(&hw_resources, 0, sizeof(hw_resource_list_t));
 	
-	/* Connect to the parent's driver. */
-	parent_sess = ddf_dev_parent_sess_get(ns->dev);
-	if (parent_sess == NULL) {
-		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
-		    "device %s.", ddf_dev_get_name(ns->dev));
-		ret = ENOENT;
-		goto failed;
-	}
-	
 	/* Get hw resources. */
-	ret = hw_res_get_resource_list(parent_sess, &hw_resources);
+	ret = hw_res_get_resource_list(ns->parent_sess, &hw_resources);
 	if (ret != EOK) {
 		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
@@ -487,5 +478,5 @@
 {
 	/* Enable interrupt using IRC service. */
-	int rc = irc_enable_interrupt(ns->irq);
+	int rc = hw_res_enable_interrupt(ns->parent_sess, ns->irq);
 	if (rc != EOK)
 		return EIO;
@@ -780,5 +771,5 @@
 	
 	ns8250_read_from_device(ns);
-	irc_clear_interrupt(ns->irq);
+	hw_res_clear_interrupt(ns->parent_sess, ns->irq);
 }
 
@@ -829,4 +820,12 @@
 	fibril_condvar_initialize(&ns->input_buffer_available);
 	ns->dev = dev;
+	
+	ns->parent_sess = ddf_dev_parent_sess_get(ns->dev);
+	if (ns->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
+		    "device %s.", ddf_dev_get_name(ns->dev));
+		rc = EIO;
+		goto fail;
+	}
 	
 	rc = ns8250_dev_initialize(ns);
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/char/pl050/pl050.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -38,7 +38,7 @@
 #include <ddf/interrupt.h>
 #include <ddf/log.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <io/chardev_srv.h>
-#include <irc.h>
 
 #include "pl050_hw.h"
@@ -221,5 +221,5 @@
 	}
 
-	rc = irc_enable_interrupt(res.irqs.irqs[0]);
+	rc = hw_res_enable_interrupt(pl050->parent_sess, res.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/e1k/e1k.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -40,9 +40,9 @@
 #include <thread.h>
 #include <byteorder.h>
-#include <irc.h>
 #include <as.h>
 #include <ddi.h>
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
 #include <device/hw_res_parsed.h>
 #include <pci_dev_iface.h>
@@ -116,4 +116,8 @@
 /** E1000 device data */
 typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** Device configuration */
 	e1000_info_t info;
@@ -1757,5 +1761,5 @@
 	e1000_enable_interrupts(e1000);
 	
-	int rc = irc_enable_interrupt(e1000->irq);
+	int rc = hw_res_enable_interrupt(e1000->parent_sess, e1000->irq);
 	if (rc != EOK) {
 		e1000_disable_interrupts(e1000);
@@ -1802,5 +1806,5 @@
 	e1000_disable_rx(e1000);
 	
-	irc_disable_interrupt(e1000->irq);
+	hw_res_disable_interrupt(e1000->parent_sess, e1000->irq);
 	e1000_disable_interrupts(e1000);
 	
@@ -1884,4 +1888,5 @@
 	
 	memset(e1000, 0, sizeof(e1000_t));
+	e1000->dev = dev;
 	
 	nic_set_specific(nic, e1000);
@@ -1998,4 +2003,10 @@
 		ddf_msg(LVL_ERROR, "Unable to allocate device softstate");
 		return ENOMEM;
+	}
+	
+	e1000->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (e1000->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed connecting parent device.");
+		return EIO;
 	}
 	
@@ -2119,5 +2130,4 @@
 {
 	ddf_fun_t *fun;
-	assert(dev);
 	
 	/* Initialize device structure for E1000 */
Index: uspace/drv/nic/ne2k/dp8390.h
===================================================================
--- uspace/drv/nic/ne2k/dp8390.h	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/ne2k/dp8390.h	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -50,4 +50,6 @@
 #define __NET_NETIF_DP8390_H__
 
+#include <async.h>
+#include <ddf/driver.h>
 #include <fibril_synch.h>
 #include <nic.h>
@@ -223,4 +225,8 @@
 
 typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/* Device configuration */
 	void *base_port; /**< Port assigned from ISA configuration **/
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -40,5 +40,5 @@
 #include <stdio.h>
 #include <errno.h>
-#include <irc.h>
+#include <device/hw_res.h>
 #include <stdlib.h>
 #include <str_error.h>
@@ -256,5 +256,5 @@
 			return rc;
 
-		rc = irc_enable_interrupt(ne2k->irq);
+		rc = hw_res_enable_interrupt(ne2k->parent_sess, ne2k->irq);
 		if (rc != EOK) {
 			ne2k_down(ne2k);
@@ -269,5 +269,5 @@
 	ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
 
-	(void) irc_disable_interrupt(ne2k->irq);
+	(void) hw_res_disable_interrupt(ne2k->parent_sess, ne2k->irq);
 	ne2k->receive_configuration = RCR_AB | RCR_AM;
 	ne2k_down(ne2k);
@@ -384,4 +384,11 @@
 	}
 	
+	ne2k->dev = dev;
+	ne2k->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (ne2k->parent_sess == NULL) {
+		ne2k_dev_cleanup(dev);
+		return ENOMEM;
+	}
+	
 	int rc = ne2k_dev_init(nic_data);
 	if (rc != EOK) {
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/rtl8139/driver.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -36,8 +36,8 @@
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
 #include <io/log.h>
 #include <nic.h>
 #include <pci_dev_iface.h>
-#include <irc.h>
 #include <stdio.h>
 #include <str.h>
@@ -920,5 +920,5 @@
 	rtl8139_hw_int_set(rtl8139);
 
-	int rc = irc_enable_interrupt(rtl8139->irq);
+	int rc = hw_res_enable_interrupt(rtl8139->parent_sess, rtl8139->irq);
 	if (rc != EOK) {
 		rtl8139_on_stopped(nic_data);
@@ -976,5 +976,5 @@
 		return NULL;
 
-	rtl8139_t *rtl8139 = malloc(sizeof(rtl8139_t));
+	rtl8139_t *rtl8139 = calloc(1, sizeof(rtl8139_t));
 	if (!rtl8139) {
 		nic_unbind_and_destroy(dev);
@@ -982,5 +982,5 @@
 	}
 
-	memset(rtl8139, 0, sizeof(rtl8139_t));
+	rtl8139->dev = dev;
 
 	rtl8139->nic_data = nic_data;
@@ -1166,4 +1166,9 @@
 
 	ddf_msg(LVL_DEBUG, "rtl8139: dev_data created");
+	rtl8139->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (rtl8139->parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Error connecting parent device.");
+		return EIO;
+	}
 
 	/* Obtain and fill hardware resources info and connect to parent */
@@ -1258,5 +1263,4 @@
 	ddf_fun_t *fun;
 
-	assert(dev);
 	ddf_msg(LVL_NOTE, "RTL8139_dev_add %s (handle = %zu)",
 	    ddf_dev_get_name(dev), ddf_dev_get_handle(dev));
Index: uspace/drv/nic/rtl8139/driver.h
===================================================================
--- uspace/drv/nic/rtl8139/driver.h	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/rtl8139/driver.h	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -87,4 +87,8 @@
 /** RTL8139 device data */
 typedef struct rtl8139_data {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O address of the device */
 	void *io_addr;
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/rtl8169/driver.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -31,5 +31,4 @@
 #include <align.h>
 #include <byteorder.h>
-#include <irc.h>
 #include <libarch/barrier.h>
 
@@ -38,9 +37,10 @@
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
+#include <device/hw_res.h>
+#include <device/hw_res_parsed.h>
 #include <io/log.h>
 #include <nic.h>
 #include <pci_dev_iface.h>
 
-#include <ipc/irc.h>
 #include <sysinfo.h>
 #include <ipc/ns.h>
@@ -396,12 +396,17 @@
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
 
+	rtl8169->dev = dev;
+	rtl8169->parent_sess = ddf_dev_parent_sess_get(dev);
+	if (rtl8169->parent_sess == NULL)
+		return EIO;
+
 	/* Get PCI VID & PID */
-	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
-	    PCI_VENDOR_ID, &rtl8169->pci_vid);
+	rc = pci_config_space_read_16(rtl8169->parent_sess, PCI_VENDOR_ID,
+	    &rtl8169->pci_vid);
 	if (rc != EOK)
 		return rc;
 
-	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
-	    PCI_DEVICE_ID, &rtl8169->pci_pid);
+	rc = pci_config_space_read_16(rtl8169->parent_sess, PCI_DEVICE_ID,
+	    &rtl8169->pci_pid);
 	if (rc != EOK)
 		return rc;
@@ -745,5 +750,6 @@
 
 	pio_write_16(rtl8169->regs + IMR, 0xffff);
-	irc_enable_interrupt(rtl8169->irq);
+	/* XXX Check return value */
+	hw_res_enable_interrupt(rtl8169->parent_sess, rtl8169->irq);
 
 	return EOK;
Index: uspace/drv/nic/rtl8169/driver.h
===================================================================
--- uspace/drv/nic/rtl8169/driver.h	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/nic/rtl8169/driver.h	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -49,4 +49,8 @@
 /** RTL8139 device data */
 typedef struct rtl8169_data {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Parent session */
+	async_sess_t *parent_sess;
 	/** I/O address of the device */
 	void *regs_phys;
Index: uspace/drv/platform/icp/icp.c
===================================================================
--- uspace/drv/platform/icp/icp.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/drv/platform/icp/icp.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <errno.h>
+#include <irc.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -142,8 +143,27 @@
 }
 
-static int icp_enable_interrupt(ddf_fun_t *fun, int irq)
-{
-	/* TODO */
+static bool icp_fun_owns_interrupt(icp_fun_t *fun, int irq)
+{
+	const hw_resource_list_t *res = &fun->hw_resources;
+
+	/* Check that specified irq really belongs to the function */
+	for (size_t i = 0; i < res->count; ++i) {
+		if (res->resources[i].type == INTERRUPT &&
+		    res->resources[i].res.interrupt.irq == irq) {
+			return true;
+		}
+	}
+
 	return false;
+}
+
+static int icp_fun_enable_interrupt(ddf_fun_t *fnode, int irq)
+{
+	icp_fun_t *fun = icp_fun(fnode);
+
+	if (!icp_fun_owns_interrupt(fun, irq))
+		return EINVAL;
+
+	return irc_enable_interrupt(irq);
 }
 
@@ -155,5 +175,5 @@
 static hw_res_ops_t icp_hw_res_ops = {
 	.get_resource_list = &icp_get_resources,
-	.enable_interrupt = &icp_enable_interrupt,
+	.enable_interrupt = &icp_fun_enable_interrupt,
 };
 
Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/lib/c/generic/device/hw_res.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -86,4 +86,26 @@
 }
 
+int hw_res_disable_interrupt(async_sess_t *sess, int irq)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_DISABLE_INTERRUPT, irq);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int hw_res_clear_interrupt(async_sess_t *sess, int irq)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_CLEAR_INTERRUPT, irq);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
 /** Setup DMA channel to specified place and mode.
  *
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/lib/c/include/device/hw_res.h	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -52,4 +52,6 @@
 	HW_RES_GET_RESOURCE_LIST = 0,
 	HW_RES_ENABLE_INTERRUPT,
+	HW_RES_DISABLE_INTERRUPT,
+	HW_RES_CLEAR_INTERRUPT,
 	HW_RES_DMA_CHANNEL_SETUP,
 	HW_RES_DMA_CHANNEL_REMAIN,
@@ -116,4 +118,6 @@
 extern int hw_res_get_resource_list(async_sess_t *, hw_resource_list_t *);
 extern int hw_res_enable_interrupt(async_sess_t *, int);
+extern int hw_res_disable_interrupt(async_sess_t *, int);
+extern int hw_res_clear_interrupt(async_sess_t *, int);
 
 extern int hw_res_dma_channel_setup(async_sess_t *, unsigned int, uint32_t,
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -45,4 +45,8 @@
 static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
+static void remote_hw_res_disable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
+static void remote_hw_res_clear_interrupt(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
 static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
@@ -53,4 +57,6 @@
 	[HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
 	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
+	[HW_RES_DISABLE_INTERRUPT] = &remote_hw_res_disable_interrupt,
+	[HW_RES_CLEAR_INTERRUPT] = &remote_hw_res_clear_interrupt,
 	[HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
 	[HW_RES_DMA_CHANNEL_REMAIN] = &remote_hw_res_dma_channel_remain,
@@ -68,4 +74,34 @@
 	
 	if (hw_res_ops->enable_interrupt == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	const int irq = DEV_IPC_GET_ARG1(*call);
+	const int ret = hw_res_ops->enable_interrupt(fun, irq);
+	async_answer_0(callid, ret);
+}
+
+static void remote_hw_res_disable_interrupt(ddf_fun_t *fun, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+	
+	if (hw_res_ops->disable_interrupt == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	const int irq = DEV_IPC_GET_ARG1(*call);
+	const int ret = hw_res_ops->disable_interrupt(fun, irq);
+	async_answer_0(callid, ret);
+}
+
+static void remote_hw_res_clear_interrupt(ddf_fun_t *fun, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+	
+	if (hw_res_ops->clear_interrupt == NULL) {
 		async_answer_0(callid, ENOTSUP);
 		return;
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision ce732e7424b576553251a9ef4cfff88391a2fe24)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision d51838f190d8e49cb00493b84858f7ad93996014)
@@ -45,4 +45,6 @@
 	hw_resource_list_t *(*get_resource_list)(ddf_fun_t *);
 	int (*enable_interrupt)(ddf_fun_t *, int);
+	int (*disable_interrupt)(ddf_fun_t *, int);
+	int (*clear_interrupt)(ddf_fun_t *, int);
 	int (*dma_channel_setup)(ddf_fun_t *, unsigned, uint32_t, uint32_t, uint8_t);
 	int (*dma_channel_remain)(ddf_fun_t *, unsigned, size_t *);
