[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