[PATCH] mailbox: avoid timer start from callback

2020-10-16 Thread jassisinghbrar
From: Jassi Brar 

If the txdone is done by polling, it is possible for msg_submit() to start
the timer while txdone_hrtimer() callback is running. If the timer needs
recheduling, it could already be enqueued by the time hrtimer_forward_now()
is called, leading hrtimer to loudly complain.

WARNING: CPU: 3 PID: 74 at kernel/time/hrtimer.c:932 hrtimer_forward+0xc4/0x110
CPU: 3 PID: 74 Comm: kworker/u8:1 Not tainted 
5.9.0-rc2-00236-gd3520067d01c-dirty #5
Hardware name: Libre Computer AML-S805X-AC (DT)
Workqueue: events_freezable_power_ thermal_zone_device_check
pstate: 2085 (nzCv daIf -PAN -UAO BTYPE=--)
pc : hrtimer_forward+0xc4/0x110
lr : txdone_hrtimer+0xf8/0x118
[...]

This can be fixed by not starting the timer from the callback path. Which
requires the timer reloading as long as any message is queued on the
channel, and not just when current tx is not done yet.

Signed-off-by: Jassi Brar 
---
 drivers/mailbox/mailbox.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 0b821a5b2db8..a093a6ecaa66 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -82,9 +82,12 @@ static void msg_submit(struct mbox_chan *chan)
 exit:
spin_unlock_irqrestore(>lock, flags);
 
-   if (!err && (chan->txdone_method & TXDONE_BY_POLL))
-   /* kick start the timer immediately to avoid delays */
-   hrtimer_start(>mbox->poll_hrt, 0, HRTIMER_MODE_REL);
+   /* kick start the timer immediately to avoid delays */
+   if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
+   /* but only if not already active */
+   if (!hrtimer_active(>mbox->poll_hrt))
+   hrtimer_start(>mbox->poll_hrt, 0, 
HRTIMER_MODE_REL);
+   }
 }
 
 static void tx_tick(struct mbox_chan *chan, int r)
@@ -122,11 +125,10 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer 
*hrtimer)
struct mbox_chan *chan = >chans[i];
 
if (chan->active_req && chan->cl) {
+   resched = true;
txdone = chan->mbox->ops->last_tx_done(chan);
if (txdone)
tx_tick(chan, 0);
-   else
-   resched = true;
}
}
 
-- 
2.25.1



[PATCH] firmware: arm_scmi: fix timeout value for send_message

2020-06-07 Thread jassisinghbrar
From: Jassi Brar 

Currently scmi_do_xfer() submits a message to mailbox api and waits
for an apparently very short time. This works if there are not many
messages in the queue already. However, if many clients share a
channel and/or each client submits many messages in a row, the
timeout value becomes too short and returns error even if the mailbox
is working fine according to the load. The timeout occurs when the
message is still in the api/queue awaiting its turn to ride the bus.

 Fix this by increasing the timeout value enough (500ms?) so that it
fails only if there is an actual problem in the transmission (like a
lockup or crash).

  [If we want to capture a situation when the remote didn't
respond within expected latency, then the timeout should not
start here, but from tx_prepare callback ... just before the
message physically gets on the channel]

Signed-off-by: Jassi Brar 
---
 drivers/firmware/arm_scmi/driver.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c 
b/drivers/firmware/arm_scmi/driver.c
index dbec767222e9..46ddafe7ffc0 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -303,7 +303,7 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct 
scmi_xfer *xfer)
}
 
