From: Andrew Jeffery <andrew@codeconstruct.com.au>
To: Jammy Huang <jammy_huang@aspeedtech.com>,
jassisinghbrar@gmail.com, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, joel@jms.id.au,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-aspeed@lists.ozlabs.org
Subject: Re: [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX series SoC
Date: Fri, 27 Jun 2025 11:24:23 +0930 [thread overview]
Message-ID: <91b94197dc245f70e3cbd05944e8ed3712b7fd25.camel@codeconstruct.com.au> (raw)
In-Reply-To: <20250625073417.2395037-3-jammy_huang@aspeedtech.com>
On Wed, 2025-06-25 at 15:34 +0800, Jammy Huang wrote:
> Add mailbox controller driver for AST27XX SoCs, which provides
> independent tx/rx mailbox between different processors. There are 4
> channels for each tx/rx mailbox and each channel has an 32-byte FIFO.
>
> Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com>
> ---
> drivers/mailbox/Kconfig | 8 +
> drivers/mailbox/Makefile | 2 +
> drivers/mailbox/ast2700-mailbox.c | 240 ++++++++++++++++++++++++++++++
> 3 files changed, 250 insertions(+)
> create mode 100644 drivers/mailbox/ast2700-mailbox.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> index 68eeed660a4a..1c38cd570091 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -340,4 +340,12 @@ config THEAD_TH1520_MBOX
> kernel is running, and E902 core used for power management among other
> things.
>
> +config AST2700_MBOX
> + tristate "ASPEED AST2700 IPC driver"
> + depends on ARCH_ASPEED || COMPILE_TEST
> + help
> + Mailbox driver implementation for ASPEED AST27XX SoCs. This driver
> + can be used to send message between different processors in SoC.
> + The driver provides mailbox support for sending interrupts to the
> + clients. Say Y here if you want to build this driver.
> endif
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> index 13a3448b3271..9a9add9a7548 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -72,3 +72,5 @@ obj-$(CONFIG_QCOM_CPUCP_MBOX) += qcom-cpucp-mbox.o
> obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
>
> obj-$(CONFIG_THEAD_TH1520_MBOX) += mailbox-th1520.o
> +
> +obj-$(CONFIG_AST2700_MBOX) += ast2700-mailbox.o
> diff --git a/drivers/mailbox/ast2700-mailbox.c b/drivers/mailbox/ast2700-mailbox.c
> new file mode 100644
> index 000000000000..5470053f8139
> --- /dev/null
> +++ b/drivers/mailbox/ast2700-mailbox.c
> @@ -0,0 +1,240 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright Aspeed Technology Inc. (C) 2025. All rights reserved
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/mailbox_controller.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +/* Each bit in the register represents an IPC ID */
> +#define IPCR_TX_TRIG 0x00
> +#define IPCR_ENABLE 0x04
> +#define IPCR_STATUS 0x08
> +#define RX_IRQ(n) BIT(n)
> +#define RX_IRQ_MASK 0xf
> +#define IPCR_DATA 0x10
> +
> +struct ast2700_mbox_data {
> + u8 num_chans;
> + u8 msg_size;
> +};
> +
> +struct ast2700_mbox {
> + struct mbox_controller mbox;
> + u8 msg_size;
> + void __iomem *tx_regs;
> + void __iomem *rx_regs;
> + spinlock_t lock;
> +};
> +
> +static inline int ch_num(struct mbox_chan *chan)
> +{
> + return chan - chan->mbox->chans;
> +}
> +
> +static inline bool ast2700_mbox_tx_done(struct ast2700_mbox *mb, int idx)
> +{
> + return !(readl(mb->tx_regs + IPCR_STATUS) & BIT(idx));
> +}
> +
> +static irqreturn_t ast2700_mbox_irq(int irq, void *p)
> +{
> + struct ast2700_mbox *mb = p;
> + void __iomem *data_reg;
> + int num_words;
> + u32 *word_data;
> + u32 status;
> + int n;
> +
> + /* Only examine channels that are currently enabled. */
> + status = readl(mb->rx_regs + IPCR_ENABLE) &
> + readl(mb->rx_regs + IPCR_STATUS);
Also need to lock over these reads to handle concurrent
startup/shutdown?
> +
> + if (!(status & RX_IRQ_MASK))
> + return IRQ_NONE;
> +
> + for (n = 0; n < mb->mbox.num_chans; ++n) {
> + struct mbox_chan *chan = &mb->mbox.chans[n];
> +
> + if (!(status & RX_IRQ(n)))
> + continue;
> +
> + /* Read the message data */
> + for (data_reg = mb->rx_regs + IPCR_DATA + mb->msg_size * n,
> + word_data = chan->con_priv,
> + num_words = (mb->msg_size / sizeof(u32));
> + num_words;
> + num_words--, data_reg += sizeof(u32), word_data++)
> + *word_data = readl(data_reg);
> +
> + mbox_chan_received_data(chan, chan->con_priv);
> +
> + /* The IRQ can be cleared only once the FIFO is empty. */
> + writel(RX_IRQ(n), mb->rx_regs + IPCR_STATUS);
Can we rather clear the status once outside the loop immediately before
return?
writel(status, mb->rx_regs + IPCR_STATUS);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int ast2700_mbox_send_data(struct mbox_chan *chan, void *data)
> +{
> + struct ast2700_mbox *mb = dev_get_drvdata(chan->mbox->dev);
> + void __iomem *data_reg;
> + u32 *word_data;
> + int num_words;
> + int idx = ch_num(chan);
> +
> + if (!(readl(mb->tx_regs + IPCR_ENABLE) & BIT(idx))) {
> + dev_warn(mb->mbox.dev, "%s: Ch-%d not enabled yet\n", __func__, idx);
> + return -EBUSY;
-ENODEV? I wouldn't say it's busy here :)
> + }
> +
> + if (!(ast2700_mbox_tx_done(mb, idx))) {
> + dev_warn(mb->mbox.dev, "%s: Ch-%d last data has not finished\n", __func__, idx);
> + return -EBUSY;
> + }
> +
> + /* Write the message data */
> + for (data_reg = mb->tx_regs + IPCR_DATA + mb->msg_size * idx,
> + word_data = (u32 *)data,
> + num_words = (mb->msg_size / sizeof(u32));
> + num_words;
> + num_words--, data_reg += sizeof(u32), word_data++)
> + writel(*word_data, data_reg);
> +
> + writel(BIT(idx), mb->tx_regs + IPCR_TX_TRIG);
> + dev_dbg(mb->mbox.dev, "%s: Ch-%d sent\n", __func__, idx);
> +
> + return 0;
> +}
> +
*snip*
> +
> +static int ast2700_mbox_probe(struct platform_device *pdev)
> +{
> + struct ast2700_mbox *mb;
> + const struct ast2700_mbox_data *dev_data;
> + struct device *dev = &pdev->dev;
> + int irq, ret;
> +
> + if (!pdev->dev.of_node)
> + return -ENODEV;
> +
> + dev_data = device_get_match_data(&pdev->dev);
> +
> + mb = devm_kzalloc(dev, sizeof(*mb), GFP_KERNEL);
> + if (!mb)
> + return -ENOMEM;
> +
> + mb->mbox.chans = devm_kcalloc(&pdev->dev, dev_data->num_chans,
> + sizeof(*mb->mbox.chans), GFP_KERNEL);
> + if (!mb->mbox.chans)
> + return -ENOMEM;
> +
> + /* con_priv of each channel is used to store the message received */
> + for (int i = 0; i < dev_data->num_chans; i++) {
> + mb->mbox.chans[i].con_priv = devm_kcalloc(dev, dev_data->msg_size,
> + sizeof(u8), GFP_KERNEL);
> + if (!mb->mbox.chans[i].con_priv)
> + return -ENOMEM;
> + }
> +
> + platform_set_drvdata(pdev, mb);
> +
> + mb->tx_regs = devm_platform_ioremap_resource(pdev, 0);
See the thought about reg-names on the binding.
Andrew
next prev parent reply other threads:[~2025-06-27 1:54 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-25 7:34 [PATCH v5 0/2] ASPEED: Add mailbox driver for AST2700 series Jammy Huang
2025-06-25 7:34 ` [PATCH v5 1/2] dt-bindings: mailbox: Add ASPEED AST2700 series SoC Jammy Huang
2025-06-25 15:50 ` Rob Herring
2025-06-26 3:41 ` Jammy Huang
2025-06-27 1:52 ` Andrew Jeffery
2025-06-27 2:22 ` Jammy Huang
2025-06-25 7:34 ` [PATCH v5 2/2] mailbox: aspeed: add mailbox driver for AST27XX " Jammy Huang
2025-06-27 1:54 ` Andrew Jeffery [this message]
2025-06-27 2:21 ` Jammy Huang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=91b94197dc245f70e3cbd05944e8ed3712b7fd25.camel@codeconstruct.com.au \
--to=andrew@codeconstruct.com.au \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jammy_huang@aspeedtech.com \
--cc=jassisinghbrar@gmail.com \
--cc=joel@jms.id.au \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.