[PATCH v5 2/9] greybus: svc: add gb_svc_flush()

From: Ayush Singh

Date: Tue Nov 03 2026 - 11:46:23 EST


A host driver that is its own SVC, such as a software SVC, injects
requests like MODULE_REMOVED through greybus_data_rcvd(). The core acts
on them asynchronously: the request handler runs on the connection
workqueue and queues the actual work on svc->wq. The response is sent
before that work runs, so it cannot tell the driver that the module is
gone.

Add gb_svc_flush() to wait until every request received so far has been
fully processed. It flushes the connection workqueue, then svc->wq.

Signed-off-by: Ayush Singh <ayush@xxxxxxxxxxxxxxx>
---
drivers/greybus/svc.c | 14 ++++++++++++++
include/linux/greybus/svc.h | 1 +
2 files changed, 15 insertions(+)

diff --git a/drivers/greybus/svc.c b/drivers/greybus/svc.c
index 490577731a19..788d95b4b87b 100644
--- a/drivers/greybus/svc.c
+++ b/drivers/greybus/svc.c
@@ -1381,6 +1381,20 @@ static void gb_svc_remove_modules(struct gb_svc *svc)
}
}

+/**
+ * gb_svc_flush - wait for received SVC requests to be processed
+ * @svc: the SVC
+ *
+ * Requests pass through the connection workqueue on their way to svc->wq, so
+ * both have to be flushed, in this order.
+ */
+void gb_svc_flush(struct gb_svc *svc)
+{
+ flush_workqueue(svc->connection->wq);
+ flush_workqueue(svc->wq);
+}
+EXPORT_SYMBOL_GPL(gb_svc_flush);
+
void gb_svc_del(struct gb_svc *svc)
{
gb_connection_disable_rx(svc->connection);
diff --git a/include/linux/greybus/svc.h b/include/linux/greybus/svc.h
index da547fb9071b..ced5fc3a9c6b 100644
--- a/include/linux/greybus/svc.h
+++ b/include/linux/greybus/svc.h
@@ -63,6 +63,7 @@ struct gb_svc *gb_svc_create(struct gb_host_device *hd);
int gb_svc_add(struct gb_svc *svc);
void gb_svc_del(struct gb_svc *svc);
void gb_svc_put(struct gb_svc *svc);
+void gb_svc_flush(struct gb_svc *svc);

int gb_svc_pwrmon_intf_sample_get(struct gb_svc *svc, u8 intf_id,
u8 measurement_type, u32 *value);

--
2.56.0