if (xfer->hdr.poll_completion) {
-   ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
+   ktime_t stop = ktime_add_ns(ktime_get(), 500 * 1000 * 
NSEC_PER_USEC);
 
spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
 
@@ -313,7 +313,7 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct 
scmi_xfer *xfer)
ret = -ETIMEDOUT;
} else {
/* And we wait for the response. */
-   timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
+   timeout = msecs_to_jiffies(500);
if (!wait_for_completion_timeout(>done, timeout)) {
dev_err(dev, "timed out in resp(caller: %pS)\n",
(void *)_RET_IP_);
-- 
2.25.1



[PATCH v4 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-hdmac.c | 581 +++
 3 files changed, 592 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 7af874b69ffb..d312ebbafbee 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -342,6 +342,16 @@ config MCF_EDMA
  minimal intervention from a host processor.
  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+   tristate "Milbeaut AHB DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ HDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index f5ce8665e944..5f0df3611414 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index ..2bb33535ab9e
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR0x0 /* global */
+#define MLB_HDMAC_DE   BIT(31)
+#define MLB_HDMAC_DS   BIT(30)
+#define MLB_HDMAC_PR   BIT(28)
+#define MLB_HDMAC_DH   GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE0x10
+
+#define MLB_HDMAC_DMACA0x0 /* channel */
+#define MLB_HDMAC_EB   BIT(31)
+#define MLB_HDMAC_PB   BIT(30)
+#define MLB_HDMAC_ST   BIT(29)
+#define MLB_HDMAC_IS   GENMASK(28, 24)
+#define MLB_HDMAC_BT   GENMASK(23, 20)
+#define MLB_HDMAC_BC   GENMASK(19, 16)
+#define MLB_HDMAC_TC   GENMASK(15, 0)
+#define MLB_HDMAC_DMACB0x4
+#define MLB_HDMAC_TT   GENMASK(31, 30)
+#define MLB_HDMAC_MS   GENMASK(29, 28)
+#define MLB_HDMAC_TW   GENMASK(27, 26)
+#define MLB_HDMAC_FS   BIT(25)
+#define MLB_HDMAC_FD   BIT(24)
+#define MLB_HDMAC_RC   BIT(23)
+#define MLB_HDMAC_RS   BIT(22)
+#define MLB_HDMAC_RD   BIT(21)
+#define MLB_HDMAC_EI   BIT(20)
+#define MLB_HDMAC_CI   BIT(19)
+#define HDMAC_PAUSE0x7
+#define MLB_HDMAC_SS   GENMASK(18, 16)
+#define MLB_HDMAC_SP   GENMASK(15, 12)
+#define MLB_HDMAC_DP   GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA   0x8
+#define MLB_HDMAC_DMACDA   0xc
+
+#define MLB_HDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+   BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+   BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+   struct virt_dma_desc vd;
+   struct scatterlist *sgl;
+   unsigned int sg_len;
+   unsigned int sg_cur;
+   enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_hdmac_device *mdev;
+   struct milbeaut_hdmac_desc *md;
+   void __iomem *reg_ch_base;
+   unsigned int slave_id;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_hdmac_device {
+   struct dma_device ddev;
+   struct clk *clk;
+   void __iomem *reg_base;
+   struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   

[PATCH v4 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Reviewed-by: Rob Herring 
Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt  | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index ..1f0875bd5abc
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,32 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability below.
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:   Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:  Should contain DMA registers location and length.
+- interrupts:   Should contain all of the per-channel DMA interrupts.
+ Number of channels is configurable - 2, 4 or 8, so
+ the number of interrupts specified should be {2,4,8}.
+- #dma-cells:   Should be 1. Specify the ID of the slave.
+- clocks:   Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+   hdmac1: dma-controller@1e11 {
+   compatible = "socionext,milbeaut-m10v-hdmac";
+   reg = <0x1e11 0x1>;
+   interrupts = <0 132 4>,
+<0 133 4>,
+<0 134 4>,
+<0 135 4>,
+<0 136 4>,
+<0 137 4>,
+<0 138 4>,
+<0 139 4>;
+   #dma-cells = <1>;
+   clocks = <_clk>;
+   };
-- 
2.20.1



[PATCH v4 0/2] Add support for AHB DMA controller on Milbeaut series

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AHB DMA (HDMAC) controller support on Milbeaut series.
This controller is capable of Mem<->MEM and DEV<->MEM transfer. But only 
DEV<->MEM
is currently supported.

Changes since v3:
 # Drop unused variables
 # Add controller init instruction

Changes since v2:
 # Spelling mistake fix
 # Bug fix prep_slave - made local copy of sgl

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC
bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt  |  32 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-hdmac.c  | 581 ++
 4 files changed, 624 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.20.1



[PATCH v3 2/2] dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut XDMAC controller. The controller only
supports Mem-To-Mem transfers over upto 8 configurable channels.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-xdmac.c | 418 +++
 3 files changed, 429 insertions(+)
 create mode 100644 drivers/dma/milbeaut-xdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d312ebbafbee..a34cd5a72a7b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -352,6 +352,16 @@ config MILBEAUT_HDMAC
  Say yes here to support the Socionext Milbeaut
  HDMAC device.
 
+config MILBEAUT_XDMAC
+   tristate "Milbeaut AXI DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ XDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 5f0df3611414..e3a8fdf80c76 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
 obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
+obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-xdmac.c b/drivers/dma/milbeaut-xdmac.c
new file mode 100644
index ..3d5b1926a58d
--- /dev/null
+++ b/drivers/dma/milbeaut-xdmac.c
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+/* global register */
+#define M10V_XDACS 0x00
+
+/* channel local register */
+#define M10V_XDTBC 0x10
+#define M10V_XDSSA 0x14
+#define M10V_XDDSA 0x18
+#define M10V_XDSAC 0x1C
+#define M10V_XDDAC 0x20
+#define M10V_XDDCC 0x24
+#define M10V_XDDES 0x28
+#define M10V_XDDPC 0x2C
+#define M10V_XDDSD 0x30
+
+#define M10V_XDACS_XE BIT(28)
+
+#define M10V_DEFBS 0x3
+#define M10V_DEFBL 0xf
+
+#define M10V_XDSAC_SBS GENMASK(17, 16)
+#define M10V_XDSAC_SBL GENMASK(11, 8)
+
+#define M10V_XDDAC_DBS GENMASK(17, 16)
+#define M10V_XDDAC_DBL GENMASK(11, 8)
+
+#define M10V_XDDES_CE  BIT(28)
+#define M10V_XDDES_SE  BIT(24)
+#define M10V_XDDES_SA  BIT(15)
+#define M10V_XDDES_TF  GENMASK(23, 20)
+#define M10V_XDDES_EI  BIT(1)
+#define M10V_XDDES_TI  BIT(0)
+
+#define M10V_XDDSD_IS_MASK GENMASK(3, 0)
+#define M10V_XDDSD_IS_NORMAL   0x8
+
+#define MLB_XDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
+
+struct milbeaut_xdmac_desc {
+   struct virt_dma_desc vd;
+   size_t len;
+   dma_addr_t src;
+   dma_addr_t dst;
+};
+
+struct milbeaut_xdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_xdmac_desc *md;
+   void __iomem *reg_ch_base;
+};
+
+struct milbeaut_xdmac_device {
+   struct dma_device ddev;
+   void __iomem *reg_base;
+   struct milbeaut_xdmac_chan channels[0];
+};
+
+static struct milbeaut_xdmac_chan *
+to_milbeaut_xdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_xdmac_chan, vc);
+}
+
+static struct milbeaut_xdmac_desc *
+to_milbeaut_xdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_xdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_xdmac_desc *
+milbeaut_xdmac_next_desc(struct milbeaut_xdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   list_del(>node);
+
+   mc->md = to_milbeaut_xdmac_desc(vd);
+
+   return mc->md;
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_chan_start(struct milbeaut_xdmac_chan *mc,
+   struct milbeaut_xdmac_desc *md)
+{
+   u32 val;
+
+   /* Setup the channel */
+   val = md->len - 1;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDTBC);
+
+   val = md->src;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDSSA);
+
+   val = md->dst;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDDSA);
+
+   val = readl_relaxed(mc->reg_ch_base + M10V_XDSAC);
+   val &= ~(M10V_XDSAC_SBS | M10V_XDSAC_SBL);
+   val |= FIELD_PREP(M10V_XDSAC_SBS, 

[PATCH v3 1/2] dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC bindings

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut XDMAC
controller. Controller only supports Mem->Mem transfers. Number
of physical channels are determined by the number of irqs registered.

Reviewed-by: Rob Herring 
Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-xdmac.txt  | 24 +++
 1 file changed, 24 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
new file mode 100644
index ..305791804062
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
@@ -0,0 +1,24 @@
+* Milbeaut AXI DMA Controller
+
+Milbeaut AXI DMA controller has only memory to memory transfer capability.
+
+* DMA controller
+
+Required property:
+- compatible:  Should be  "socionext,milbeaut-m10v-xdmac"
+- reg: Should contain DMA registers location and length.
+- interrupts:  Should contain all of the per-channel DMA interrupts.
+Number of channels is configurable - 2, 4 or 8, so
+the number of interrupts specified should be {2,4,8}.
+- #dma-cells:  Should be 1.
+
+Example:
+   xdmac0: dma-controller@1c25 {
+   compatible = "socionext,milbeaut-m10v-xdmac";
+   reg = <0x1c25 0x1000>;
+   interrupts = <0 17 0x4>,
+<0 18 0x4>,
+<0 19 0x4>,
+<0 20 0x4>;
+   #dma-cells = <1>;
+   };
-- 
2.20.1



[PATCH v3 0/2] Add support for AXI DMA controller on Milbeaut series

2019-10-14 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AXI DMA (XDMAC) controller support on Milbeaut series.
This controller is capable of only Mem<->MEM transfers. Number of channels is
configurable {2,4,8}

Changes Since v2:
 # Drop unused variable

Changes Since v1:
  # Spelling mistake fix

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC
bindings
  dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-xdmac.txt  |  24 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-xdmac.c  | 418 ++
 4 files changed, 453 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
 create mode 100644 drivers/dma/milbeaut-xdmac.c

-- 
2.20.1



[PATCH v3 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Reviewed-by: Rob Herring 
Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt  | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index ..1f0875bd5abc
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,32 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability below.
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:   Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:  Should contain DMA registers location and length.
+- interrupts:   Should contain all of the per-channel DMA interrupts.
+ Number of channels is configurable - 2, 4 or 8, so
+ the number of interrupts specified should be {2,4,8}.
+- #dma-cells:   Should be 1. Specify the ID of the slave.
+- clocks:   Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+   hdmac1: dma-controller@1e11 {
+   compatible = "socionext,milbeaut-m10v-hdmac";
+   reg = <0x1e11 0x1>;
+   interrupts = <0 132 4>,
+<0 133 4>,
+<0 134 4>,
+<0 135 4>,
+<0 136 4>,
+<0 137 4>,
+<0 138 4>,
+<0 139 4>;
+   #dma-cells = <1>;
+   clocks = <_clk>;
+   };
-- 
2.17.1



[PATCH v3 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-hdmac.c | 583 +++
 3 files changed, 594 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 03fa0c58cef3..66979f27f0f3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -348,6 +348,16 @@ config MCF_EDMA
  minimal intervention from a host processor.
  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+   tristate "Milbeaut AHB DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ HDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 5bddf6f8790f..e4aed0730dea 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index ..600ffd0cfa26
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR0x0 /* global */
+#define MLB_HDMAC_DE   BIT(31)
+#define MLB_HDMAC_DS   BIT(30)
+#define MLB_HDMAC_PR   BIT(28)
+#define MLB_HDMAC_DH   GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE0x10
+
+#define MLB_HDMAC_DMACA0x0 /* channel */
+#define MLB_HDMAC_EB   BIT(31)
+#define MLB_HDMAC_PB   BIT(30)
+#define MLB_HDMAC_ST   BIT(29)
+#define MLB_HDMAC_IS   GENMASK(28, 24)
+#define MLB_HDMAC_BT   GENMASK(23, 20)
+#define MLB_HDMAC_BC   GENMASK(19, 16)
+#define MLB_HDMAC_TC   GENMASK(15, 0)
+#define MLB_HDMAC_DMACB0x4
+#define MLB_HDMAC_TT   GENMASK(31, 30)
+#define MLB_HDMAC_MS   GENMASK(29, 28)
+#define MLB_HDMAC_TW   GENMASK(27, 26)
+#define MLB_HDMAC_FS   BIT(25)
+#define MLB_HDMAC_FD   BIT(24)
+#define MLB_HDMAC_RC   BIT(23)
+#define MLB_HDMAC_RS   BIT(22)
+#define MLB_HDMAC_RD   BIT(21)
+#define MLB_HDMAC_EI   BIT(20)
+#define MLB_HDMAC_CI   BIT(19)
+#define HDMAC_PAUSE0x7
+#define MLB_HDMAC_SS   GENMASK(18, 16)
+#define MLB_HDMAC_SP   GENMASK(15, 12)
+#define MLB_HDMAC_DP   GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA   0x8
+#define MLB_HDMAC_DMACDA   0xc
+
+#define MLB_HDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+   BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+   BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+   struct virt_dma_desc vd;
+   struct scatterlist *sgl;
+   unsigned int sg_len;
+   unsigned int sg_cur;
+   enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_hdmac_device *mdev;
+   struct milbeaut_hdmac_desc *md;
+   void __iomem *reg_ch_base;
+   unsigned int slave_id;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_hdmac_device {
+   struct dma_device ddev;
+   struct clk *clk;
+   void __iomem *reg_base;
+   struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   

[PATCH v2 2/2] dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut XDMAC controller. The controller only
supports Mem-To-Mem transfers over upto 8 configurable channels.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-xdmac.c | 426 +++
 3 files changed, 437 insertions(+)
 create mode 100644 drivers/dma/milbeaut-xdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 66979f27f0f3..e0e3b21a0c4c 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -358,6 +358,16 @@ config MILBEAUT_HDMAC
  Say yes here to support the Socionext Milbeaut
  HDMAC device.
 
+config MILBEAUT_XDMAC
+   tristate "Milbeaut AXI DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ XDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e4aed0730dea..41e06a845b01 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
 obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
+obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-xdmac.c b/drivers/dma/milbeaut-xdmac.c
new file mode 100644
index ..f2e04541d031
--- /dev/null
+++ b/drivers/dma/milbeaut-xdmac.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+/* global register */
+#define M10V_XDACS 0x00
+
+/* channel local register */
+#define M10V_XDTBC 0x10
+#define M10V_XDSSA 0x14
+#define M10V_XDDSA 0x18
+#define M10V_XDSAC 0x1C
+#define M10V_XDDAC 0x20
+#define M10V_XDDCC 0x24
+#define M10V_XDDES 0x28
+#define M10V_XDDPC 0x2C
+#define M10V_XDDSD 0x30
+
+#define M10V_XDACS_XE BIT(28)
+
+#define M10V_DEFBS 0x3
+#define M10V_DEFBL 0xf
+
+#define M10V_XDSAC_SBS GENMASK(17, 16)
+#define M10V_XDSAC_SBL GENMASK(11, 8)
+
+#define M10V_XDDAC_DBS GENMASK(17, 16)
+#define M10V_XDDAC_DBL GENMASK(11, 8)
+
+#define M10V_XDDES_CE  BIT(28)
+#define M10V_XDDES_SE  BIT(24)
+#define M10V_XDDES_SA  BIT(15)
+#define M10V_XDDES_TF  GENMASK(23, 20)
+#define M10V_XDDES_EI  BIT(1)
+#define M10V_XDDES_TI  BIT(0)
+
+#define M10V_XDDSD_IS_MASK GENMASK(3, 0)
+#define M10V_XDDSD_IS_NORMAL   0x8
+
+#define MLB_XDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
+
+struct milbeaut_xdmac_desc {
+   struct virt_dma_desc vd;
+   size_t len;
+   dma_addr_t src;
+   dma_addr_t dst;
+};
+
+struct milbeaut_xdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_xdmac_device *mdev;
+   struct milbeaut_xdmac_desc *md;
+   void __iomem *reg_ch_base;
+   int irq;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_xdmac_device {
+   struct dma_device ddev;
+   void __iomem *reg_base;
+   struct milbeaut_xdmac_chan channels[0];
+};
+
+static struct milbeaut_xdmac_chan *
+to_milbeaut_xdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_xdmac_chan, vc);
+}
+
+static struct milbeaut_xdmac_desc *
+to_milbeaut_xdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_xdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_xdmac_desc *
+milbeaut_xdmac_next_desc(struct milbeaut_xdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   list_del(>node);
+
+   mc->md = to_milbeaut_xdmac_desc(vd);
+
+   return mc->md;
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_chan_start(struct milbeaut_xdmac_chan *mc,
+   struct milbeaut_xdmac_desc *md)
+{
+   u32 val;
+
+   /* Setup the channel */
+   val = md->len - 1;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDTBC);
+
+   val = md->src;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDSSA);
+
+   val = md->dst;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDDSA);
+
+   val = readl_relaxed(mc->reg_ch_base + M10V_XDSAC);
+ 

[PATCH v3 0/2] Add support for AHB DMA controller on Milbeaut series

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AHB DMA (HDMAC) controller support on Milbeaut series.
This controller is capable of Mem<->MEM and DEV<->MEM transfer. But only 
DEV<->MEM
is currently supported.

Changes since v2:
 # Spelling mistake fix
 # Bug fix prep_slave - made local copy of sgl 

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC
bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt  |  32 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-hdmac.c  | 583 ++
 4 files changed, 626 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.17.1



[PATCH v2 1/2] dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC bindings

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut XDMAC
controller. Controller only supports Mem->Mem transfers. Number
of physical channels are determined by the number of irqs registered.

Reviewed-by: Rob Herring 
Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-xdmac.txt  | 24 +++
 1 file changed, 24 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
new file mode 100644
index ..305791804062
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
@@ -0,0 +1,24 @@
+* Milbeaut AXI DMA Controller
+
+Milbeaut AXI DMA controller has only memory to memory transfer capability.
+
+* DMA controller
+
+Required property:
+- compatible:  Should be  "socionext,milbeaut-m10v-xdmac"
+- reg: Should contain DMA registers location and length.
+- interrupts:  Should contain all of the per-channel DMA interrupts.
+Number of channels is configurable - 2, 4 or 8, so
+the number of interrupts specified should be {2,4,8}.
+- #dma-cells:  Should be 1.
+
+Example:
+   xdmac0: dma-controller@1c25 {
+   compatible = "socionext,milbeaut-m10v-xdmac";
+   reg = <0x1c25 0x1000>;
+   interrupts = <0 17 0x4>,
+<0 18 0x4>,
+<0 19 0x4>,
+<0 20 0x4>;
+   #dma-cells = <1>;
+   };
-- 
2.17.1



[PATCH v2 0/2] Add support for AXI DMA controller on Milbeaut series

2019-09-09 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AXI DMA (XDMAC) controller support on Milbeaut series.
This controller is capable of only Mem<->MEM transfers. Number of channels is
configurable {2,4,8}

Changes Since v1:
  # Spelling mistake fix

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC
bindings
  dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-xdmac.txt  |  24 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-xdmac.c  | 426 ++
 4 files changed, 461 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
 create mode 100644 drivers/dma/milbeaut-xdmac.c

-- 
2.17.1



[PATCH 2/2] dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut XDMAC controller. The controller only
supports Mem-To-Mem transfers over upto 8 configurable channels.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-xdmac.c | 426 +++
 3 files changed, 437 insertions(+)
 create mode 100644 drivers/dma/milbeaut-xdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 66979f27f0f3..e0e3b21a0c4c 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -358,6 +358,16 @@ config MILBEAUT_HDMAC
  Say yes here to support the Socionext Milbeaut
  HDMAC device.
 
+config MILBEAUT_XDMAC
+   tristate "Milbeaut AXI DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ XDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e4aed0730dea..41e06a845b01 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
 obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
+obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-xdmac.c b/drivers/dma/milbeaut-xdmac.c
new file mode 100644
index ..f2e04541d031
--- /dev/null
+++ b/drivers/dma/milbeaut-xdmac.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+/* global register */
+#define M10V_XDACS 0x00
+
+/* channel local register */
+#define M10V_XDTBC 0x10
+#define M10V_XDSSA 0x14
+#define M10V_XDDSA 0x18
+#define M10V_XDSAC 0x1C
+#define M10V_XDDAC 0x20
+#define M10V_XDDCC 0x24
+#define M10V_XDDES 0x28
+#define M10V_XDDPC 0x2C
+#define M10V_XDDSD 0x30
+
+#define M10V_XDACS_XE BIT(28)
+
+#define M10V_DEFBS 0x3
+#define M10V_DEFBL 0xf
+
+#define M10V_XDSAC_SBS GENMASK(17, 16)
+#define M10V_XDSAC_SBL GENMASK(11, 8)
+
+#define M10V_XDDAC_DBS GENMASK(17, 16)
+#define M10V_XDDAC_DBL GENMASK(11, 8)
+
+#define M10V_XDDES_CE  BIT(28)
+#define M10V_XDDES_SE  BIT(24)
+#define M10V_XDDES_SA  BIT(15)
+#define M10V_XDDES_TF  GENMASK(23, 20)
+#define M10V_XDDES_EI  BIT(1)
+#define M10V_XDDES_TI  BIT(0)
+
+#define M10V_XDDSD_IS_MASK GENMASK(3, 0)
+#define M10V_XDDSD_IS_NORMAL   0x8
+
+#define MLB_XDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
+BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
+
+struct milbeaut_xdmac_desc {
+   struct virt_dma_desc vd;
+   size_t len;
+   dma_addr_t src;
+   dma_addr_t dst;
+};
+
+struct milbeaut_xdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_xdmac_device *mdev;
+   struct milbeaut_xdmac_desc *md;
+   void __iomem *reg_ch_base;
+   int irq;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_xdmac_device {
+   struct dma_device ddev;
+   void __iomem *reg_base;
+   struct milbeaut_xdmac_chan channels[0];
+};
+
+static struct milbeaut_xdmac_chan *
+to_milbeaut_xdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_xdmac_chan, vc);
+}
+
+static struct milbeaut_xdmac_desc *
+to_milbeaut_xdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_xdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_xdmac_desc *
+milbeaut_xdmac_next_desc(struct milbeaut_xdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   list_del(>node);
+
+   mc->md = to_milbeaut_xdmac_desc(vd);
+
+   return mc->md;
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_chan_start(struct milbeaut_xdmac_chan *mc,
+   struct milbeaut_xdmac_desc *md)
+{
+   u32 val;
+
+   /* Setup the channel */
+   val = md->len - 1;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDTBC);
+
+   val = md->src;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDSSA);
+
+   val = md->dst;
+   writel_relaxed(val, mc->reg_ch_base + M10V_XDDSA);
+
+   val = readl_relaxed(mc->reg_ch_base + M10V_XDSAC);
+ 

