mailbox: add list of used channels to debugfs

During development, it is useful to see which mailboxes are currently
obtained. Use a seq-file in debugfs to list the currently registered
controllers and their used channels. Example output from a Renesas R-Car
X5H based system:

 # cat /sys/kernel/debug/mailbox/mailbox_summary

189e0000.system-controller:
   0: c1000000.mailbox_test_send_to_recv
   1: c1000100.mailbox_test_recv_to_send
 128: c1000100.mailbox_test_recv_to_send
 129: c1000000.mailbox_test_send_to_recv
189e1000.system-controller:
   4: scmi_dev.1
   5: scmi_dev.2

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
This commit is contained in:
Wolfram Sang 2026-05-06 09:16:06 +02:00 committed by Jassi Brar
parent 4f176444dc
commit 5e4907c490

View File

@ -7,6 +7,7 @@
*/
#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
@ -16,6 +17,7 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
static LIST_HEAD(mbox_cons);
@ -644,3 +646,66 @@ int devm_mbox_controller_register(struct device *dev,
return 0;
}
EXPORT_SYMBOL_GPL(devm_mbox_controller_register);
#ifdef CONFIG_DEBUG_FS
static void *mbox_seq_start(struct seq_file *s, loff_t *pos)
{
mutex_lock(&con_mutex);
return seq_list_start(&mbox_cons, *pos);
}
static void *mbox_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
return seq_list_next(v, &mbox_cons, pos);
}
static void mbox_seq_stop(struct seq_file *s, void *v)
{
mutex_unlock(&con_mutex);
}
static int mbox_seq_show(struct seq_file *seq, void *v)
{
const struct mbox_controller *mbox = list_entry(v, struct mbox_controller, node);
seq_printf(seq, "%s:\n", dev_name(mbox->dev));
for (unsigned int i = 0; i < mbox->num_chans; i++) {
struct mbox_chan *chan = &mbox->chans[i];
scoped_guard(spinlock_irqsave, &chan->lock) {
if (chan->cl) {
struct device *cl_dev = chan->cl->dev;
seq_printf(seq, " %3u: %s\n", i,
cl_dev ? dev_name(cl_dev) : "NULL device");
}
}
}
return 0;
}
static const struct seq_operations mbox_sops = {
.start = mbox_seq_start,
.next = mbox_seq_next,
.stop = mbox_seq_stop,
.show = mbox_seq_show,
};
DEFINE_SEQ_ATTRIBUTE(mbox);
/*
* subsys_initcall() is used here but controllers may already have been
* registered earlier or will be later. The rationale is that debugfs is
* accessed only late, i.e. from userspace. So, files created here must make no
* assumptions about initcall ordering.
*/
static int __init mbox_init(void)
{
struct dentry *mbox_debugfs = debugfs_create_dir("mailbox", NULL);
debugfs_create_file("mailbox_summary", 0444, mbox_debugfs, NULL, &mbox_fops);
return 0;
}
subsys_initcall(mbox_init);
#endif /* DEBUG_FS */