Index: uspace/srv/devman/client_conn.c
===================================================================
--- uspace/srv/devman/client_conn.c	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/client_conn.c	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2025 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
- * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -479,4 +479,39 @@
 }
 
+/** Quiesce function.
+ *
+ * Send a request to quiesce a function to the responsible driver.
+ */
+static void devman_fun_quiesce(ipc_call_t *icall)
+{
+	fun_node_t *fun;
+	dev_node_t *child;
+	errno_t rc;
+
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
+	if (fun == NULL) {
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	fibril_rwlock_read_lock(&device_tree.rwlock);
+
+	/* Check function state */
+	if (fun->state == FUN_REMOVED) {
+		fibril_rwlock_read_unlock(&device_tree.rwlock);
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	child = fun->child;
+	dev_add_ref(child);
+	fibril_rwlock_read_unlock(&device_tree.rwlock);
+
+	rc = driver_dev_quiesce(&device_tree, child);
+	fun_del_ref(fun);
+
+	async_answer_0(icall, rc);
+}
+
 /** Find handle for the function instance identified by its service ID. */
 static void devman_fun_sid_to_handle(ipc_call_t *icall)
@@ -790,4 +825,7 @@
 			devman_fun_offline(&call);
 			break;
+		case DEVMAN_FUN_QUIESCE:
+			devman_fun_quiesce(&call);
+			break;
 		case DEVMAN_FUN_SID_TO_HANDLE:
 			devman_fun_sid_to_handle(&call);
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/driver.c	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -741,4 +741,27 @@
 }
 
+errno_t driver_dev_quiesce(dev_tree_t *tree, dev_node_t *dev)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	driver_t *drv;
+	devman_handle_t handle;
+
+	assert(dev != NULL);
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_quiesce(%p)", dev);
+
+	fibril_rwlock_read_lock(&tree->rwlock);
+	drv = dev->drv;
+	handle = dev->handle;
+	fibril_rwlock_read_unlock(&tree->rwlock);
+
+	exch = async_exchange_begin(drv->sess);
+	retval = async_req_1_0(exch, DRIVER_DEV_QUIESCE, handle);
+	async_exchange_end(exch);
+
+	return retval;
+}
+
 errno_t driver_dev_gone(dev_tree_t *tree, dev_node_t *dev)
 {
Index: uspace/srv/devman/driver.h
===================================================================
--- uspace/srv/devman/driver.h	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/driver.h	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2025 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
- * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -53,4 +53,5 @@
 extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
 extern errno_t driver_dev_remove(dev_tree_t *, dev_node_t *);
+extern errno_t driver_dev_quiesce(dev_tree_t *, dev_node_t *);
 extern errno_t driver_dev_gone(dev_tree_t *, dev_node_t *);
 extern errno_t driver_fun_online(dev_tree_t *, fun_node_t *);
Index: uspace/srv/devman/drv_conn.c
===================================================================
--- uspace/srv/devman/drv_conn.c	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/drv_conn.c	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -444,4 +444,42 @@
 
 	rc = fun_offline(fun);
+	if (rc != EOK) {
+		fun_busy_unlock(fun);
+		fun_del_ref(fun);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	fun_busy_unlock(fun);
+	fun_del_ref(fun);
+	async_answer_0(icall, EOK);
+}
+
+/** Quiesce function by driver request.
+ *
+ */
+static void devman_drv_fun_quiesce(ipc_call_t *icall, driver_t *drv)
+{
+	fun_node_t *fun;
+	errno_t rc;
+
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
+	if (fun == NULL) {
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	fun_busy_lock(fun);
+
+	fibril_rwlock_write_lock(&device_tree.rwlock);
+	if (fun->dev == NULL || fun->dev->drv != drv) {
+		fun_busy_unlock(fun);
+		fun_del_ref(fun);
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+	fibril_rwlock_write_unlock(&device_tree.rwlock);
+
+	rc = fun_quiesce(fun);
 	if (rc != EOK) {
 		fun_busy_unlock(fun);
@@ -677,4 +715,7 @@
 			devman_drv_fun_offline(&call, driver);
 			break;
+		case DEVMAN_DRV_FUN_QUIESCE:
+			devman_drv_fun_quiesce(&call, driver);
+			break;
 		case DEVMAN_DRV_FUN_WAIT_STABLE:
 			devman_drv_fun_wait_stable(&call, driver);
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/fun.c	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2025 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
  * All rights reserved.
@@ -428,4 +429,61 @@
 }
 
+errno_t fun_quiesce(fun_node_t *fun)
+{
+	errno_t rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "fun_quiesce(%s)", fun->pathname);
+	fibril_rwlock_read_lock(&device_tree.rwlock);
+
+	if (fun->state == FUN_OFF_LINE) {
+		fibril_rwlock_read_unlock(&device_tree.rwlock);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Function %s is off line.",
+		    fun->pathname);
+		return EOK;
+	}
+
+	if (fun->ftype != fun_inner) {
+		/* Nothing to do */
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Nothing to do for external "
+		    "function %s\n", fun->pathname);
+		fibril_rwlock_read_unlock(&device_tree.rwlock);
+		return EOK;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Quiescing inner function %s.",
+	    fun->pathname);
+
+	if (fun->child == NULL) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Function %s child is NULL.",
+		    fun->pathname);
+		fibril_rwlock_read_unlock(&device_tree.rwlock);
+		return EOK;
+	}
+
+	dev_node_t *dev = fun->child;
+	device_state_t dev_state;
+
+	dev_add_ref(dev);
+	dev_state = dev->state;
+
+	fibril_rwlock_read_unlock(&device_tree.rwlock);
+
+	/* If device is owned by driver, ask driver to quiesce it. */
+	if (dev_state == DEVICE_USABLE) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Call driver_dev_quiesce() "
+		    "for %s.", fun->pathname);
+		rc = driver_dev_quiesce(&device_tree, dev);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR,
+			    "driver_dev_quiesce() -> %d", (int)rc);
+			dev_del_ref(dev);
+			return ENOTSUP;
+		}
+	}
+
+	dev_del_ref(dev);
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/srv/devman/fun.h
===================================================================
--- uspace/srv/devman/fun.h	(revision 832cbe7f6539badd99e8e5715f4a59e044c65c44)
+++ uspace/srv/devman/fun.h	(revision 9a41e6eff45368e179eedd7b5d26fac14c515321)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2025 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
- * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -51,4 +51,5 @@
 extern errno_t fun_online(fun_node_t *);
 extern errno_t fun_offline(fun_node_t *);
+extern errno_t fun_quiesce(fun_node_t *);
 
 #endif