[PATCH 1/2] dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC bindings

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut XDMAC
controller. Controller only supports Mem->Mem transfers. Number
of physical channels are determined by the number of irqs registered.

Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-xdmac.txt  | 24 +++
 1 file changed, 24 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
new file mode 100644
index ..1f15512e3f19
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
@@ -0,0 +1,24 @@
+* Milbeaut AXI DMA Controller
+
+Milbeaut AXI DMA controller has only memory to memory transfer capability.
+
+* DMA controller
+
+Required property:
+- compatible:  Should be  "socionext,milbeaut-m10v-xdmac"
+- reg: Should contain DMA registers location and length.
+- interrupts:  Should contain all of the per-channel DMA interrupts.
+Number of channels is configurable - 2, 4 or 8, so
+the number of interrupts specfied should be {2,4,8}.
+- #dma-cells:  Should be 1.
+
+Example:
+   xdmac0: dma-controller@1c25 {
+   compatible = "socionext,milbeaut-m10v-xdmac";
+   reg = <0x1c25 0x1000>;
+   interrupts = <0 17 0x4>,
+<0 18 0x4>,
+<0 19 0x4>,
+<0 20 0x4>;
+   #dma-cells = <1>;
+   };
-- 
2.17.1



[PATCH 0/2] Add support for AXI DMA controller on Milbeaut series

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AXI DMA (XDMAC) controller support on Milbeaut series.
This controller is capable of only Mem<->MEM transfers. Number of channels is
configurable {2,4,8}

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-xdmac: Add Socionext Milbeaut XDMAC
bindings
  dmaengine: milbeaut-xdmac: Add XDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-xdmac.txt  |  24 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-xdmac.c  | 426 ++
 4 files changed, 461 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-xdmac.txt
 create mode 100644 drivers/dma/milbeaut-xdmac.c

