lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260110-ums9230-mailbox-v1-3-5941cab4f4e5@abscue.de>
Date: Sat, 10 Jan 2026 16:43:37 +0100
From: Otto Pflüger <otto.pflueger@...cue.de>
To: Jassi Brar <jassisinghbrar@...il.com>, Rob Herring <robh@...nel.org>, 
 Krzysztof Kozlowski <krzk+dt@...nel.org>, 
 Conor Dooley <conor+dt@...nel.org>, Orson Zhai <orsonzhai@...il.com>, 
 Baolin Wang <baolin.wang@...ux.alibaba.com>, 
 Chunyan Zhang <zhang.lyra@...il.com>
Cc: linux-kernel@...r.kernel.org, devicetree@...r.kernel.org, 
 Otto Pflüger <otto.pflueger@...cue.de>
Subject: [PATCH 3/4] mailbox: sprd: add support for mailbox revision 2

Newer Unisoc SoCs such as UMS9230 include a new revision of the mailbox
IP with support for up to 16 channels. Since the new revision has a
similar register layout and many parts have remained unchanged, make the
driver support both revisions.

Signed-off-by: Otto Pflüger <otto.pflueger@...cue.de>
---
 drivers/mailbox/sprd-mailbox.c | 103 ++++++++++++++++++++++++++++++++---------
 1 file changed, 82 insertions(+), 21 deletions(-)

diff --git a/drivers/mailbox/sprd-mailbox.c b/drivers/mailbox/sprd-mailbox.c
index 9a3d388f76b78632ca08948e0fe0ad484aed23c3..26256581a76ad59785a1c87a34eb91f5985dc948 100644
--- a/drivers/mailbox/sprd-mailbox.c
+++ b/drivers/mailbox/sprd-mailbox.c
@@ -24,7 +24,8 @@
 #define SPRD_MBOX_IRQ_STS	0x18
 #define SPRD_MBOX_IRQ_MSK	0x1c
 #define SPRD_MBOX_LOCK		0x20
-#define SPRD_MBOX_FIFO_DEPTH	0x24
+#define SPRD_MBOX_FIFO_DEPTH	0x24 /* outbox only */
+#define SPRD_MBOX_IN_FIFO_STS2	0x24 /* inbox only, revision 2 */
 
 /* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */
 #define SPRD_INBOX_FIFO_DELIVER_MASK		GENMASK(23, 16)
@@ -32,8 +33,18 @@
 #define SPRD_INBOX_FIFO_DELIVER_SHIFT		16
 #define SPRD_INBOX_FIFO_BUSY_MASK		GENMASK(7, 0)
 
+/* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_RST register */
+#define SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST	GENMASK(31, 0)
+
+/* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_STS register */
+#define SPRD_INBOX_R2_FIFO_DELIVER_MASK		GENMASK(15, 0)
+
+/* Bit and mask definition for SPRD_MBOX_IN_FIFO_STS2 register */
+#define SPRD_INBOX_R2_FIFO_OVERFLOW_MASK	GENMASK(31, 16)
+#define SPRD_INBOX_R2_FIFO_BUSY_MASK		GENMASK(15, 0)
+
 /* Bit and mask definition for SPRD_MBOX_IRQ_STS register */
-#define SPRD_MBOX_IRQ_CLR			BIT(0)
+#define SPRD_MBOX_IRQ_CLR			GENMASK(31, 0)
 
 /* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */
 #define SPRD_OUTBOX_FIFO_FULL			BIT(2)
@@ -52,8 +63,18 @@
 #define SPRD_OUTBOX_FIFO_IRQ_MASK		GENMASK(4, 0)
 
 #define SPRD_OUTBOX_BASE_SPAN			0x1000
-#define SPRD_MBOX_CHAN_MAX			8
-#define SPRD_SUPP_INBOX_ID_SC9863A		7
+#define SPRD_MBOX_R1_CHAN_MAX			8
+#define SPRD_MBOX_R2_CHAN_MAX			16
+
+enum sprd_mbox_version {
+	SPRD_MBOX_R1,
+	SPRD_MBOX_R2,
+};
+
+struct sprd_mbox_info {
+	enum sprd_mbox_version version;
+	unsigned long supp_id;
+};
 
 struct sprd_mbox_priv {
 	struct mbox_controller	mbox;
@@ -64,9 +85,11 @@ struct sprd_mbox_priv {
 	void __iomem		*supp_base;
 	u32			outbox_fifo_depth;
 
+	const struct sprd_mbox_info *info;
+
 	struct mutex		lock;
 	u32			refcnt;
-	struct mbox_chan	chan[SPRD_MBOX_CHAN_MAX];
+	struct mbox_chan	chan[SPRD_MBOX_R2_CHAN_MAX];
 };
 
 static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox)
@@ -154,22 +177,34 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
 {
 	struct sprd_mbox_priv *priv = data;
 	struct mbox_chan *chan;
-	u32 fifo_sts, send_sts, busy, id;
+	u32 fifo_sts, fifo_sts2, send_sts, busy, id;
 
 	fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS);
 
