[PATCH 10/11] lib: sbi_domain: Add domain notifier infrastructure
Pawandeep Oza
pawandeep.oza at oss.qualcomm.com
Tue Oct 13 12:47:57 PDT 2026
On Tue, Sep 22, 2026 at 8:24 PM Anup Patel <anup.patel at oss.qualcomm.com> wrote:
>
> 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
>
Reviewed-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
Tested-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
More information about the opensbi
mailing list