-- 
2.17.1



[PATCH v2 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-hdmac.c | 571 +++
 3 files changed, 582 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 03fa0c58cef3..66979f27f0f3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -348,6 +348,16 @@ config MCF_EDMA
  minimal intervention from a host processor.
  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+   tristate "Milbeaut AHB DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ HDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 5bddf6f8790f..e4aed0730dea 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index ..25ba0a692c94
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,571 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR0x0 /* global */
+#define MLB_HDMAC_DE   BIT(31)
+#define MLB_HDMAC_DS   BIT(30)
+#define MLB_HDMAC_PR   BIT(28)
+#define MLB_HDMAC_DH   GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE0x10
+
+#define MLB_HDMAC_DMACA0x0 /* channel */
+#define MLB_HDMAC_EB   BIT(31)
+#define MLB_HDMAC_PB   BIT(30)
+#define MLB_HDMAC_ST   BIT(29)
+#define MLB_HDMAC_IS   GENMASK(28, 24)
+#define MLB_HDMAC_BT   GENMASK(23, 20)
+#define MLB_HDMAC_BC   GENMASK(19, 16)
+#define MLB_HDMAC_TC   GENMASK(15, 0)
+#define MLB_HDMAC_DMACB0x4
+#define MLB_HDMAC_TT   GENMASK(31, 30)
+#define MLB_HDMAC_MS   GENMASK(29, 28)
+#define MLB_HDMAC_TW   GENMASK(27, 26)
+#define MLB_HDMAC_FS   BIT(25)
+#define MLB_HDMAC_FD   BIT(24)
+#define MLB_HDMAC_RC   BIT(23)
+#define MLB_HDMAC_RS   BIT(22)
+#define MLB_HDMAC_RD   BIT(21)
+#define MLB_HDMAC_EI   BIT(20)
+#define MLB_HDMAC_CI   BIT(19)
+#define HDMAC_PAUSE0x7
+#define MLB_HDMAC_SS   GENMASK(18, 16)
+#define MLB_HDMAC_SP   GENMASK(15, 12)
+#define MLB_HDMAC_DP   GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA   0x8
+#define MLB_HDMAC_DMACDA   0xc
+
+#define MLB_HDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+   BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+   BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+   struct virt_dma_desc vd;
+   struct scatterlist *sgl;
+   unsigned int sg_len;
+   unsigned int sg_cur;
+   enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_hdmac_device *mdev;
+   struct milbeaut_hdmac_desc *md;
+   void __iomem *reg_ch_base;
+   unsigned int slave_id;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_hdmac_device {
+   struct dma_device ddev;
+   struct clk *clk;
+   void __iomem *reg_base;
+   struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   

[PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt  | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index ..f0960724f1c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,32 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability bellow.
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:   Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:  Should contain DMA registers location and length.
+- interrupts:   Should contain all of the per-channel DMA interrupts.
+ Number of channels is configurable - 2, 4 or 8, so
+ the number of interrupts specfied should be {2,4,8}.
+- #dma-cells:   Should be 1. Specify the ID of the slave.
+- clocks:   Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+   hdmac1: dma-controller@1e11 {
+   compatible = "socionext,milbeaut-m10v-hdmac";
+   reg = <0x1e11 0x1>;
+   interrupts = <0 132 4>,
+<0 133 4>,
+<0 134 4>,
+<0 135 4>,
+<0 136 4>,
+<0 137 4>,
+<0 138 4>,
+<0 139 4>;
+   #dma-cells = <1>;
+   clocks = <_clk>;
+   };
-- 
2.17.1



[PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series

2019-08-17 Thread jassisinghbrar
From: Jassi Brar 

Changes since v1:
1) Drop uncessary headers from driver
2) Some Cosmetic changes.
3) Define macro for magic numbers
4) Specify constraints on number of channels/irq in DT bindings

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC
bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt  |  32 +
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-hdmac.c  | 571 ++
 4 files changed, 614 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.17.1