+	if (priv->info->version == SPRD_MBOX_R2)
+		fifo_sts2 = readl(priv->inbox_base + SPRD_MBOX_IN_FIFO_STS2);
+
 	/* Get the inbox data delivery status */
-	send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >>
-		SPRD_INBOX_FIFO_DELIVER_SHIFT;
+	if (priv->info->version == SPRD_MBOX_R2) {
+		send_sts = fifo_sts & SPRD_INBOX_R2_FIFO_DELIVER_MASK;
+	} else {
+		send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >>
+			SPRD_INBOX_FIFO_DELIVER_SHIFT;
+	}
+
 	if (!send_sts) {
 		dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n");
 		return IRQ_NONE;
 	}
 
 	/* Clear FIFO delivery and overflow status first */
-	writel(fifo_sts &
-	       (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK),
-	       priv->inbox_base + SPRD_MBOX_FIFO_RST);
+	if (priv->info->version == SPRD_MBOX_R2) {
+		writel(SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST,
+		       priv->inbox_base + SPRD_MBOX_FIFO_RST);
+	} else {
+		writel(fifo_sts & (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK),
+		       priv->inbox_base + SPRD_MBOX_FIFO_RST);
+	}
 
 	while (send_sts) {
 		id = __ffs(send_sts);
@@ -181,7 +216,11 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
 		 * Check if the message was fetched by remote target, if yes,
 		 * that means the transmission has been completed.
 		 */
-		busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK;
+		if (priv->info->version == SPRD_MBOX_R2)
+			busy = fifo_sts2 & SPRD_INBOX_R2_FIFO_BUSY_MASK;
+		else
+			busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK;
+
 		if (!(busy & BIT(id)))
 			mbox_chan_txdone(chan, 0);
 	}
@@ -295,7 +334,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct sprd_mbox_priv *priv;
 	int ret, inbox_irq, outbox_irq, supp_irq;
-	unsigned long id, supp;
+	unsigned long id;
 	struct clk *clk;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -305,6 +344,10 @@ static int sprd_mbox_probe(struct platform_device *pdev)
 	priv->dev = dev;
 	mutex_init(&priv->lock);
 
+	priv->info = of_device_get_match_data(dev);
+	if (!priv->info)
+		return -EINVAL;
+
 	/*
 	 * Unisoc mailbox uses an inbox to send messages to the target
 	 * core, and uses (an) outbox(es) to receive messages from other
@@ -362,12 +405,12 @@ static int sprd_mbox_probe(struct platform_device *pdev)
 			return ret;
 		}
 
-		supp = (unsigned long) of_device_get_match_data(dev);
-		if (!supp) {
+		if (!priv->info->supp_id) {
 			dev_err(dev, "no supplementary outbox specified\n");
 			return -ENODEV;
 		}
-		priv->supp_base = priv->outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp);
+		priv->supp_base = priv->outbox_base +
+			(SPRD_OUTBOX_BASE_SPAN * priv->info->supp_id);
 	}
 
 	/* Get the default outbox FIFO depth */
@@ -375,11 +418,15 @@ static int sprd_mbox_probe(struct platform_device *pdev)
 		readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1;
 	priv->mbox.dev = dev;
 	priv->mbox.chans = &priv->chan[0];
-	priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX;
 	priv->mbox.ops = &sprd_mbox_ops;
 	priv->mbox.txdone_irq = true;
 
-	for (id = 0; id < SPRD_MBOX_CHAN_MAX; id++)
+	if (priv->info->version == SPRD_MBOX_R2)
+		priv->mbox.num_chans = SPRD_MBOX_R2_CHAN_MAX;
+	else
+		priv->mbox.num_chans = SPRD_MBOX_R1_CHAN_MAX;
+
+	for (id = 0; id < priv->mbox.num_chans; id++)
 		priv->chan[id].con_priv = (void *)id;
 
 	ret = devm_mbox_controller_register(dev, &priv->mbox);
@@ -391,10 +438,24 @@ static int sprd_mbox_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sprd_mbox_info sc9860_mbox_info = {
+	.version = SPRD_MBOX_R1,
+};
+
+static const struct sprd_mbox_info sc9863a_mbox_info = {
+	.version = SPRD_MBOX_R1,
+	.supp_id = 7,
+};
+
+static const struct sprd_mbox_info ums9230_mbox_info = {
+	.version = SPRD_MBOX_R2,
+	.supp_id = 6,
+};
+
 static const struct of_device_id sprd_mbox_of_match[] = {
-	{ .compatible = "sprd,sc9860-mailbox" },
-	{ .compatible = "sprd,sc9863a-mailbox",
-	  .data = (void *)SPRD_SUPP_INBOX_ID_SC9863A },
+	{ .compatible = "sprd,sc9860-mailbox", .data = &sc9860_mbox_info },
+	{ .compatible = "sprd,sc9863a-mailbox", .data = &sc9863a_mbox_info },
+	{ .compatible = "sprd,ums9230-mailbox", .data = &ums9230_mbox_info },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, sprd_mbox_of_match);

-- 
2.50.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