summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml2
-rw-r--r--Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml13
-rw-r--r--Documentation/devicetree/bindings/mailbox/ti,secure-proxy.txt50
-rw-r--r--Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml79
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/mailbox/Kconfig2
-rw-r--r--drivers/mailbox/arm_mhu_db.c4
-rw-r--r--drivers/mailbox/bcm-flexrm-mailbox.c4
-rw-r--r--drivers/mailbox/mailbox-xgene-slimpro.c6
-rw-r--r--drivers/mailbox/mailbox.h2
-rw-r--r--drivers/mailbox/pcc.c3
-rw-r--r--drivers/mailbox/pl320-ipc.c2
-rw-r--r--drivers/mailbox/sprd-mailbox.c147
-rw-r--r--drivers/mailbox/ti-msgmgr.c2
14 files changed, 212 insertions, 105 deletions
diff --git a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
index 168beeb7e9f7..b222f993b232 100644
--- a/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
+++ b/Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
@@ -25,6 +25,8 @@ properties:
items:
- enum:
- qcom,sm8250-ipcc
+ - qcom,sm8350-ipcc
+ - qcom,sc7280-ipcc
- const: qcom,ipcc
reg:
diff --git a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
index 26a5cca3f838..80feba82cbd6 100644
--- a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
@@ -15,6 +15,7 @@ properties:
compatible:
enum:
- sprd,sc9860-mailbox
+ - sprd,sc9863a-mailbox
reg:
items:
@@ -22,9 +23,15 @@ properties:
- description: outbox registers' base address
interrupts:
+ minItems: 2
+ maxItems: 3
+
+ interrupt-names:
+ minItems: 2
items:
- - description: inbox interrupt
- - description: outbox interrupt
+ - const: inbox
+ - const: outbox
+ - const: supp-outbox
clocks:
maxItems: 1
@@ -40,6 +47,7 @@ required:
- compatible
- reg
- interrupts
+ - interrupt-names
- "#mbox-cells"
- clocks
- clock-names
@@ -56,5 +64,6 @@ examples:
clock-names = "enable";
clocks = <&aon_gate 53>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "inbox", "outbox";
};
...
diff --git a/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.txt b/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.txt
deleted file mode 100644
index 6c9c7daf0f5c..000000000000
--- a/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-Texas Instruments' Secure Proxy
-========================================
-
-The Texas Instruments' secure proxy is a mailbox controller that has
-configurable queues selectable at SoC(System on Chip) integration. The
-Message manager is broken up into different address regions that are
-called "threads" or "proxies" - each instance is unidirectional and is
-instantiated at SoC integration level by system controller to indicate
-receive or transmit path.
-
-Message Manager Device Node:
-===========================
-Required properties:
---------------------
-- compatible: Shall be "ti,am654-secure-proxy"
-- reg-names target_data - Map the proxy data region
- rt - Map the realtime status region
- scfg - Map the configuration region
-- reg: Contains the register map per reg-names.
-- #mbox-cells Shall be 1 and shall refer to the transfer path
- called thread.
-- interrupt-names: Contains interrupt names matching the rx transfer path
- for a given SoC. Receive interrupts shall be of the
- format: "rx_<PID>".
-- interrupts: Contains the interrupt information corresponding to
- interrupt-names property.
-
-Example(AM654):
-------------
-
- secure_proxy: mailbox@32c00000 {
- compatible = "ti,am654-secure-proxy";
- #mbox-cells = <1>;
- reg-names = "target_data", "rt", "scfg";
- reg = <0x0 0x32c00000 0x0 0x100000>,
- <0x0 0x32400000 0x0 0x100000>,
- <0x0 0x32800000 0x0 0x100000>;
- interrupt-names = "rx_011";
- interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- dmsc: dmsc {
- [...]
- mbox-names = "rx", "tx";
- # RX Thread ID is 11
- # TX Thread ID is 13
- mboxes= <&secure_proxy 11>,
- <&secure_proxy 13>;
- [...]
- };
diff --git a/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml b/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml
new file mode 100644
index 000000000000..eea822861804
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/ti,secure-proxy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments' Secure Proxy
+
+maintainers:
+ - Nishanth Menon <nm@ti.com>
+
+description: |
+ The Texas Instruments' secure proxy is a mailbox controller that has
+ configurable queues selectable at SoC(System on Chip) integration. The
+ Message manager is broken up into different address regions that are
+ called "threads" or "proxies" - each instance is unidirectional and is
+ instantiated at SoC integration level by system controller to indicate
+ receive or transmit path.
+
+properties:
+ $nodename:
+ pattern: "^mailbox@[0-9a-f]+$"
+
+ compatible:
+ const: ti,am654-secure-proxy
+
+ "#mbox-cells":
+ const: 1
+ description:
+ Contains the secure proxy thread ID used for the specific transfer path.
+
+ reg-names:
+ items:
+ - const: target_data
+ - const: rt
+ - const: scfg
+
+ reg:
+ minItems: 3
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 100
+ items:
+ pattern: "^rx_[0-9]{3}$"
+ description:
+ Contains the interrupt name information for the Rx interrupt path for
+ secure proxy thread in the form 'rx_<PID>'.
+
+ interrupts:
+ minItems: 1
+ maxItems: 100
+ description:
+ Contains the interrupt information for the Rx interrupt path for secure
+ proxy.
+
+required:
+ - compatible
+ - reg-names
+ - reg
+ - interrupt-names
+ - interrupts
+ - "#mbox-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ secure_proxy: mailbox@32c00000 {
+ compatible = "ti,am654-secure-proxy";
+ #mbox-cells = <1>;
+ reg-names = "target_data", "rt", "scfg";
+ reg = <0x32c00000 0x100000>,
+ <0x32400000 0x100000>,
+ <0x32800000 0x100000>;
+ interrupt-names = "rx_011";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index bccfb16e3d98..8f4a072f47ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10772,6 +10772,7 @@ S: Maintained
F: drivers/mailbox/
F: include/linux/mailbox_client.h
F: include/linux/mailbox_controller.h
+F: Documentation/devicetree/bindings/mailbox/
MAILBOX ARM MHUv2
M: Viresh Kumar <viresh.kumar@linaro.org>
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index f4abe3529acd..68de2c6af727 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -78,7 +78,7 @@ config OMAP_MBOX_KFIFO_SIZE
module parameter).
config ROCKCHIP_MBOX
- bool "Rockchip Soc Intergrated Mailbox Support"
+ bool "Rockchip Soc Integrated Mailbox Support"
depends on ARCH_ROCKCHIP || COMPILE_TEST
help
This driver provides support for inter-processor communication
diff --git a/drivers/mailbox/arm_mhu_db.c b/drivers/mailbox/arm_mhu_db.c
index 8eb66c4ecf5b..8674153cc893 100644
--- a/drivers/mailbox/arm_mhu_db.c
+++ b/drivers/mailbox/arm_mhu_db.c
@@ -278,10 +278,8 @@ static int mhu_db_probe(struct amba_device *adev, const struct amba_id *id)
return -ENOMEM;
mhu->base = devm_ioremap_resource(dev, &adev->res);
- if (IS_ERR(mhu->base)) {
- dev_err(dev, "ioremap failed\n");
+ if (IS_ERR(mhu->base))
return PTR_ERR(mhu->base);
- }
chans = devm_kcalloc(dev, max_chans, sizeof(*chans), GFP_KERNEL);
if (!chans)
diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c
index bee33abb5308..b4f33dc399a0 100644
--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -423,7 +423,7 @@ static void flexrm_enqueue_desc(u32 nhpos, u32 nhcnt, u32 reqid,
*
* In general use, number of non-HEADER descriptors can easily go
* beyond 31. To tackle this situation, we have packet (or request)
- * extenstion bits (STARTPKT and ENDPKT) in the HEADER descriptor.
+ * extension bits (STARTPKT and ENDPKT) in the HEADER descriptor.
*
* To use packet extension, the first HEADER descriptor of request
* (or packet) will have STARTPKT=1 and ENDPKT=0. The intermediate
@@ -1095,7 +1095,7 @@ static int flexrm_process_completions(struct flexrm_ring *ring)
/*
* Get current completion read and write offset
*
- * Note: We should read completion write pointer atleast once
+ * Note: We should read completion write pointer at least once
* after we get a MSI interrupt because HW maintains internal
* MSI status which will allow next MSI interrupt only after
* completion write pointer is read.
diff --git a/drivers/mailbox/mailbox-xgene-slimpro.c b/drivers/mailbox/mailbox-xgene-slimpro.c
index de260799f1b9..5b3a2dcd5955 100644
--- a/drivers/mailbox/mailbox-xgene-slimpro.c
+++ b/drivers/mailbox/mailbox-xgene-slimpro.c
@@ -51,10 +51,10 @@ struct slimpro_mbox_chan {
/**
* X-Gene SlimPRO Mailbox controller data
*
- * X-Gene SlimPRO Mailbox controller has 8 commnunication channels.
- * Each channel has a separate IRQ number assgined to it.
+ * X-Gene SlimPRO Mailbox controller has 8 communication channels.
+ * Each channel has a separate IRQ number assigned to it.
*
- * @mb_ctrl: Representation of the commnunication channel controller
+ * @mb_ctrl: Representation of the communication channel controller
* @mc: Array of SlimPRO mailbox channels of the controller
* @chans: Array of mailbox communication channels
*
diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h
index 4e3cc4426513..046d6d258b32 100644
--- a/drivers/mailbox/mailbox.h
+++ b/drivers/mailbox/mailbox.h
@@ -5,6 +5,6 @@
#define TXDONE_BY_IRQ BIT(0) /* controller has remote RTR irq */
#define TXDONE_BY_POLL BIT(1) /* controller can read status of last TX */
-#define TXDONE_BY_ACK BIT(2) /* S/W ACK recevied by Client ticks the TX */
+#define TXDONE_BY_ACK BIT(2) /* S/W ACK received by Client ticks the TX */
#endif /* __MAILBOX_H */
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index ef9ecd1f5958..0296558f9e22 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -32,7 +32,7 @@
* * Client writes WRITE cmd in communication region cmd address.
* * Client issues mbox_send_message() which rings the PCC doorbell
* for its PCC channel.
- * * If command completes, then writes have succeded and it can release
+ * * If command completes, then writes have succeeded and it can release
* the channel lock.
*
* There is a Nominal latency defined for each channel which indicates
@@ -577,7 +577,6 @@ static struct platform_driver pcc_mbox_driver = {
.probe = pcc_mbox_probe,
.driver = {
.name = "PCCT",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c
index 25e0b6f7a10f..fbcf07930390 100644
--- a/drivers/mailbox/pl320-ipc.c
+++ b/drivers/mailbox/pl320-ipc.c
@@ -73,7 +73,7 @@ static u32 __ipc_rcv(int mbox, u32 *data)
return data[1];
}
-/* blocking implmentation from the A9 side, not usuable in interrupts! */
+/* blocking implementation from the A9 side, not usable in interrupts! */
int pl320_ipc_transmit(u32 *data)
{
int ret;
diff --git a/drivers/mailbox/sprd-mailbox.c b/drivers/mailbox/sprd-mailbox.c
index 4c325301a2fe..e3c899abeed8 100644
--- a/drivers/mailbox/sprd-mailbox.c
+++ b/drivers/mailbox/sprd-mailbox.c
@@ -11,6 +11,7 @@
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -25,41 +26,47 @@
#define SPRD_MBOX_LOCK 0x20
#define SPRD_MBOX_FIFO_DEPTH 0x24
-/* Bit and mask definiation for inbox's SPRD_MBOX_FIFO_STS register */
+/* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */
#define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16)
#define SPRD_INBOX_FIFO_OVERLOW_MASK GENMASK(15, 8)
#define SPRD_INBOX_FIFO_DELIVER_SHIFT 16
#define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0)
-/* Bit and mask definiation for SPRD_MBOX_IRQ_STS register */
+/* Bit and mask definition for SPRD_MBOX_IRQ_STS register */
#define SPRD_MBOX_IRQ_CLR BIT(0)
-/* Bit and mask definiation for outbox's SPRD_MBOX_FIFO_STS register */
+/* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */
#define SPRD_OUTBOX_FIFO_FULL BIT(2)
#define SPRD_OUTBOX_FIFO_WR_SHIFT 16
#define SPRD_OUTBOX_FIFO_RD_SHIFT 24
#define SPRD_OUTBOX_FIFO_POS_MASK GENMASK(7, 0)
-/* Bit and mask definiation for inbox's SPRD_MBOX_IRQ_MSK register */
+/* Bit and mask definition for inbox's SPRD_MBOX_IRQ_MSK register */
#define SPRD_INBOX_FIFO_BLOCK_IRQ BIT(0)
#define SPRD_INBOX_FIFO_OVERFLOW_IRQ BIT(1)
#define SPRD_INBOX_FIFO_DELIVER_IRQ BIT(2)
#define SPRD_INBOX_FIFO_IRQ_MASK GENMASK(2, 0)
-/* Bit and mask definiation for outbox's SPRD_MBOX_IRQ_MSK register */
+/* Bit and mask definition for outbox's SPRD_MBOX_IRQ_MSK register */
#define SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ BIT(0)
#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
struct sprd_mbox_priv {
struct mbox_controller mbox;
struct device *dev;
void __iomem *inbox_base;
void __iomem *outbox_base;
+ /* Base register address for supplementary outbox */
+ void __iomem *supp_base;
struct clk *clk;
u32 outbox_fifo_depth;
+ struct mutex lock;
+ u32 refcnt;
struct mbox_chan chan[SPRD_MBOX_CHAN_MAX];
};
@@ -94,14 +101,13 @@ static u32 sprd_mbox_get_fifo_len(struct sprd_mbox_priv *priv, u32 fifo_sts)
return fifo_len;
}
-static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data)
+static irqreturn_t do_outbox_isr(void __iomem *base, struct sprd_mbox_priv *priv)
{
- struct sprd_mbox_priv *priv = data;
struct mbox_chan *chan;
u32 fifo_sts, fifo_len, msg[2];
int i, id;
- fifo_sts = readl(priv->outbox_base + SPRD_MBOX_FIFO_STS);
+ fifo_sts = readl(base + SPRD_MBOX_FIFO_STS);
fifo_len = sprd_mbox_get_fifo_len(priv, fifo_sts);
if (!fifo_len) {
@@ -110,23 +116,41 @@ static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data)
}
for (i = 0; i < fifo_len; i++) {
- msg[0] = readl(priv->outbox_base + SPRD_MBOX_MSG_LOW);
- msg[1] = readl(priv->outbox_base + SPRD_MBOX_MSG_HIGH);
- id = readl(priv->outbox_base + SPRD_MBOX_ID);
+ msg[0] = readl(base + SPRD_MBOX_MSG_LOW);
+ msg[1] = readl(base + SPRD_MBOX_MSG_HIGH);
+ id = readl(base + SPRD_MBOX_ID);
chan = &priv->chan[id];
- mbox_chan_received_data(chan, (void *)msg);
+ if (chan->cl)
+ mbox_chan_received_data(chan, (void *)msg);
+ else
+ dev_warn_ratelimited(priv->dev,
+ "message's been dropped at ch[%d]\n", id);
/* Trigger to update outbox FIFO pointer */
- writel(0x1, priv->outbox_base + SPRD_MBOX_TRIGGER);
+ writel(0x1, base + SPRD_MBOX_TRIGGER);
}
/* Clear irq status after reading all message. */
- writel(SPRD_MBOX_IRQ_CLR, priv->outbox_base + SPRD_MBOX_IRQ_STS);
+ writel(SPRD_MBOX_IRQ_CLR, base + SPRD_MBOX_IRQ_STS);
return IRQ_HANDLED;
}
+static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data)
+{
+ struct sprd_mbox_priv *priv = data;
+
+ return do_outbox_isr(priv->outbox_base, priv);
+}
+
+static irqreturn_t sprd_mbox_supp_isr(int irq, void *data)
+{
+ struct sprd_mbox_priv *priv = data;
+
+ return do_outbox_isr(priv->supp_base, priv);
+}
+
static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
{
struct sprd_mbox_priv *priv = data;
@@ -150,7 +174,7 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
chan = &priv->chan[id];
/*
- * Check if the message was fetched by remote traget, if yes,
+ * 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;
@@ -215,18 +239,30 @@ static int sprd_mbox_startup(struct mbox_chan *chan)
struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
u32 val;
- /* Select outbox FIFO mode and reset the outbox FIFO status */
- writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST);
-
- /* Enable inbox FIFO overflow and delivery interrupt */
- val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK);
- val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ);
- writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
-
- /* Enable outbox FIFO not empty interrupt */
- val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK);
- val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
- writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+ mutex_lock(&priv->lock);
+ if (priv->refcnt++ == 0) {
+ /* Select outbox FIFO mode and reset the outbox FIFO status */
+ writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST);
+
+ /* Enable inbox FIFO overflow and delivery interrupt */
+ val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+ val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ);
+ writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+
+ /* Enable outbox FIFO not empty interrupt */
+ val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+ val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
+ writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+
+ /* Enable supplementary outbox as the fundamental one */
+ if (priv->supp_base) {
+ writel(0x0, priv->supp_base + SPRD_MBOX_FIFO_RST);
+ val = readl(priv->supp_base + SPRD_MBOX_IRQ_MSK);
+ val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
+ writel(val, priv->supp_base + SPRD_MBOX_IRQ_MSK);
+ }
+ }
+ mutex_unlock(&priv->lock);
return 0;
}
@@ -235,9 +271,17 @@ static void sprd_mbox_shutdown(struct mbox_chan *chan)
{
struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
- /* Disable inbox & outbox interrupt */
- writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
- writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+ mutex_lock(&priv->lock);
+ if (--priv->refcnt == 0) {
+ /* Disable inbox & outbox interrupt */
+ writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+ writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+
+ if (priv->supp_base)
+ writel(SPRD_OUTBOX_FIFO_IRQ_MASK,
+ priv->supp_base + SPRD_MBOX_IRQ_MSK);
+ }
+ mutex_unlock(&priv->lock);
}
static const struct mbox_chan_ops sprd_mbox_ops = {
@@ -258,21 +302,26 @@ 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;
- unsigned long id;
+ int ret, inbox_irq, outbox_irq, supp_irq;
+ unsigned long id, supp;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = dev;
+ mutex_init(&priv->lock);
/*
- * The Spreadtrum mailbox uses an inbox to send messages to the target
- * core, and uses an outbox to receive messages from other cores.
+ * Unisoc mailbox uses an inbox to send messages to the target
+ * core, and uses (an) outbox(es) to receive messages from other
+ * cores.
*
- * Thus the mailbox controller supplies 2 different register addresses
- * and IRQ numbers for inbox and outbox.
+ * Thus in general the mailbox controller supplies 2 different
+ * register addresses and IRQ numbers for inbox and outbox.
+ *
+ * If necessary, a supplementary inbox could be enabled optionally
+ * with an independent FIFO and an extra interrupt.
*/
priv->inbox_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->inbox_base))
@@ -298,7 +347,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)
return ret;
}
- inbox_irq = platform_get_irq(pdev, 0);
+ inbox_irq = platform_get_irq_byname(pdev, "inbox");
if (inbox_irq < 0)
return inbox_irq;
@@ -309,7 +358,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)
return ret;
}
- outbox_irq = platform_get_irq(pdev, 1);
+ outbox_irq = platform_get_irq_byname(pdev, "outbox");
if (outbox_irq < 0)
return outbox_irq;
@@ -320,6 +369,24 @@ static int sprd_mbox_probe(struct platform_device *pdev)
return ret;
}
+ /* Supplementary outbox IRQ is optional */
+ supp_irq = platform_get_irq_byname(pdev, "supp-outbox");
+ if (supp_irq > 0) {
+ ret = devm_request_irq(dev, supp_irq, sprd_mbox_supp_isr,
+ IRQF_NO_SUSPEND, dev_name(dev), priv);
+ if (ret) {
+ dev_err(dev, "failed to request outbox IRQ: %d\n", ret);
+ return ret;
+ }
+
+ supp = (unsigned long) of_device_get_match_data(dev);
+ if (!supp) {
+ dev_err(dev, "no supplementary outbox specified\n");
+ return -ENODEV;
+ }
+ priv->supp_base = priv->outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp);
+ }
+
/* Get the default outbox FIFO depth */
priv->outbox_fifo_depth =
readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1;
@@ -342,7 +409,9 @@ static int sprd_mbox_probe(struct platform_device *pdev)
}
static const struct of_device_id sprd_mbox_of_match[] = {
- { .compatible = "sprd,sc9860-mailbox", },
+ { .compatible = "sprd,sc9860-mailbox" },
+ { .compatible = "sprd,sc9863a-mailbox",
+ .data = (void *)SPRD_SUPP_INBOX_ID_SC9863A },
{ },
};
MODULE_DEVICE_TABLE(of, sprd_mbox_of_match);
diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c
index 0130628f4d9d..efb43b038596 100644
--- a/drivers/mailbox/ti-msgmgr.c
+++ b/drivers/mailbox/ti-msgmgr.c
@@ -239,7 +239,7 @@ static irqreturn_t ti_msgmgr_queue_rx_interrupt(int irq, void *p)
/*
* I have no idea about the protocol being used to communicate with the
- * remote producer - 0 could be valid data, so I wont make a judgement
+ * remote producer - 0 could be valid data, so I won't make a judgement
* of how many bytes I should be reading. Let the client figure this
* out.. I just read the full message and pass it on..
*/