[PATCH 0/2] Add support for AHB DMA controller on Milbeaut series

2019-06-13 Thread jassisinghbrar
From: Jassi Brar 

The following series adds AHB DMA (HDMAC) controller support on Milbeaut series.
This controller is capable of Mem<->MEM and DEV<->MEM transfer. But only 
DEV<->MEM
is currently supported.

Jassi Brar (2):
  dt-bindings: milbeaut-hdmac: Add Socionext Milbeaut HDMAC bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt   |  54 ++
 drivers/dma/Kconfig   |  10 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/milbeaut-hdmac.c  | 572 ++
 4 files changed, 637 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.17.1



[PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

2019-06-13 Thread jassisinghbrar
From: Jassi Brar 

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar 
---
 drivers/dma/Kconfig  |  10 +
 drivers/dma/Makefile |   1 +
 drivers/dma/milbeaut-hdmac.c | 572 +++
 3 files changed, 583 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 703275cc29de..15a1d5263ca1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -347,6 +347,16 @@ config MCF_EDMA
  minimal intervention from a host processor.
  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+   tristate "Milbeaut AHB DMA support"
+   depends on ARCH_MILBEAUT || COMPILE_TEST
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Say yes here to support the Socionext Milbeaut
+ HDMAC device.
+
 config MMP_PDMA
bool "MMP PDMA support"
depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6126e1c3a875..d0a9f46726e8 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index ..9c9fabdf8cdc
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR0x0 /* global */
+#define MLB_HDMAC_DE   BIT(31)
+#define MLB_HDMAC_DS   BIT(30)
+#define MLB_HDMAC_PR   BIT(28)
+#define MLB_HDMAC_DH   GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE0x10
+
+#define MLB_HDMAC_DMACA0x0 /* channel */
+#define MLB_HDMAC_EB   BIT(31)
+#define MLB_HDMAC_PB   BIT(30)
+#define MLB_HDMAC_ST   BIT(29)
+#define MLB_HDMAC_IS   GENMASK(28, 24)
+#define MLB_HDMAC_BT   GENMASK(23, 20)
+#define MLB_HDMAC_BC   GENMASK(19, 16)
+#define MLB_HDMAC_TC   GENMASK(15, 0)
+#define MLB_HDMAC_DMACB0x4
+#define MLB_HDMAC_TT   GENMASK(31, 30)
+#define MLB_HDMAC_MS   GENMASK(29, 28)
+#define MLB_HDMAC_TW   GENMASK(27, 26)
+#define MLB_HDMAC_FS   BIT(25)
+#define MLB_HDMAC_FD   BIT(24)
+#define MLB_HDMAC_RC   BIT(23)
+#define MLB_HDMAC_RS   BIT(22)
+#define MLB_HDMAC_RD   BIT(21)
+#define MLB_HDMAC_EI   BIT(20)
+#define MLB_HDMAC_CI   BIT(19)
+#define MLB_HDMAC_SS   GENMASK(18, 16)
+#define MLB_HDMAC_SP   GENMASK(15, 12)
+#define MLB_HDMAC_DP   GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA   0x8
+#define MLB_HDMAC_DMACDA   0xc
+
+#define MLB_HDMAC_BUSWIDTHS(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+   BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+   BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+   struct virt_dma_desc vd;
+   struct scatterlist *sgl;
+   unsigned int sg_len;
+   unsigned int sg_cur;
+   enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+   struct virt_dma_chan vc;
+   struct milbeaut_hdmac_device *mdev;
+   struct milbeaut_hdmac_desc *md;
+   void __iomem *reg_ch_base;
+   unsigned int slave_id;
+   struct dma_slave_config cfg;
+};
+
+struct milbeaut_hdmac_device {
+   struct dma_device ddev;
+   struct clk *clk;
+   void __iomem *reg_base;
+   struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+   return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+   return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+   struct virt_dma_desc *vd;
+
+   vd = vchan_next_desc(>vc);
+   if (!vd) {
+   mc->md = NULL;
+   return NULL;
+   }
+
+   list_del(>node);
+
+   

[PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings

2019-06-13 Thread jassisinghbrar
From: Jassi Brar 

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Signed-off-by: Jassi Brar 
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt   | 54 +++
 1 file changed, 54 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt 
b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index ..a104fcb9e73d
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,51 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability bellow.
+ - memory to memory transfer
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:   Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:  Should contain DMA registers location and length.
+- interrupts:   Should contain all of the per-channel DMA interrupts.
+- #dma-cells:   Should be 1. Specify the ID of the slave.
+- clocks:   Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+   hdmac1: hdmac@1e11 {
+   compatible = "socionext,milbeaut-m10v-hdmac";
+   reg = <0x1e11 0x1>;
+   interrupts = <0 132 4>,
+<0 133 4>,
+<0 134 4>,
+<0 135 4>,
+<0 136 4>,
+<0 137 4>,
+<0 138 4>,
+<0 139 4>;
+   #dma-cells = <1>;
+   clocks = <_clk>;
+   };
+
+* DMA client
+
+Clients have to specify the DMA requests with phandles in a list.
+
+Required properties:
+- dmas: List of one or more DMA request specifiers. One DMA 
request specifier
+consists of a phandle to the DMA controller followed by 
the integer
+specifying the request line.
+- dma-names:List of string identifiers for the DMA requests. For the 
correct
+names, have a look at the specific client driver.
+
+Example:
+
+   sni_spi1: spi@1e800100 {
+   ...
+   dmas = < 22>, < 21>;
+   dma-names = "tx", "rx";
+   ...
+   };
-- 
2.17.1



[RFC 2/3] mailbox: Introduce a new common API

2013-04-27 Thread jassisinghbrar
From: Jassi Brar 

Introduce common framework for client/protocol drivers and
controller drivers of Inter-Processor-Communication (IPC).

Client driver developers should have a look at
 include/linux/mailbox_client.h to understand the part of
the API exposed to client drivers.
Similarly controller driver developers should have a look
at include/linux/mailbox_controller.h

Signed-off-by: Jassi Brar 
---
 drivers/mailbox/Makefile   |4 +
 drivers/mailbox/mailbox.c  |  470 
 include/linux/mailbox.h|   20 ++
 include/linux/mailbox_client.h |   88 +++
 include/linux/mailbox_controller.h |  105 
 5 files changed, 687 insertions(+)
 create mode 100644 drivers/mailbox/mailbox.c
 create mode 100644 include/linux/mailbox.h
 create mode 100644 include/linux/mailbox_client.h
 create mode 100644 include/linux/mailbox_controller.h

diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 543ad6a..fefef7e 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -1 +1,5 @@
+# Generic MAILBOX API
+
+obj-$(CONFIG_MAILBOX)  += mailbox.o
+
 obj-$(CONFIG_PL320_MBOX)   += pl320-ipc.o
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
new file mode 100644
index 000..c5ec93e
--- /dev/null
+++ b/drivers/mailbox/mailbox.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2013 Linaro Ltd
+ * Author: Jaswinder Singh 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * The length of circular buffer for queuing messages from a client.
+ * 'msg_count' tracks the number of buffered messages while 'msg_free'
+ * is the index where the next message would be buffered.
+ * We shouldn't need it too big because every transferr is interrupt
+ * triggered and if we have lots of data to transfer, the interrupt
+ * latencies are going to be the bottleneck, not the buffer length.
+ * Besides, ipc_send_message could be called from atomic context and
+ * the client could also queue another message from the notifier 'txcb'
+ * of the last transfer done.
+ */
+#define MBOX_TX_QUEUE_LEN  10
+
+#define TXDONE_BY_IRQ  (1 << 0) /* controller has remote RTR irq */
+#define TXDONE_BY_POLL (1 << 1) /* controller can read status of last 
TX */
+#define TXDONE_BY_ACK  (1 << 2) /* S/W ACK recevied by Client ticks the TX */
+
+struct ipc_chan {
+   char chan_name[32]; /* controller_name:link_name */
+   unsigned txdone_method;
+
+   /* Cached values from controller */
+   struct ipc_link *link;
+   struct ipc_link_ops *link_ops;
+
+   /* Cached values from client */
+   void (*rxcb)(void *data);
+   void (*txcb)(request_token_t t, enum xfer_result r);
+   bool tx_block;
+   unsigned long tx_tout;
+   struct completion tx_complete;
+
+   request_token_t active_token;
+   unsigned msg_count, msg_free;
+   void *msg_data[MBOX_TX_QUEUE_LEN];
+   /* Timer shared by all links of a controller */
+   struct tx_poll_timer *timer;
+   bool assigned;
+   /* Serialize access to the channel */
+   spinlock_t lock;
+   /* Hook to add to the global list of channels */
+   struct list_head node;
+   /* Notifier to all clients waiting on aquiring this channel */
+   struct blocking_notifier_head avail;
+};
+
+/*
+ * If the controller supports only TXDONE_BY_POLL, this
+ * timer polls all the links for txdone.
+ */
+struct tx_poll_timer {
+   struct timer_list poll;
+   unsigned period;
+};
+
+static struct list_head ipc_channels;
+static DEFINE_MUTEX(chpool_mutex);
+
+static request_token_t _add_to_rbuf(struct ipc_chan *chan, void *data)
+{
+   request_token_t idx;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+
+   /* See if there is any space left */
+   if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
+   spin_unlock_irqrestore(>lock, flags);
+   return 0;
+   }
+
+   idx = chan->msg_free;
+   chan->msg_data[idx] = data;
+   chan->msg_count++;
+
+   if (idx == MBOX_TX_QUEUE_LEN - 1)
+   chan->msg_free = 0;
+   else
+   chan->msg_free++;
+
+   spin_unlock_irqrestore(>lock, flags);
+
+   return idx + 1;
+}
+
+static void _msg_submit(struct ipc_chan *chan)
+{
+   struct ipc_link *link = chan->link;
+   unsigned count, idx;
+   unsigned long flags;
+   void *data;
+   int err;
+
+   spin_lock_irqsave(>lock, flags);
+
+   if (!chan->msg_count || chan->active_token) {
+   spin_unlock_irqrestore(>lock, flags);
+   return;
+   }
+
+   count = chan->msg_count;
+   idx = chan->msg_free;
+   if (idx >= count)
+ 

[RFC 3/3] mailbox: pl320: Introduce common API driver

2013-04-27 Thread jassisinghbrar
From: Jassi Brar 

Convert the PL320 controller driver to work with the common
mailbox API. Also convert the only user of PL320, highbank-cpufreq.c
to work with thee API. Drop the obsoleted driver pl320-ipc.c

Signed-off-by: Jassi Brar 
---
 drivers/cpufreq/highbank-cpufreq.c   |   22 +++-
 drivers/mailbox/Makefile |2 +-
 drivers/mailbox/{pl320-ipc.c => pl320.c} |  194 --
 include/linux/pl320-ipc.h|   17 ---
 4 files changed, 125 insertions(+), 110 deletions(-)
 rename drivers/mailbox/{pl320-ipc.c => pl320.c} (51%)
 delete mode 100644 include/linux/pl320-ipc.h

diff --git a/drivers/cpufreq/highbank-cpufreq.c 
b/drivers/cpufreq/highbank-cpufreq.c
index 3118b87..5c057e0 100644
--- a/drivers/cpufreq/highbank-cpufreq.c
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -19,7 +19,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #define HB_CPUFREQ_CHANGE_NOTE 0x8001
@@ -29,8 +29,26 @@
 static int hb_voltage_change(unsigned int freq)
 {
u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 100};
+   struct ipc_client cl;
+   int ret = -ETIMEDOUT;
+   void *chan;
 
-   return pl320_ipc_transmit(msg);
+   cl.rxcb = NULL;
+   cl.txcb = NULL;
+   cl.tx_block = true;
+   cl.tx_tout = 1000; /* 1 sec */
+   cl.cntlr_data = NULL;
+   cl.knows_txdone = false;
+   cl.chan_name = "pl320:A9_to_M3";
+
+   chan = ipc_request_channel();
+
+   if (ipc_send_message(chan, (void *)msg))
+   ret = msg[1]; /* PL320 updates buffer with FIFO after ACK */
+
+   ipc_free_channel(chan);
+
+   return ret;
 }
 
 static int hb_cpufreq_clk_notify(struct notifier_block *nb,
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index fefef7e..7b897f3 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,4 +2,4 @@
 
 obj-$(CONFIG_MAILBOX)  += mailbox.o
 
-obj-$(CONFIG_PL320_MBOX)   += pl320-ipc.o
+obj-$(CONFIG_PL320_MBOX)   += pl320.o
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320.c
similarity index 51%
rename from drivers/mailbox/pl320-ipc.c
rename to drivers/mailbox/pl320.c
index f3755e0..98b40f4 100644
--- a/drivers/mailbox/pl320-ipc.c
+++ b/drivers/mailbox/pl320.c
@@ -25,8 +25,9 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
+#include 
+#include 
 
 #define IPCMxSOURCE(m) ((m) * 0x40)
 #define IPCMxDSET(m)   (((m) * 0x40) + 0x004)
@@ -44,114 +45,86 @@
 
 #define MBOX_MASK(n)   (1 << (n))
 #define IPC_TX_MBOX1
-#define IPC_RX_MBOX2
 
 #define CHAN_MASK(n)   (1 << (n))
 #define A9_SOURCE  1
 #define M3_SOURCE  0
 
-static void __iomem *ipc_base;
-static int ipc_irq;
-static DEFINE_MUTEX(ipc_m1_lock);
-static DECLARE_COMPLETION(ipc_completion);
-static ATOMIC_NOTIFIER_HEAD(ipc_notifier);
+struct pl320_con {
+   u32 *data;
+   int ipc_irq;
+   struct device *dev;
+   struct ipc_link link;
+   void __iomem *ipc_base;
+   struct ipc_controller ipc_con;
+};
 
-static inline void set_destination(int source, int mbox)
+static inline struct pl320_con *to_pl320(struct ipc_link *l)
 {
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox));
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox));
-}
+   if (!l)
+   return NULL;
 
