Commit d8201efe authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mailbox-v5.13' of git://git.linaro.org/landing-teams/working/fujitsu/integration

Pull mailbox updates from Jassi Brar:
 "qcom:
   - enable support for SM8350 and SC7280

  sprd:
   - refcount channel usage
   - specify interrupt names in dt
   - support sc9863a

  arm:
   - drop redundant print

  ti:
   - convert dt-bindings to json schema

  and misc spelling fixes"

* tag 'mailbox-v5.13' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
  dt-bindings: mailbox: qcom-ipcc: Add compatible for SC7280
  dt-bindings: mailbox: ti,secure-proxy: Convert to json schema
  mailbox: arm_mhu_db: Remove redundant dev_err call in mhu_db_probe()
  mailbox: sprd: Add supplementary inbox support
  dt-bindings: mailbox: Add interrupt-names to SPRD mailbox
  mailbox: sprd: Introduce refcnt when clients requests/free channels
  MAINTAINERS: Add DT bindings directory to mailbox
  mailbox: fix various typos in comments
  mailbox: pcc: fix platform_no_drv_owner.cocci warnings
  dt-bindings: mailbox: Add compatible for SM8350 IPCC
parents c969f245 2335f556
......@@ -25,6 +25,8 @@ properties:
items:
- enum:
- qcom,sm8250-ipcc
- qcom,sm8350-ipcc
- qcom,sc7280-ipcc
- const: qcom,ipcc
reg:
......
......@@ -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";
};
...
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>;
[...]
};
# 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>;
};
......@@ -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>
......
......@@ -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
......
......@@ -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)
......
......@@ -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.
......
......@@ -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
*
......
......@@ -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 */
......@@ -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,
},
};
......
......@@ -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;
......
......@@ -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);
......
......@@ -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..
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment