[PATCH 05/11] lib: utils/mpxy: Introduce mpxy_rpmi_no_mbox_init() function
Anup Patel
anup.patel at oss.qualcomm.com
Tue Sep 22 20:23:53 PDT 2026
Add new mpxy_rpmi_no_mbox_init() function to instantiate MPXY RPMI
channel without any mailbox channel backing. This new function can
be used by MPXY RPMI drivers that want to emulate MPXY channels in
software.
Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
---
include/sbi_utils/mpxy/fdt_mpxy_rpmi.h | 6 +-
lib/utils/mpxy/fdt_mpxy_rpmi.c | 119 ++++++++++++++++---------
2 files changed, 83 insertions(+), 42 deletions(-)
diff --git a/include/sbi_utils/mpxy/fdt_mpxy_rpmi.h b/include/sbi_utils/mpxy/fdt_mpxy_rpmi.h
index a3968e87..c4e6897f 100644
--- a/include/sbi_utils/mpxy/fdt_mpxy_rpmi.h
+++ b/include/sbi_utils/mpxy/fdt_mpxy_rpmi.h
@@ -84,7 +84,11 @@ struct mpxy_rpmi_data {
void (*cleanup_group)(void *context);
};
-/** Common probe function for MPXY RPMI drivers */
+/** Function to instantiate MPXY RPMI channel */
+int mpxy_rpmi_no_mbox_init(const struct mpxy_rpmi_data *data, u32 mpxy_channel_id,
+ const char *dom_name);
+
+/** FDT probe function to instantiate MPXY RPMI channel */
int fdt_mpxy_rpmi_init(const void *fdt, int nodeoff, const struct fdt_match *match);
#endif
diff --git a/lib/utils/mpxy/fdt_mpxy_rpmi.c b/lib/utils/mpxy/fdt_mpxy_rpmi.c
index 9b8e69e1..103ded13 100644
--- a/lib/utils/mpxy/fdt_mpxy_rpmi.c
+++ b/lib/utils/mpxy/fdt_mpxy_rpmi.c
@@ -219,44 +219,37 @@ static int mpxy_rpmi_get_attribute(struct mpxy_rpmi *rmb,
return rc;
}
-int fdt_mpxy_rpmi_init(const void *fdt, int nodeoff, const struct fdt_match *match)
+static int __mpxy_rpmi_init(const struct mpxy_rpmi_data *data,
+ struct mbox_chan *chan, u32 mpxy_channel_id,
+ struct sbi_domain *dom)
{
- u32 channel_id, servicegrp_ver, pro_ver, max_data_len, tx_tout, rx_tout;
- u32 impl_id, impl_ver;
- const struct mpxy_rpmi_data *data = match->data;
+ u32 servicegrp_ver, pro_ver, max_data_len, tx_tout, rx_tout;
struct mpxy_rpmi *rmb;
- struct mbox_chan *chan;
- const fdt32_t *val;
- int rc, len;
+ u32 impl_id, impl_ver;
+ int rc;
+
+ if (!data || !dom)
+ return SBI_EINVAL;
+
+ /*
+ * When mailbox channel is not available, both get_attribute_group() and
+ * xfer_group() callbacks must be available.
+ */
+ if (!chan && (!data->get_attribute_group || !data->xfer_group))
+ return SBI_EINVAL;
/* Allocate context for MPXY RPMI instance */
rmb = sbi_zalloc(sizeof(*rmb));
if (!rmb)
return SBI_ENOMEM;
rmb->data = data;
-
- /*
- * If channel request failed then other end does not support
- * service group so do nothing.
- */
- rc = fdt_mailbox_request_chan(fdt, nodeoff, 0, &chan);
- if (rc) {
- rc = SBI_ENODEV;
- goto fail_free_client;
- }
rmb->chan = chan;
- /* Match channel service group id */
- if (data->servicegrp_id != chan->chan_args[0]) {
- rc = SBI_EINVAL;
- goto fail_free_chan;
- }
-
/* Setup RPMI service group context */
if (data->setup_group) {
rc = data->setup_group(&rmb->group_context, chan, data);
if (rc)
- goto fail_free_chan;
+ goto fail_free_client;
}
/* Get channel protocol version */
@@ -301,24 +294,11 @@ int fdt_mpxy_rpmi_init(const void *fdt, int nodeoff, const struct fdt_match *mat
if (rc)
goto fail_cleanup_group;
- /*
- * The "riscv,sbi-mpxy-channel-id" DT property is mandatory
- * for MPXY RPMI drivers so if this is not present then try
- * other drivers.
- */
- val = fdt_getprop(fdt, nodeoff, "riscv,sbi-mpxy-channel-id", &len);
- if (len > 0 && val) {
- channel_id = fdt32_to_cpu(*val);
- } else {
- rc = SBI_ENODEV;
- goto fail_cleanup_group;
- }
-
/* Setup MPXY RPMI channel */
/* Channel ID*/
- rmb->channel.channel_id = channel_id;
+ rmb->channel.channel_id = mpxy_channel_id;
/* Set the owner domain */
- rmb->channel.owner_domain = &root;
+ rmb->channel.owner_domain = dom;
/* Callback for read RPMI attributes */
rmb->channel.read_attributes = mpxy_read_attributes;
/* Callback for write RPMI attributes */
@@ -360,9 +340,66 @@ int fdt_mpxy_rpmi_init(const void *fdt, int nodeoff, const struct fdt_match *mat
fail_cleanup_group:
if (data->cleanup_group)
data->cleanup_group(rmb->group_context);
-fail_free_chan:
- mbox_controller_free_chan(chan);
fail_free_client:
sbi_free(rmb);
return rc;
}
+
+int mpxy_rpmi_no_mbox_init(const struct mpxy_rpmi_data *data, u32 mpxy_channel_id,
+ const char *dom_name)
+{
+ /* Create MPXY RPMI instance without mailbox channel */
+ return __mpxy_rpmi_init(data, NULL, mpxy_channel_id, sbi_domain_find_by_name(dom_name));
+}
+
+int fdt_mpxy_rpmi_init(const void *fdt, int nodeoff, const struct fdt_match *match)
+{
+ const struct mpxy_rpmi_data *data = match->data;
+ struct mbox_chan *chan = NULL;
+ const fdt32_t *val;
+ u32 channel_id;
+ int rc, len;
+
+ /* Request mailbox channel when available */
+ val = fdt_getprop(fdt, nodeoff, "mboxes", &len);
+ if (val) {
+ /*
+ * If channel request failed then other end does not support
+ * service group so do nothing.
+ */
+ rc = fdt_mailbox_request_chan(fdt, nodeoff, 0, &chan);
+ if (rc)
+ return SBI_ENODEV;
+
+ /* Match channel service group id */
+ if (data->servicegrp_id != chan->chan_args[0]) {
+ rc = SBI_EINVAL;
+ goto fail_free_chan;
+ }
+ }
+
+ /*
+ * The "riscv,sbi-mpxy-channel-id" DT property is mandatory
+ * for MPXY RPMI drivers so if this is not present then try
+ * other drivers.
+ */
+ val = fdt_getprop(fdt, nodeoff, "riscv,sbi-mpxy-channel-id", &len);
+ if (len > 0 && val) {
+ channel_id = fdt32_to_cpu(*val);
+ } else {
+ rc = SBI_ENODEV;
+ goto fail_free_chan;
+ }
+
+ /* Create MPXY RPMI instance with mailbox channel discovered from DT */
+ rc = __mpxy_rpmi_init(data, chan, channel_id, &root);
+ if (rc)
+ goto fail_free_chan;
+
+ return SBI_OK;
+
+fail_free_chan:
+ if (chan)
+ mbox_controller_free_chan(chan);
+ return rc;
+}
--
2.43.0
More information about the opensbi
mailing list