[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241220-acpm-v4-upstream-mbox-v6-3-a6942806e52a@linaro.org>
Date: Fri, 20 Dec 2024 13:49:58 +0000
From: Tudor Ambarus <tudor.ambarus@...aro.org>
To: Jassi Brar <jassisinghbrar@...il.com>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>, Krzysztof Kozlowski <krzk@...nel.org>,
Alim Akhtar <alim.akhtar@...sung.com>
Cc: linux-kernel@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
devicetree@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
andre.draszik@...aro.org, peter.griffin@...aro.org, kernel-team@...roid.com,
willmcvicker@...gle.com, daniel.lezcano@...aro.org,
vincent.guittot@...aro.org, ulf.hansson@...aro.org, arnd@...db.de,
Tudor Ambarus <tudor.ambarus@...aro.org>
Subject: [PATCH v6 3/5] mailbox: add support for clients to request
channels by args
There are clients that can discover channel identifiers at runtime by
parsing a shared memory for example, as in the ACPM interface's case.
Supply a new framework API: mbox_request_channel_by_args().
It works by supplying the usual client pointer as the first argument,
the usual index of the mailbox specifier in the 'mboxes' property as
a second argument, and a pointer to a 'const struct mbox_xlate_args'
as a third. The newly introduced struct is modeled after
'struct of_phandle_args'. The API identifies the controller's device
node, and then calls that controller's xlate() method that will return
a pointer to a mbox_chan or a ERR_PTR. The binding between the channel
and the client is done in the typical way.
Signed-off-by: Tudor Ambarus <tudor.ambarus@...aro.org>
---
drivers/mailbox/mailbox.c | 60 ++++++++++++++++++++++++++++++++++++++
include/linux/mailbox.h | 17 +++++++++++
include/linux/mailbox_client.h | 3 ++
include/linux/mailbox_controller.h | 4 +++
4 files changed, 84 insertions(+)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index d3d26a2c9895..0eecffd5a2ad 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -467,6 +467,66 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
}
EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
+/**
+ * mbox_request_channel_by_args - request a mailbox channel using client's
+ * channel identifiers.
+ * @cl: identity of the client requesting the channel.
+ * @index: index of mailbox specifier in 'mboxes' property.
+ * @spec: arguments that describe the channel.
+ *
+ * Used by clients that can discover the channel identifiers at runtime (by
+ * parsing a shared memory for example). The description of
+ * mbox_request_channel() applies here as well.
+ *
+ * Return: Pointer to the channel assigned to the client if successful.
+ * ERR_PTR for request failure.
+ */
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+ int index, const struct mbox_xlate_args *mbox_spec)
+{
+ struct of_phandle_args of_args;
+ struct device *dev = cl->dev;
+ struct mbox_controller *mbox;
+ struct mbox_chan *chan;
+ int ret;
+
+ if (!dev || !dev->of_node) {
+ pr_debug("%s: No owner device node\n", __func__);
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (of_parse_phandle_with_args(dev->of_node, "mboxes",
+ "#mbox-cells", index, &of_args)) {
+ dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
+ return ERR_PTR(-ENODEV);
+ }
+
+ mutex_lock(&con_mutex);
+
+ chan = ERR_PTR(-EPROBE_DEFER);
+ list_for_each_entry(mbox, &mbox_cons, node)
+ if (mbox->dev->of_node == of_args.np && mbox->xlate) {
+ chan = mbox->xlate(mbox, mbox_spec);
+ if (!IS_ERR(chan))
+ break;
+ }
+
+ of_node_put(of_args.np);
+
+ if (IS_ERR(chan)) {
+ mutex_unlock(&con_mutex);
+ return chan;
+ }
+
+ ret = __mbox_bind_client(chan, cl);
+ if (ret)
+ chan = ERR_PTR(ret);
+
+ mutex_unlock(&con_mutex);
+ return chan;
+}
+EXPORT_SYMBOL_GPL(mbox_request_channel_by_args);
+
/**
* mbox_free_channel - The client relinquishes control of a mailbox
* channel by this call.
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
new file mode 100644
index 000000000000..cef88c5ae49d
--- /dev/null
+++ b/include/linux/mailbox.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __LINUX_MAILBOX_H
+#define __LINUX_MAILBOX_H
+
+#include <linux/types.h>
+
+#define MBOX_XLATE_MAX_ARGS 16
+struct mbox_xlate_args {
+ int args_count;
+ u32 args[MBOX_XLATE_MAX_ARGS];
+};
+
+#endif /* __LINUX_MAILBOX_H */
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 734694912ef7..06e2721313ca 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -9,6 +9,7 @@
#include <linux/of.h>
#include <linux/device.h>
+#include <linux/mailbox.h>
struct mbox_chan;
@@ -41,6 +42,8 @@ int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
const char *name);
struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+ int index, const struct mbox_xlate_args *mbox_spec);
int mbox_send_message(struct mbox_chan *chan, void *mssg);
int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 6fee33cb52f5..dfddcf966f9f 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -8,6 +8,7 @@
#include <linux/hrtimer.h>
#include <linux/device.h>
#include <linux/completion.h>
+#include <linux/mailbox.h>
struct mbox_chan;
@@ -67,6 +68,7 @@ struct mbox_chan_ops {
* @txpoll_period: If 'txdone_poll' is in effect, the API polls for
* last TX's status after these many millisecs
* @of_xlate: Controller driver specific mapping of channel via DT
+ * @xlate: Controller driver specific mapping of channel
* @poll_hrt: API private. hrtimer used to poll for TXDONE on all
* channels.
* @node: API private. To hook into list of controllers.
@@ -81,6 +83,8 @@ struct mbox_controller {
unsigned txpoll_period;
struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
const struct of_phandle_args *sp);
+ struct mbox_chan *(*xlate)(struct mbox_controller *mbox,
+ const struct mbox_xlate_args *sp);
/* Internal to API */
struct hrtimer poll_hrt;
spinlock_t poll_hrt_lock;
--
2.47.1.613.gc27f4b7a9f-goog
Powered by blists - more mailing lists