-static inline void clear_destination(int source, int mbox)
-{
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox));
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox));
+   return container_of(l, struct pl320_con, link);
 }
 
-static void __ipc_send(int mbox, u32 *data)
+static irqreturn_t ipc_handler(int irq, void *p)
 {
-   int i;
-   for (i = 0; i < 7; i++)
-   __raw_writel(data[i], ipc_base + IPCMxDR(mbox, i));
-   __raw_writel(0x1, ipc_base + IPCMxSEND(mbox));
-}
+   struct ipc_link *link = (struct ipc_link *)p;
+   struct pl320_con *pl320 = to_pl320(link);
+   void __iomem *ipc_base = pl320->ipc_base;
+   u32 irq_stat;
 
-static u32 __ipc_rcv(int mbox, u32 *data)
-{
-   int i;
-   for (i = 0; i < 7; i++)
-   data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i));
-   return data[1];
-}
+   irq_stat = __raw_readl(ipc_base + IPCMMIS(1));
+   if (irq_stat & MBOX_MASK(IPC_TX_MBOX)) {
+   u32 *data = pl320->data;
+   int i;
 
-/* blocking implmentation from the A9 side, not usuable in interrupts! */
-int pl320_ipc_transmit(u32 *data)
-{
-   int ret;
+   __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+
+   /*
+* The PL320 driver specifies that the send buffer
+* will be overwritten by same fifo upon TX ACK.
+*/
+   for (i = 0; i < 7; i++)
+   data[i] = __raw_readl(ipc_base
+

[RFC 2/3] mailbox: Introduce a new common API

2013-04-27 Thread jassisinghbrar
From: Jassi Brar jaswinder.si...@linaro.org

Introduce common framework for client/protocol drivers and
controller drivers of Inter-Processor-Communication (IPC).

Client driver developers should have a look at
 include/linux/mailbox_client.h to understand the part of
the API exposed to client drivers.
Similarly controller driver developers should have a look
at include/linux/mailbox_controller.h

Signed-off-by: Jassi Brar jaswinder.si...@linaro.org
---
 drivers/mailbox/Makefile   |4 +
 drivers/mailbox/mailbox.c  |  470 
 include/linux/mailbox.h|   20 ++
 include/linux/mailbox_client.h |   88 +++
 include/linux/mailbox_controller.h |  105 
 5 files changed, 687 insertions(+)
 create mode 100644 drivers/mailbox/mailbox.c
 create mode 100644 include/linux/mailbox.h
 create mode 100644 include/linux/mailbox_client.h
 create mode 100644 include/linux/mailbox_controller.h

diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 543ad6a..fefef7e 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -1 +1,5 @@
+# Generic MAILBOX API
+
+obj-$(CONFIG_MAILBOX)  += mailbox.o
+
 obj-$(CONFIG_PL320_MBOX)   += pl320-ipc.o
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
new file mode 100644
index 000..c5ec93e
--- /dev/null
+++ b/drivers/mailbox/mailbox.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2013 Linaro Ltd
+ * Author: Jaswinder Singh jassisinghb...@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/interrupt.h
+#include linux/spinlock.h
+#include linux/mutex.h
+#include linux/delay.h
+#include linux/slab.h
+#include linux/err.h
+#include linux/module.h
+#include linux/mailbox_client.h
+#include linux/mailbox_controller.h
+
+/*
+ * The length of circular buffer for queuing messages from a client.
+ * 'msg_count' tracks the number of buffered messages while 'msg_free'
+ * is the index where the next message would be buffered.
+ * We shouldn't need it too big because every transferr is interrupt
+ * triggered and if we have lots of data to transfer, the interrupt
+ * latencies are going to be the bottleneck, not the buffer length.
+ * Besides, ipc_send_message could be called from atomic context and
+ * the client could also queue another message from the notifier 'txcb'
+ * of the last transfer done.
+ */
+#define MBOX_TX_QUEUE_LEN  10
+
+#define TXDONE_BY_IRQ  (1  0) /* controller has remote RTR irq */
+#define TXDONE_BY_POLL (1  1) /* controller can read status of last 
TX */
+#define TXDONE_BY_ACK  (1  2) /* S/W ACK recevied by Client ticks the TX */
+
+struct ipc_chan {
+   char chan_name[32]; /* controller_name:link_name */
+   unsigned txdone_method;
+
+   /* Cached values from controller */
+   struct ipc_link *link;
+   struct ipc_link_ops *link_ops;
+
+   /* Cached values from client */
+   void (*rxcb)(void *data);
+   void (*txcb)(request_token_t t, enum xfer_result r);
+   bool tx_block;
+   unsigned long tx_tout;
+   struct completion tx_complete;
+
+   request_token_t active_token;
+   unsigned msg_count, msg_free;
+   void *msg_data[MBOX_TX_QUEUE_LEN];
+   /* Timer shared by all links of a controller */
+   struct tx_poll_timer *timer;
+   bool assigned;
+   /* Serialize access to the channel */
+   spinlock_t lock;
+   /* Hook to add to the global list of channels */
+   struct list_head node;
+   /* Notifier to all clients waiting on aquiring this channel */
+   struct blocking_notifier_head avail;
+};
+
+/*
+ * If the controller supports only TXDONE_BY_POLL, this
+ * timer polls all the links for txdone.
+ */
+struct tx_poll_timer {
+   struct timer_list poll;
+   unsigned period;
+};
+
+static struct list_head ipc_channels;
+static DEFINE_MUTEX(chpool_mutex);
+
+static request_token_t _add_to_rbuf(struct ipc_chan *chan, void *data)
+{
+   request_token_t idx;
+   unsigned long flags;
+
+   spin_lock_irqsave(chan-lock, flags);
+
+   /* See if there is any space left */
+   if (chan-msg_count == MBOX_TX_QUEUE_LEN) {
+   spin_unlock_irqrestore(chan-lock, flags);
+   return 0;
+   }
+
+   idx = chan-msg_free;
+   chan-msg_data[idx] = data;
+   chan-msg_count++;
+
+   if (idx == MBOX_TX_QUEUE_LEN - 1)
+   chan-msg_free = 0;
+   else
+   chan-msg_free++;
+
+   spin_unlock_irqrestore(chan-lock, flags);
+
+   return idx + 1;
+}
+
+static void _msg_submit(struct ipc_chan *chan)
+{
+   struct ipc_link *link = chan-link;
+   unsigned count, idx;
+   unsigned long flags;
+   void *data;
+   int err;
+
+   spin_lock_irqsave(chan-lock, flags);
+
+   if 

[RFC 3/3] mailbox: pl320: Introduce common API driver

2013-04-27 Thread jassisinghbrar
From: Jassi Brar jaswinder.si...@linaro.org

Convert the PL320 controller driver to work with the common
mailbox API. Also convert the only user of PL320, highbank-cpufreq.c
to work with thee API. Drop the obsoleted driver pl320-ipc.c

Signed-off-by: Jassi Brar jaswinder.si...@linaro.org
---
 drivers/cpufreq/highbank-cpufreq.c   |   22 +++-
 drivers/mailbox/Makefile |2 +-
 drivers/mailbox/{pl320-ipc.c = pl320.c} |  194 --
 include/linux/pl320-ipc.h|   17 ---
 4 files changed, 125 insertions(+), 110 deletions(-)
 rename drivers/mailbox/{pl320-ipc.c = pl320.c} (51%)
 delete mode 100644 include/linux/pl320-ipc.h

diff --git a/drivers/cpufreq/highbank-cpufreq.c 
b/drivers/cpufreq/highbank-cpufreq.c
index 3118b87..5c057e0 100644
--- a/drivers/cpufreq/highbank-cpufreq.c
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -19,7 +19,7 @@
 #include linux/cpu.h
 #include linux/err.h
 #include linux/of.h
-#include linux/pl320-ipc.h
+#include linux/mailbox_client.h
 #include linux/platform_device.h
 
 #define HB_CPUFREQ_CHANGE_NOTE 0x8001
@@ -29,8 +29,26 @@
 static int hb_voltage_change(unsigned int freq)
 {
u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 100};
+   struct ipc_client cl;
+   int ret = -ETIMEDOUT;
+   void *chan;
 
-   return pl320_ipc_transmit(msg);
+   cl.rxcb = NULL;
+   cl.txcb = NULL;
+   cl.tx_block = true;
+   cl.tx_tout = 1000; /* 1 sec */
+   cl.cntlr_data = NULL;
+   cl.knows_txdone = false;
+   cl.chan_name = pl320:A9_to_M3;
+
+   chan = ipc_request_channel(cl);
+
+   if (ipc_send_message(chan, (void *)msg))
+   ret = msg[1]; /* PL320 updates buffer with FIFO after ACK */
+
+   ipc_free_channel(chan);
+
+   return ret;
 }
 
 static int hb_cpufreq_clk_notify(struct notifier_block *nb,
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index fefef7e..7b897f3 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,4 +2,4 @@
 
 obj-$(CONFIG_MAILBOX)  += mailbox.o
 
-obj-$(CONFIG_PL320_MBOX)   += pl320-ipc.o
+obj-$(CONFIG_PL320_MBOX)   += pl320.o
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320.c
similarity index 51%
rename from drivers/mailbox/pl320-ipc.c
rename to drivers/mailbox/pl320.c
index f3755e0..98b40f4 100644
--- a/drivers/mailbox/pl320-ipc.c
+++ b/drivers/mailbox/pl320.c
@@ -25,8 +25,9 @@
 #include linux/spinlock.h
 #include linux/device.h
 #include linux/amba/bus.h
-
-#include linux/pl320-ipc.h
+#include linux/slab.h
+#include linux/platform_device.h
+#include linux/mailbox_controller.h
 
 #define IPCMxSOURCE(m) ((m) * 0x40)
 #define IPCMxDSET(m)   (((m) * 0x40) + 0x004)
@@ -44,114 +45,86 @@
 
 #define MBOX_MASK(n)   (1  (n))
 #define IPC_TX_MBOX1
-#define IPC_RX_MBOX2
 
 #define CHAN_MASK(n)   (1  (n))
 #define A9_SOURCE  1
 #define M3_SOURCE  0
 
-static void __iomem *ipc_base;
-static int ipc_irq;
-static DEFINE_MUTEX(ipc_m1_lock);
-static DECLARE_COMPLETION(ipc_completion);
-static ATOMIC_NOTIFIER_HEAD(ipc_notifier);
+struct pl320_con {
+   u32 *data;
+   int ipc_irq;
+   struct device *dev;
+   struct ipc_link link;
+   void __iomem *ipc_base;
+   struct ipc_controller ipc_con;
+};
 
-static inline void set_destination(int source, int mbox)
+static inline struct pl320_con *to_pl320(struct ipc_link *l)
 {
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox));
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox));
-}
+   if (!l)
+   return NULL;
 
