[PATCH 10/11] lib: sbi_domain: Add domain notifier infrastructure

Anup Patel anup.patel at oss.qualcomm.com
Tue Sep 22 20:23:58 PDT 2026


From: Oza Pawandeep <pawandeep.oza at oss.qualcomm.com>

Introduce a notifier callback mechanism that allows subsystems to
register interest in domain events (such as registration). Whenever
such events happen for a domain, all registered notifiers are invoked.

The following public interfaces are added to sbi_domain.h:

  - sbi_domain_register_notifier(): registers a notifier callback.
    Duplicate (fn, event, priv) pairs are silently ignored.

  - sbi_domain_unregister_notifier(): removes a previously registered
    notifier callback.

Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
Signed-off-by: Oza Pawandeep <pawandeep.oza at oss.qualcomm.com>
---
 include/sbi/sbi_domain.h | 40 +++++++++++++++++++++
 lib/sbi/sbi_domain.c     | 78 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index d530f939..56a21397 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -387,4 +387,44 @@ int sbi_domain_finalize(struct sbi_scratch *scratch);
 /** Initialize domains */
 int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
 
+/** Possible domain notify events */
+enum sbi_domain_notify_event {
+	SBI_DOMAIN_NOTIFY_EVENT_REGISTER = 0,
+	SBI_DOMAIN_NOTIFY_EVENT_MAX,
+};
+
+/**
+ * Domain notify callback.
+ * @param dom pointer to domain
+ * @param event domain notify event
+ * @param priv private data of the callback
+ * @return 0 on success (informs framework to continue notifications)
+ * @return negative error code on failure (informs framework to not continue notifications)
+ */
+typedef int (*sbi_domain_notify_fn)(struct sbi_domain *dom,
+				     enum sbi_domain_notify_event event,
+				     void *priv);
+
+/**
+ * Register domain notifier
+ * @param fn domain notify callback
+ * @param event domain notify event
+ * @param priv private data of the callback
+ * @return 0 on success
+ * @return negative error code on failure
+ */
+int sbi_domain_register_notifier(sbi_domain_notify_fn fn,
+				 enum sbi_domain_notify_event event, void *priv);
+
+/**
+ * Unregister domain notifier
+ * @param fn domain notify callback
+ * @param event domain notify event
+ * @param priv private data of the callback
+ * @return 0 on success
+ * @return negative error code on failure
+ */
+int sbi_domain_unregister_notifier(sbi_domain_notify_fn fn,
+				   enum sbi_domain_notify_event event, void *priv);
+
 #endif
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 1c95b0fc..42fe5632 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -35,6 +35,74 @@ struct sbi_domain root = {
 
 static unsigned long domain_hart_ptr_offset;
 
+struct sbi_domain_notify_entry {
+	struct sbi_dlist		node;
+	sbi_domain_notify_fn		fn;
+	enum sbi_domain_notify_event	event;
+	void				*priv;
+};
+
+static SBI_LIST_HEAD(domain_notifier_list);
+
+int sbi_domain_register_notifier(sbi_domain_notify_fn fn,
+				 enum sbi_domain_notify_event event, void *priv)
+{
+	struct sbi_domain_notify_entry *entry;
+
+	if (!fn || SBI_DOMAIN_NOTIFY_EVENT_MAX <= event)
+		return SBI_EINVAL;
+
+	sbi_list_for_each_entry(entry, &domain_notifier_list, node) {
+		if (entry->fn == fn && entry->event == event && entry->priv == priv)
+			return SBI_OK;
+	}
+
+	entry = sbi_zalloc(sizeof(*entry));
+	if (!entry)
+		return SBI_ENOMEM;
+
+	entry->fn    = fn;
+	entry->event = event;
+	entry->priv  = priv;
+	sbi_list_add_tail(&entry->node, &domain_notifier_list);
+	return SBI_OK;
+}
+
+int sbi_domain_unregister_notifier(sbi_domain_notify_fn fn,
+				   enum sbi_domain_notify_event event, void *priv)
+{
+	struct sbi_domain_notify_entry *entry, *tmp;
+
+	if (!fn || SBI_DOMAIN_NOTIFY_EVENT_MAX <= event)
+		return SBI_EINVAL;
+
+	sbi_list_for_each_entry_safe(entry, tmp, &domain_notifier_list, node) {
+		if (entry->fn == fn && entry->event == event && entry->priv == priv) {
+			sbi_list_del(&entry->node);
+			sbi_free(entry);
+			return SBI_OK;
+		}
+	}
+
+	return SBI_ENODEV;
+}
+
+static int sbi_domain_notify_all(struct sbi_domain *dom, enum sbi_domain_notify_event event)
+{
+	struct sbi_domain_notify_entry *entry, *tmp;
+	int rc;
+
+	sbi_list_for_each_entry_safe(entry, tmp, &domain_notifier_list, node) {
+		if (entry->event == event) {
+			rc = entry->fn(dom, event, entry->priv);
+			if (rc)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
 struct sbi_domain *sbi_hartindex_to_domain(u32 hartindex)
 {
 	struct sbi_scratch *scratch;
@@ -719,6 +787,16 @@ int sbi_domain_register(struct sbi_domain *dom)
 		return rc;
 	}
 
+	/* Notify everyone */
+	rc = sbi_domain_notify_all(dom, SBI_DOMAIN_NOTIFY_EVENT_REGISTER);
+	if (rc) {
+		sbi_printf("%s: domain notification failed for %s (error %d)\n",
+			   __func__, dom->name, rc);
+		sbi_domain_cleanup_state(dom);
+		sbi_list_del(&dom->node);
+		return rc;
+	}
+
 	return 0;
 }
 
-- 
2.43.0




More information about the opensbi mailing list