-static inline void clear_destination(int source, int mbox)
-{
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox));
-   __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox));
+   return container_of(l, struct pl320_con, link);
 }
 
-static void __ipc_send(int mbox, u32 *data)
+static irqreturn_t ipc_handler(int irq, void *p)
 {
-   int i;
-   for (i = 0; i  7; i++)
-   __raw_writel(data[i], ipc_base + IPCMxDR(mbox, i));
-   __raw_writel(0x1, ipc_base + IPCMxSEND(mbox));
-}
+   struct ipc_link *link = (struct ipc_link *)p;
+   struct pl320_con *pl320 = to_pl320(link);
+   void __iomem *ipc_base = pl320-ipc_base;
+   u32 irq_stat;
 
-static u32 __ipc_rcv(int mbox, u32 *data)
-{
-   int i;
-   for (i = 0; i  7; i++)
-   data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i));
-   return data[1];
-}
+   irq_stat = __raw_readl(ipc_base + IPCMMIS(1));
+   if (irq_stat  MBOX_MASK(IPC_TX_MBOX)) {
+   u32 *data = pl320-data;
+   int i;
 
-/* blocking implmentation from the A9 side, not usuable in interrupts! */
-int pl320_ipc_transmit(u32 *data)
-{
-   int ret;
+   __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+
+   /*
+