* [PATCH 0/5] Add STM32 DMAMUX support
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patchset adds support for the STM32 DMA multiplexer.
It allows to map any peripheral DMA request to any channel of the product
DMAs.
This IP has been introduced with STM32H7 SoC.
M'boumba Cedric Madianga (5):
dt-bindings: Document the STM32 DMAMUX bindings
dmaengine: Add STM32 DMAMUX driver
dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
dmaengine: stm32-dma: Add support for STM32 DMAMUX
ARM: configs: stm32: Add DMAMUX support in STM32 defconfig
.../devicetree/bindings/dma/stm32-dma.txt | 3 +
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 +++++
arch/arm/configs/stm32_defconfig | 1 +
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/stm32-dma.c | 13 +-
drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++
7 files changed, 312 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
create mode 100644 drivers/dma/stm32-dmamux.c
--
1.9.1
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 0/5] Add STM32 DMAMUX support
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: M'boumba Cedric Madianga
This patchset adds support for the STM32 DMA multiplexer.
It allows to map any peripheral DMA request to any channel of the product
DMAs.
This IP has been introduced with STM32H7 SoC.
M'boumba Cedric Madianga (5):
dt-bindings: Document the STM32 DMAMUX bindings
dmaengine: Add STM32 DMAMUX driver
dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
dmaengine: stm32-dma: Add support for STM32 DMAMUX
ARM: configs: stm32: Add DMAMUX support in STM32 defconfig
.../devicetree/bindings/dma/stm32-dma.txt | 3 +
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 +++++
arch/arm/configs/stm32_defconfig | 1 +
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/stm32-dma.c | 13 +-
drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++
7 files changed, 312 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
create mode 100644 drivers/dma/stm32-dmamux.c
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 0/5] Add STM32 DMAMUX support
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: linux-arm-kernel
This patchset adds support for the STM32 DMA multiplexer.
It allows to map any peripheral DMA request to any channel of the product
DMAs.
This IP has been introduced with STM32H7 SoC.
M'boumba Cedric Madianga (5):
dt-bindings: Document the STM32 DMAMUX bindings
dmaengine: Add STM32 DMAMUX driver
dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
dmaengine: stm32-dma: Add support for STM32 DMAMUX
ARM: configs: stm32: Add DMAMUX support in STM32 defconfig
.../devicetree/bindings/dma/stm32-dma.txt | 3 +
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 +++++
arch/arm/configs/stm32_defconfig | 1 +
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/stm32-dma.c | 13 +-
drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++
7 files changed, 312 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
create mode 100644 drivers/dma/stm32-dmamux.c
--
1.9.1
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patch adds the documentation of device tree bindings for the STM32
DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
new file mode 100644
index 0000000..1039420
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
@@ -0,0 +1,57 @@
+STM32 DMA MUX (DMA request router)
+
+Required properties:
+- compatible: "st,stm32-dmamux"
+- reg: Memory map for accessing module
+- #dma-cells: Should be set to <4>.
+ For more details about the four cells, please see stm32-dma.txt
+ documentation binding file
+- dma-masters: Phandle pointing to the DMA controller
+- clocks: Input clock of the DMAMUX instance.
+
+Optional properties:
+- dma-channels : Number of DMA channels supported.
+- dma-requests : Number of DMA requests supported.
+- resets: Reference to a reset controller asserting the DMA controller
+
+Example:
+
+/* DMA controller */
+dma2: dma-controller@40026400 {
+ compatible = "st,stm32-dma";
+ reg = <0x40026400 0x400>;
+ interrupts = <56>,
+ <57>,
+ <58>,
+ <59>,
+ <60>,
+ <68>,
+ <69>,
+ <70>;
+ clocks = <&clk_hclk>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ resets = <&rcc 150>;
+ st,dmamux;
+ dma-channels = <8>;
+};
+
+/* DMA mux */
+dmamux2: dma-router@40020820 {
+ compatible = "st,stm32-dmamux";
+ reg = <0x40020800 0x1c>;
+ #dma-cells = <4>;
+ dma-requests = <128>;
+ dma-masters = <&dma2>;
+};
+
+/* DMA client */
+usart1: serial@40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&clk_pclk2>;
+ dmas = <&dmamux2 0 41 0x400 0x00>,
+ <&dmamux2 1 42 0x400 0x00>;
+ dma-names = "rx", "tx";
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: M'boumba Cedric Madianga
This patch adds the documentation of device tree bindings for the STM32
DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
new file mode 100644
index 0000000..1039420
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
@@ -0,0 +1,57 @@
+STM32 DMA MUX (DMA request router)
+
+Required properties:
+- compatible: "st,stm32-dmamux"
+- reg: Memory map for accessing module
+- #dma-cells: Should be set to <4>.
+ For more details about the four cells, please see stm32-dma.txt
+ documentation binding file
+- dma-masters: Phandle pointing to the DMA controller
+- clocks: Input clock of the DMAMUX instance.
+
+Optional properties:
+- dma-channels : Number of DMA channels supported.
+- dma-requests : Number of DMA requests supported.
+- resets: Reference to a reset controller asserting the DMA controller
+
+Example:
+
+/* DMA controller */
+dma2: dma-controller@40026400 {
+ compatible = "st,stm32-dma";
+ reg = <0x40026400 0x400>;
+ interrupts = <56>,
+ <57>,
+ <58>,
+ <59>,
+ <60>,
+ <68>,
+ <69>,
+ <70>;
+ clocks = <&clk_hclk>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ resets = <&rcc 150>;
+ st,dmamux;
+ dma-channels = <8>;
+};
+
+/* DMA mux */
+dmamux2: dma-router@40020820 {
+ compatible = "st,stm32-dmamux";
+ reg = <0x40020800 0x1c>;
+ #dma-cells = <4>;
+ dma-requests = <128>;
+ dma-masters = <&dma2>;
+};
+
+/* DMA client */
+usart1: serial@40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&clk_pclk2>;
+ dmas = <&dmamux2 0 41 0x400 0x00>,
+ <&dmamux2 1 42 0x400 0x00>;
+ dma-names = "rx", "tx";
+};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds the documentation of device tree bindings for the STM32
DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
.../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
new file mode 100644
index 0000000..1039420
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
@@ -0,0 +1,57 @@
+STM32 DMA MUX (DMA request router)
+
+Required properties:
+- compatible: "st,stm32-dmamux"
+- reg: Memory map for accessing module
+- #dma-cells: Should be set to <4>.
+ For more details about the four cells, please see stm32-dma.txt
+ documentation binding file
+- dma-masters: Phandle pointing to the DMA controller
+- clocks: Input clock of the DMAMUX instance.
+
+Optional properties:
+- dma-channels : Number of DMA channels supported.
+- dma-requests : Number of DMA requests supported.
+- resets: Reference to a reset controller asserting the DMA controller
+
+Example:
+
+/* DMA controller */
+dma2: dma-controller at 40026400 {
+ compatible = "st,stm32-dma";
+ reg = <0x40026400 0x400>;
+ interrupts = <56>,
+ <57>,
+ <58>,
+ <59>,
+ <60>,
+ <68>,
+ <69>,
+ <70>;
+ clocks = <&clk_hclk>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ resets = <&rcc 150>;
+ st,dmamux;
+ dma-channels = <8>;
+};
+
+/* DMA mux */
+dmamux2: dma-router at 40020820 {
+ compatible = "st,stm32-dmamux";
+ reg = <0x40020800 0x1c>;
+ #dma-cells = <4>;
+ dma-requests = <128>;
+ dma-masters = <&dma2>;
+};
+
+/* DMA client */
+usart1: serial at 40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&clk_pclk2>;
+ dmas = <&dmamux2 0 41 0x400 0x00>,
+ <&dmamux2 1 42 0x400 0x00>;
+ dma-names = "rx", "tx";
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
2017-03-13 14:15 ` M'boumba Cedric Madianga
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
-1 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patch implements the STM32 DMAMUX driver
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
drivers/dma/Kconfig | 9 ++
drivers/dma/Makefile | 1 +
drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 241 insertions(+)
create mode 100644 drivers/dma/stm32-dmamux.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index fc3435c..6ab80c9 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -461,6 +461,15 @@ config STM32_DMA
If you have a board based on such a MCU and wish to use DMA say Y
here.
+config STM32_DMAMUX
+ bool "STMicroelectronics STM32 dma multiplexer support"
+ depends on STM32_DMA
+ help
+ Enable support for the on-chip DMA multiplexer on STMicroelectronics
+ STM32 MCUs.
+ If you have a board based on such a MCU and wish to use DMAMUX say Y
+ here.
+
config S3C24XX_DMAC
bool "Samsung S3C24XX DMA support"
depends on ARCH_S3C24XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 0b723e9..449c7a3 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
obj-$(CONFIG_STM32_DMA) += stm32-dma.o
+obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
new file mode 100644
index 0000000..3003546
--- /dev/null
+++ b/drivers/dma/stm32-dmamux.c
@@ -0,0 +1,231 @@
+/*
+ * DMA Router driver for STM32 DMA MUX
+ *
+ * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
+ *
+ * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#define STM32_DMAMUX_CCR(x) (0x4 * (x))
+#define STM32_DMAMUX_MAX_CHANNELS 32
+#define STM32_DMAMUX_MAX_REQUESTS 255
+
+struct stm32_dmamux {
+ u32 chan_id;
+ u32 request;
+ bool busy;
+};
+
+struct stm32_dmamux_data {
+ struct dma_router dmarouter;
+ struct stm32_dmamux *muxes;
+ struct clk *clk;
+ void __iomem *iomem;
+ u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
+ u32 dmamux_channels; /* Number of DMA channels supported */
+};
+
+static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
+{
+ return readl_relaxed(iomem + reg);
+}
+
+static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
+{
+ writel_relaxed(val, iomem + reg);
+}
+
+static void stm32_dmamux_free(struct device *dev, void *route_data)
+{
+ struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
+ struct stm32_dmamux *mux = route_data;
+
+ /* Clear dma request for the right channel */
+ stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
+ clk_disable(dmamux->clk);
+ mux->busy = false;
+
+ dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
+ dev->id, mux->chan_id, mux->request);
+}
+
+static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+ struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
+ struct stm32_dmamux *mux;
+ u32 chan_id;
+ int ret;
+
+ if (dma_spec->args_count != 4) {
+ dev_err(&pdev->dev, "invalid number of dma mux args\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (dma_spec->args[0] >= dmamux->dmamux_channels) {
+ dev_err(&pdev->dev, "invalid channel id: %d\n",
+ dma_spec->args[0]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (dma_spec->args[1] > dmamux->dmamux_requests) {
+ dev_err(&pdev->dev, "invalid mux request number: %d\n",
+ dma_spec->args[1]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* The of_node_put() will be done in of_dma_router_xlate function */
+ dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
+ if (!dma_spec->np) {
+ dev_err(&pdev->dev, "can't get dma master\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ chan_id = dma_spec->args[0];
+ mux = &dmamux->muxes[chan_id];
+ mux->chan_id = chan_id;
+ mux->request = dma_spec->args[1];
+
+ if (mux->busy) {
+ dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
+ chan_id, mux->request);
+ return ERR_PTR(-EBUSY);
+ }
+
+ ret = clk_enable(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
+ mux->request);
+ mux->busy = true;
+
+ dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
+ pdev->dev.id, mux->chan_id, mux->request);
+
+ return mux;
+}
+
+static int stm32_dmamux_probe(struct platform_device *pdev)
+{
+ struct device_node *dma_node, *node = pdev->dev.of_node;
+ struct stm32_dmamux_data *dmamux;
+ struct reset_control *rst;
+ struct resource *res;
+ int ret;
+
+ if (!node)
+ return -ENODEV;
+
+ dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
+ GFP_KERNEL);
+ if (!dmamux)
+ return -ENOMEM;
+
+ dma_node = of_parse_phandle(node, "dma-masters", 0);
+ if (!dma_node) {
+ dev_err(&pdev->dev, "Can't get DMA master node\n");
+ return -ENODEV;
+ }
+ of_node_put(dma_node);
+
+ ret = of_property_read_u32(node, "dma-channels",
+ &dmamux->dmamux_channels);
+ if (ret)
+ dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
+
+ ret = of_property_read_u32(node, "dma-requests",
+ &dmamux->dmamux_requests);
+ if (ret)
+ dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
+ if (!dmamux->iomem)
+ return -ENOMEM;
+
+ dmamux->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(dmamux->clk)) {
+ dev_err(&pdev->dev, "Missing controller clock\n");
+ return PTR_ERR(dmamux->clk);
+ }
+ ret = clk_prepare(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
+ return ret;
+ }
+
+ dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
+ sizeof(struct stm32_dmamux),
+ GFP_KERNEL);
+ if (!dmamux->muxes)
+ return -ENOMEM;
+
+ rst = devm_reset_control_get(&pdev->dev, NULL);
+ if (!IS_ERR(rst)) {
+ ret = clk_enable(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+ reset_control_assert(rst);
+ udelay(2);
+ reset_control_deassert(rst);
+ clk_disable(dmamux->clk);
+ }
+
+ dmamux->dmarouter.dev = &pdev->dev;
+ dmamux->dmarouter.route_free = stm32_dmamux_free;
+ platform_set_drvdata(pdev, dmamux);
+
+ ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
+ &dmamux->dmarouter);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "STM32 DMAMUX DMA OF registration failed %d\n", ret);
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
+
+ return 0;
+}
+
+static const struct of_device_id stm32_dmamux_match[] = {
+ { .compatible = "st,stm32-dmamux" },
+ {},
+};
+
+static struct platform_driver stm32_dmamux_driver = {
+ .probe = stm32_dmamux_probe,
+ .driver = {
+ .name = "stm32-dmamux",
+ .of_match_table = stm32_dmamux_match,
+ },
+};
+
+static int __init stm32_dmamux_init(void)
+{
+ return platform_driver_register(&stm32_dmamux_driver);
+}
+arch_initcall(stm32_dmamux_init);
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: linux-arm-kernel
This patch implements the STM32 DMAMUX driver
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
drivers/dma/Kconfig | 9 ++
drivers/dma/Makefile | 1 +
drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 241 insertions(+)
create mode 100644 drivers/dma/stm32-dmamux.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index fc3435c..6ab80c9 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -461,6 +461,15 @@ config STM32_DMA
If you have a board based on such a MCU and wish to use DMA say Y
here.
+config STM32_DMAMUX
+ bool "STMicroelectronics STM32 dma multiplexer support"
+ depends on STM32_DMA
+ help
+ Enable support for the on-chip DMA multiplexer on STMicroelectronics
+ STM32 MCUs.
+ If you have a board based on such a MCU and wish to use DMAMUX say Y
+ here.
+
config S3C24XX_DMAC
bool "Samsung S3C24XX DMA support"
depends on ARCH_S3C24XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 0b723e9..449c7a3 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
obj-$(CONFIG_STM32_DMA) += stm32-dma.o
+obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
new file mode 100644
index 0000000..3003546
--- /dev/null
+++ b/drivers/dma/stm32-dmamux.c
@@ -0,0 +1,231 @@
+/*
+ * DMA Router driver for STM32 DMA MUX
+ *
+ * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
+ *
+ * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#define STM32_DMAMUX_CCR(x) (0x4 * (x))
+#define STM32_DMAMUX_MAX_CHANNELS 32
+#define STM32_DMAMUX_MAX_REQUESTS 255
+
+struct stm32_dmamux {
+ u32 chan_id;
+ u32 request;
+ bool busy;
+};
+
+struct stm32_dmamux_data {
+ struct dma_router dmarouter;
+ struct stm32_dmamux *muxes;
+ struct clk *clk;
+ void __iomem *iomem;
+ u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
+ u32 dmamux_channels; /* Number of DMA channels supported */
+};
+
+static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
+{
+ return readl_relaxed(iomem + reg);
+}
+
+static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
+{
+ writel_relaxed(val, iomem + reg);
+}
+
+static void stm32_dmamux_free(struct device *dev, void *route_data)
+{
+ struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
+ struct stm32_dmamux *mux = route_data;
+
+ /* Clear dma request for the right channel */
+ stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
+ clk_disable(dmamux->clk);
+ mux->busy = false;
+
+ dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
+ dev->id, mux->chan_id, mux->request);
+}
+
+static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+ struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
+ struct stm32_dmamux *mux;
+ u32 chan_id;
+ int ret;
+
+ if (dma_spec->args_count != 4) {
+ dev_err(&pdev->dev, "invalid number of dma mux args\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (dma_spec->args[0] >= dmamux->dmamux_channels) {
+ dev_err(&pdev->dev, "invalid channel id: %d\n",
+ dma_spec->args[0]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (dma_spec->args[1] > dmamux->dmamux_requests) {
+ dev_err(&pdev->dev, "invalid mux request number: %d\n",
+ dma_spec->args[1]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* The of_node_put() will be done in of_dma_router_xlate function */
+ dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
+ if (!dma_spec->np) {
+ dev_err(&pdev->dev, "can't get dma master\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ chan_id = dma_spec->args[0];
+ mux = &dmamux->muxes[chan_id];
+ mux->chan_id = chan_id;
+ mux->request = dma_spec->args[1];
+
+ if (mux->busy) {
+ dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
+ chan_id, mux->request);
+ return ERR_PTR(-EBUSY);
+ }
+
+ ret = clk_enable(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
+ mux->request);
+ mux->busy = true;
+
+ dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
+ pdev->dev.id, mux->chan_id, mux->request);
+
+ return mux;
+}
+
+static int stm32_dmamux_probe(struct platform_device *pdev)
+{
+ struct device_node *dma_node, *node = pdev->dev.of_node;
+ struct stm32_dmamux_data *dmamux;
+ struct reset_control *rst;
+ struct resource *res;
+ int ret;
+
+ if (!node)
+ return -ENODEV;
+
+ dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
+ GFP_KERNEL);
+ if (!dmamux)
+ return -ENOMEM;
+
+ dma_node = of_parse_phandle(node, "dma-masters", 0);
+ if (!dma_node) {
+ dev_err(&pdev->dev, "Can't get DMA master node\n");
+ return -ENODEV;
+ }
+ of_node_put(dma_node);
+
+ ret = of_property_read_u32(node, "dma-channels",
+ &dmamux->dmamux_channels);
+ if (ret)
+ dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
+
+ ret = of_property_read_u32(node, "dma-requests",
+ &dmamux->dmamux_requests);
+ if (ret)
+ dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
+ if (!dmamux->iomem)
+ return -ENOMEM;
+
+ dmamux->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(dmamux->clk)) {
+ dev_err(&pdev->dev, "Missing controller clock\n");
+ return PTR_ERR(dmamux->clk);
+ }
+ ret = clk_prepare(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
+ return ret;
+ }
+
+ dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
+ sizeof(struct stm32_dmamux),
+ GFP_KERNEL);
+ if (!dmamux->muxes)
+ return -ENOMEM;
+
+ rst = devm_reset_control_get(&pdev->dev, NULL);
+ if (!IS_ERR(rst)) {
+ ret = clk_enable(dmamux->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+ reset_control_assert(rst);
+ udelay(2);
+ reset_control_deassert(rst);
+ clk_disable(dmamux->clk);
+ }
+
+ dmamux->dmarouter.dev = &pdev->dev;
+ dmamux->dmarouter.route_free = stm32_dmamux_free;
+ platform_set_drvdata(pdev, dmamux);
+
+ ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
+ &dmamux->dmarouter);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "STM32 DMAMUX DMA OF registration failed %d\n", ret);
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
+
+ return 0;
+}
+
+static const struct of_device_id stm32_dmamux_match[] = {
+ { .compatible = "st,stm32-dmamux" },
+ {},
+};
+
+static struct platform_driver stm32_dmamux_driver = {
+ .probe = stm32_dmamux_probe,
+ .driver = {
+ .name = "stm32-dmamux",
+ .of_match_table = stm32_dmamux_match,
+ },
+};
+
+static int __init stm32_dmamux_init(void)
+{
+ return platform_driver_register(&stm32_dmamux_driver);
+}
+arch_initcall(stm32_dmamux_init);
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patch adds an optional property needed for STM32 DMA controller
addressed via STM32 DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
index 4408af6..7b5e91a 100644
--- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
+++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
@@ -16,6 +16,9 @@ Optional properties:
- resets: Reference to a reset controller asserting the DMA controller
- st,mem2mem: boolean; if defined, it indicates that the controller supports
memory-to-memory transfer
+- st,dmamux: boolean; if defined, it indicates that the controller is behind a
+ DMA multiplexer. In that case, using dma instances doesn't work for DMA
+ clients. They have to use dma-router instances.
Example:
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: M'boumba Cedric Madianga
This patch adds an optional property needed for STM32 DMA controller
addressed via STM32 DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
index 4408af6..7b5e91a 100644
--- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
+++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
@@ -16,6 +16,9 @@ Optional properties:
- resets: Reference to a reset controller asserting the DMA controller
- st,mem2mem: boolean; if defined, it indicates that the controller supports
memory-to-memory transfer
+- st,dmamux: boolean; if defined, it indicates that the controller is behind a
+ DMA multiplexer. In that case, using dma instances doesn't work for DMA
+ clients. They have to use dma-router instances.
Example:
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-03-13 14:15 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:15 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds an optional property needed for STM32 DMA controller
addressed via STM32 DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
index 4408af6..7b5e91a 100644
--- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
+++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
@@ -16,6 +16,9 @@ Optional properties:
- resets: Reference to a reset controller asserting the DMA controller
- st,mem2mem: boolean; if defined, it indicates that the controller supports
memory-to-memory transfer
+- st,dmamux: boolean; if defined, it indicates that the controller is behind a
+ DMA multiplexer. In that case, using dma instances doesn't work for DMA
+ clients. They have to use dma-router instances.
Example:
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 4/5] dmaengine: stm32-dma: Add support for STM32 DMAMUX
@ 2017-03-13 14:16 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:16 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patch adds support for STM32 DMAMUX.
When the STM32 DMA controller is behind a STM32 DMAMUX the request line
number has not to be handled by DMA but DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
drivers/dma/stm32-dma.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 786fc8f..3bf2893 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -179,6 +179,7 @@ struct stm32_dma_device {
struct clk *clk;
struct reset_control *rst;
bool mem2mem;
+ bool dmamux;
struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS];
};
@@ -968,10 +969,14 @@ static void stm32_dma_desc_free(struct virt_dma_desc *vdesc)
static void stm32_dma_set_config(struct stm32_dma_chan *chan,
struct stm32_dma_cfg *cfg)
{
+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan);
+
stm32_dma_clear_reg(&chan->chan_reg);
chan->chan_reg.dma_scr = cfg->stream_config & STM32_DMA_SCR_CFG_MASK;
- chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
+
+ if (!dmadev->dmamux)
+ chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
/* Enable Interrupts */
chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
@@ -998,8 +1003,8 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
cfg.stream_config = dma_spec->args[2];
cfg.threshold = dma_spec->args[3];
- if ((cfg.channel_id >= STM32_DMA_MAX_CHANNELS) ||
- (cfg.request_line >= STM32_DMA_MAX_REQUEST_ID)) {
+ if ((!dmadev->dmamux && cfg.request_line >= STM32_DMA_MAX_REQUEST_ID) ||
+ (cfg.channel_id >= STM32_DMA_MAX_CHANNELS)) {
dev_err(dev, "Bad channel and/or request id\n");
return NULL;
}
@@ -1058,6 +1063,8 @@ static int stm32_dma_probe(struct platform_device *pdev)
dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node,
"st,mem2mem");
+ dmadev->dmamux = of_property_read_bool(pdev->dev.of_node, "st,dmamux");
+
dmadev->rst = devm_reset_control_get(&pdev->dev, NULL);
if (!IS_ERR(dmadev->rst)) {
reset_control_assert(dmadev->rst);
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 4/5] dmaengine: stm32-dma: Add support for STM32 DMAMUX
@ 2017-03-13 14:16 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:16 UTC (permalink / raw)
To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: M'boumba Cedric Madianga
This patch adds support for STM32 DMAMUX.
When the STM32 DMA controller is behind a STM32 DMAMUX the request line
number has not to be handled by DMA but DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/dma/stm32-dma.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 786fc8f..3bf2893 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -179,6 +179,7 @@ struct stm32_dma_device {
struct clk *clk;
struct reset_control *rst;
bool mem2mem;
+ bool dmamux;
struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS];
};
@@ -968,10 +969,14 @@ static void stm32_dma_desc_free(struct virt_dma_desc *vdesc)
static void stm32_dma_set_config(struct stm32_dma_chan *chan,
struct stm32_dma_cfg *cfg)
{
+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan);
+
stm32_dma_clear_reg(&chan->chan_reg);
chan->chan_reg.dma_scr = cfg->stream_config & STM32_DMA_SCR_CFG_MASK;
- chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
+
+ if (!dmadev->dmamux)
+ chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
/* Enable Interrupts */
chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
@@ -998,8 +1003,8 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
cfg.stream_config = dma_spec->args[2];
cfg.threshold = dma_spec->args[3];
- if ((cfg.channel_id >= STM32_DMA_MAX_CHANNELS) ||
- (cfg.request_line >= STM32_DMA_MAX_REQUEST_ID)) {
+ if ((!dmadev->dmamux && cfg.request_line >= STM32_DMA_MAX_REQUEST_ID) ||
+ (cfg.channel_id >= STM32_DMA_MAX_CHANNELS)) {
dev_err(dev, "Bad channel and/or request id\n");
return NULL;
}
@@ -1058,6 +1063,8 @@ static int stm32_dma_probe(struct platform_device *pdev)
dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node,
"st,mem2mem");
+ dmadev->dmamux = of_property_read_bool(pdev->dev.of_node, "st,dmamux");
+
dmadev->rst = devm_reset_control_get(&pdev->dev, NULL);
if (!IS_ERR(dmadev->rst)) {
reset_control_assert(dmadev->rst);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 4/5] dmaengine: stm32-dma: Add support for STM32 DMAMUX
@ 2017-03-13 14:16 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:16 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds support for STM32 DMAMUX.
When the STM32 DMA controller is behind a STM32 DMAMUX the request line
number has not to be handled by DMA but DMAMUX.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
drivers/dma/stm32-dma.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 786fc8f..3bf2893 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -179,6 +179,7 @@ struct stm32_dma_device {
struct clk *clk;
struct reset_control *rst;
bool mem2mem;
+ bool dmamux;
struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS];
};
@@ -968,10 +969,14 @@ static void stm32_dma_desc_free(struct virt_dma_desc *vdesc)
static void stm32_dma_set_config(struct stm32_dma_chan *chan,
struct stm32_dma_cfg *cfg)
{
+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan);
+
stm32_dma_clear_reg(&chan->chan_reg);
chan->chan_reg.dma_scr = cfg->stream_config & STM32_DMA_SCR_CFG_MASK;
- chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
+
+ if (!dmadev->dmamux)
+ chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line);
/* Enable Interrupts */
chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
@@ -998,8 +1003,8 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
cfg.stream_config = dma_spec->args[2];
cfg.threshold = dma_spec->args[3];
- if ((cfg.channel_id >= STM32_DMA_MAX_CHANNELS) ||
- (cfg.request_line >= STM32_DMA_MAX_REQUEST_ID)) {
+ if ((!dmadev->dmamux && cfg.request_line >= STM32_DMA_MAX_REQUEST_ID) ||
+ (cfg.channel_id >= STM32_DMA_MAX_CHANNELS)) {
dev_err(dev, "Bad channel and/or request id\n");
return NULL;
}
@@ -1058,6 +1063,8 @@ static int stm32_dma_probe(struct platform_device *pdev)
dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node,
"st,mem2mem");
+ dmadev->dmamux = of_property_read_bool(pdev->dev.of_node, "st,dmamux");
+
dmadev->rst = devm_reset_control_get(&pdev->dev, NULL);
if (!IS_ERR(dmadev->rst)) {
reset_control_assert(dmadev->rst);
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 5/5] ARM: configs: stm32: Add DMAMUX support in STM32 defconfig
2017-03-13 14:15 ` M'boumba Cedric Madianga
@ 2017-03-13 14:16 ` M'boumba Cedric Madianga
-1 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:16 UTC (permalink / raw)
To: vinod.koul, robh+dt, mark.rutland, mcoquelin.stm32,
alexandre.torgue, dan.j.williams, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
Cc: M'boumba Cedric Madianga
This patch adds DMAMUX support in STM32 defconfig file
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
arch/arm/configs/stm32_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index a9d8e3c..afb6832 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -60,6 +60,7 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_STM32=y
CONFIG_DMADEVICES=y
CONFIG_STM32_DMA=y
+CONFIG_STM32_DMAMUX=y
CONFIG_IIO=y
CONFIG_STM32_ADC_CORE=y
CONFIG_STM32_ADC=y
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 5/5] ARM: configs: stm32: Add DMAMUX support in STM32 defconfig
@ 2017-03-13 14:16 ` M'boumba Cedric Madianga
0 siblings, 0 replies; 40+ messages in thread
From: M'boumba Cedric Madianga @ 2017-03-13 14:16 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds DMAMUX support in STM32 defconfig file
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
arch/arm/configs/stm32_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index a9d8e3c..afb6832 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -60,6 +60,7 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_STM32=y
CONFIG_DMADEVICES=y
CONFIG_STM32_DMA=y
+CONFIG_STM32_DMAMUX=y
CONFIG_IIO=y
CONFIG_STM32_ADC_CORE=y
CONFIG_STM32_ADC=y
--
1.9.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-20 21:34 ` Rob Herring
0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:34 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: vinod.koul, mark.rutland, mcoquelin.stm32, alexandre.torgue,
dan.j.williams, dmaengine, devicetree, linux-arm-kernel,
linux-kernel
On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds the documentation of device tree bindings for the STM32
> DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> new file mode 100644
> index 0000000..1039420
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> @@ -0,0 +1,57 @@
> +STM32 DMA MUX (DMA request router)
> +
> +Required properties:
> +- compatible: "st,stm32-dmamux"
> +- reg: Memory map for accessing module
> +- #dma-cells: Should be set to <4>.
> + For more details about the four cells, please see stm32-dma.txt
> + documentation binding file
> +- dma-masters: Phandle pointing to the DMA controller
> +- clocks: Input clock of the DMAMUX instance.
> +
> +Optional properties:
> +- dma-channels : Number of DMA channels supported.
> +- dma-requests : Number of DMA requests supported.
> +- resets: Reference to a reset controller asserting the DMA controller
> +
> +Example:
> +
> +/* DMA controller */
> +dma2: dma-controller@40026400 {
> + compatible = "st,stm32-dma";
> + reg = <0x40026400 0x400>;
> + interrupts = <56>,
> + <57>,
> + <58>,
> + <59>,
> + <60>,
> + <68>,
> + <69>,
> + <70>;
> + clocks = <&clk_hclk>;
> + #dma-cells = <4>;
> + st,mem2mem;
> + resets = <&rcc 150>;
> + st,dmamux;
> + dma-channels = <8>;
> +};
> +
> +/* DMA mux */
> +dmamux2: dma-router@40020820 {
> + compatible = "st,stm32-dmamux";
> + reg = <0x40020800 0x1c>;
> + #dma-cells = <4>;
> + dma-requests = <128>;
> + dma-masters = <&dma2>;
I think this should be modeled after the interrupt-map property (or
Stephen Boyd's gpio-map support which additionally allows pass thru of
cell values). Something like this:
dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
<1 42 0 0 &dma2 1 <req> 0 0>;
dma-map-mask = <0xffffffff 0xffffffff 0 0>;
<req> is the request number on dma2 controller.
This is more generic and would work if you have a single mux with
multiple DMA controllers.
> +};
> +
> +/* DMA client */
> +usart1: serial@40011000 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
> + reg = <0x40011000 0x400>;
> + interrupts = <37>;
> + clocks = <&clk_pclk2>;
> + dmas = <&dmamux2 0 41 0x400 0x00>,
> + <&dmamux2 1 42 0x400 0x00>;
> + dma-names = "rx", "tx";
> +};
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-20 21:34 ` Rob Herring
0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:34 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds the documentation of device tree bindings for the STM32
> DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> new file mode 100644
> index 0000000..1039420
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> @@ -0,0 +1,57 @@
> +STM32 DMA MUX (DMA request router)
> +
> +Required properties:
> +- compatible: "st,stm32-dmamux"
> +- reg: Memory map for accessing module
> +- #dma-cells: Should be set to <4>.
> + For more details about the four cells, please see stm32-dma.txt
> + documentation binding file
> +- dma-masters: Phandle pointing to the DMA controller
> +- clocks: Input clock of the DMAMUX instance.
> +
> +Optional properties:
> +- dma-channels : Number of DMA channels supported.
> +- dma-requests : Number of DMA requests supported.
> +- resets: Reference to a reset controller asserting the DMA controller
> +
> +Example:
> +
> +/* DMA controller */
> +dma2: dma-controller@40026400 {
> + compatible = "st,stm32-dma";
> + reg = <0x40026400 0x400>;
> + interrupts = <56>,
> + <57>,
> + <58>,
> + <59>,
> + <60>,
> + <68>,
> + <69>,
> + <70>;
> + clocks = <&clk_hclk>;
> + #dma-cells = <4>;
> + st,mem2mem;
> + resets = <&rcc 150>;
> + st,dmamux;
> + dma-channels = <8>;
> +};
> +
> +/* DMA mux */
> +dmamux2: dma-router@40020820 {
> + compatible = "st,stm32-dmamux";
> + reg = <0x40020800 0x1c>;
> + #dma-cells = <4>;
> + dma-requests = <128>;
> + dma-masters = <&dma2>;
I think this should be modeled after the interrupt-map property (or
Stephen Boyd's gpio-map support which additionally allows pass thru of
cell values). Something like this:
dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
<1 42 0 0 &dma2 1 <req> 0 0>;
dma-map-mask = <0xffffffff 0xffffffff 0 0>;
<req> is the request number on dma2 controller.
This is more generic and would work if you have a single mux with
multiple DMA controllers.
> +};
> +
> +/* DMA client */
> +usart1: serial@40011000 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
> + reg = <0x40011000 0x400>;
> + interrupts = <37>;
> + clocks = <&clk_pclk2>;
> + dmas = <&dmamux2 0 41 0x400 0x00>,
> + <&dmamux2 1 42 0x400 0x00>;
> + dma-names = "rx", "tx";
> +};
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-03-20 21:34 ` Rob Herring
0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:34 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds the documentation of device tree bindings for the STM32
> DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> new file mode 100644
> index 0000000..1039420
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
> @@ -0,0 +1,57 @@
> +STM32 DMA MUX (DMA request router)
> +
> +Required properties:
> +- compatible: "st,stm32-dmamux"
> +- reg: Memory map for accessing module
> +- #dma-cells: Should be set to <4>.
> + For more details about the four cells, please see stm32-dma.txt
> + documentation binding file
> +- dma-masters: Phandle pointing to the DMA controller
> +- clocks: Input clock of the DMAMUX instance.
> +
> +Optional properties:
> +- dma-channels : Number of DMA channels supported.
> +- dma-requests : Number of DMA requests supported.
> +- resets: Reference to a reset controller asserting the DMA controller
> +
> +Example:
> +
> +/* DMA controller */
> +dma2: dma-controller at 40026400 {
> + compatible = "st,stm32-dma";
> + reg = <0x40026400 0x400>;
> + interrupts = <56>,
> + <57>,
> + <58>,
> + <59>,
> + <60>,
> + <68>,
> + <69>,
> + <70>;
> + clocks = <&clk_hclk>;
> + #dma-cells = <4>;
> + st,mem2mem;
> + resets = <&rcc 150>;
> + st,dmamux;
> + dma-channels = <8>;
> +};
> +
> +/* DMA mux */
> +dmamux2: dma-router at 40020820 {
> + compatible = "st,stm32-dmamux";
> + reg = <0x40020800 0x1c>;
> + #dma-cells = <4>;
> + dma-requests = <128>;
> + dma-masters = <&dma2>;
I think this should be modeled after the interrupt-map property (or
Stephen Boyd's gpio-map support which additionally allows pass thru of
cell values). Something like this:
dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
<1 42 0 0 &dma2 1 <req> 0 0>;
dma-map-mask = <0xffffffff 0xffffffff 0 0>;
<req> is the request number on dma2 controller.
This is more generic and would work if you have a single mux with
multiple DMA controllers.
> +};
> +
> +/* DMA client */
> +usart1: serial at 40011000 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
> + reg = <0x40011000 0x400>;
> + interrupts = <37>;
> + clocks = <&clk_pclk2>;
> + dmas = <&dmamux2 0 41 0x400 0x00>,
> + <&dmamux2 1 42 0x400 0x00>;
> + dma-names = "rx", "tx";
> +};
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
2017-03-13 14:15 ` M'boumba Cedric Madianga
(?)
@ 2017-03-20 21:37 ` Rob Herring
-1 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:37 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: vinod.koul, mark.rutland, mcoquelin.stm32, alexandre.torgue,
dan.j.williams, dmaengine, devicetree, linux-arm-kernel,
linux-kernel
On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds an optional property needed for STM32 DMA controller
> addressed via STM32 DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> index 4408af6..7b5e91a 100644
> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> @@ -16,6 +16,9 @@ Optional properties:
> - resets: Reference to a reset controller asserting the DMA controller
> - st,mem2mem: boolean; if defined, it indicates that the controller supports
> memory-to-memory transfer
> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
> + clients. They have to use dma-router instances.
This should not be needed for the same reason we don't need anything
like this for chained interrupt controllers.
Also, the compatible string should be specific enough to provide this
information.
Rob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-03-20 21:37 ` Rob Herring
0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:37 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, alexandre.torgue, vinod.koul,
linux-kernel, mcoquelin.stm32, dmaengine, dan.j.williams,
linux-arm-kernel
On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds an optional property needed for STM32 DMA controller
> addressed via STM32 DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> index 4408af6..7b5e91a 100644
> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> @@ -16,6 +16,9 @@ Optional properties:
> - resets: Reference to a reset controller asserting the DMA controller
> - st,mem2mem: boolean; if defined, it indicates that the controller supports
> memory-to-memory transfer
> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
> + clients. They have to use dma-router instances.
This should not be needed for the same reason we don't need anything
like this for chained interrupt controllers.
Also, the compatible string should be specific enough to provide this
information.
Rob
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-03-20 21:37 ` Rob Herring
0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-03-20 21:37 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
> This patch adds an optional property needed for STM32 DMA controller
> addressed via STM32 DMAMUX.
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> index 4408af6..7b5e91a 100644
> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
> @@ -16,6 +16,9 @@ Optional properties:
> - resets: Reference to a reset controller asserting the DMA controller
> - st,mem2mem: boolean; if defined, it indicates that the controller supports
> memory-to-memory transfer
> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
> + clients. They have to use dma-router instances.
This should not be needed for the same reason we don't need anything
like this for chained interrupt controllers.
Also, the compatible string should be specific enough to provide this
information.
Rob
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-04-06 6:40 ` Vinod Koul
0 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-04-06 6:40 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: robh+dt, mark.rutland, mcoquelin.stm32, alexandre.torgue,
dan.j.williams, dmaengine, devicetree, linux-arm-kernel,
linux-kernel
On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
> This patch implements the STM32 DMAMUX driver
Can you describe the controller here pls
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 241 insertions(+)
> create mode 100644 drivers/dma/stm32-dmamux.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index fc3435c..6ab80c9 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -461,6 +461,15 @@ config STM32_DMA
> If you have a board based on such a MCU and wish to use DMA say Y
> here.
>
> +config STM32_DMAMUX
> + bool "STMicroelectronics STM32 dma multiplexer support"
> + depends on STM32_DMA
can you add compile test here so that we can get better compile coverage
> + help
> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
> + STM32 MCUs.
> + If you have a board based on such a MCU and wish to use DMAMUX say Y
> + here.
> +
> config S3C24XX_DMAC
> bool "Samsung S3C24XX DMA support"
> depends on ARCH_S3C24XX || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 0b723e9..449c7a3 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
> new file mode 100644
> index 0000000..3003546
> --- /dev/null
> +++ b/drivers/dma/stm32-dmamux.c
> @@ -0,0 +1,231 @@
> +/*
> + * DMA Router driver for STM32 DMA MUX
> + *
> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
we are in '17 now :)
> + *
> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
> +#define STM32_DMAMUX_MAX_CHANNELS 32
> +#define STM32_DMAMUX_MAX_REQUESTS 255
> +
> +struct stm32_dmamux {
> + u32 chan_id;
> + u32 request;
> + bool busy;
> +};
> +
> +struct stm32_dmamux_data {
> + struct dma_router dmarouter;
> + struct stm32_dmamux *muxes;
> + struct clk *clk;
> + void __iomem *iomem;
> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
> + u32 dmamux_channels; /* Number of DMA channels supported */
> +};
> +
> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
> +{
> + return readl_relaxed(iomem + reg);
> +}
> +
> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
> +{
> + writel_relaxed(val, iomem + reg);
> +}
> +
> +static void stm32_dmamux_free(struct device *dev, void *route_data)
> +{
> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct stm32_dmamux *mux = route_data;
> +
> + /* Clear dma request for the right channel */
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
> + clk_disable(dmamux->clk);
> + mux->busy = false;
> +
> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
> + dev->id, mux->chan_id, mux->request);
> +}
> +
> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + struct stm32_dmamux *mux;
> + u32 chan_id;
> + int ret;
> +
> + if (dma_spec->args_count != 4) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
> + dev_err(&pdev->dev, "invalid channel id: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in of_dma_router_xlate function */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + chan_id = dma_spec->args[0];
> + mux = &dmamux->muxes[chan_id];
> + mux->chan_id = chan_id;
> + mux->request = dma_spec->args[1];
> +
> + if (mux->busy) {
> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
> + chan_id, mux->request);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ERR_PTR(ret);
> + }
> +
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
> + mux->request);
> + mux->busy = true;
> +
> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
> + pdev->dev.id, mux->chan_id, mux->request);
> +
> + return mux;
> +}
> +
> +static int stm32_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *dma_node, *node = pdev->dev.of_node;
> + struct stm32_dmamux_data *dmamux;
> + struct reset_control *rst;
> + struct resource *res;
> + int ret;
> +
> + if (!node)
> + return -ENODEV;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
> + GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dma_node = of_parse_phandle(node, "dma-masters", 0);
> + if (!dma_node) {
> + dev_err(&pdev->dev, "Can't get DMA master node\n");
> + return -ENODEV;
> + }
> + of_node_put(dma_node);
> +
> + ret = of_property_read_u32(node, "dma-channels",
> + &dmamux->dmamux_channels);
can we have property_xxx calls alone, that way driver is not strictly
dependent on of
> + if (ret)
> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
> +
> + ret = of_property_read_u32(node, "dma-requests",
> + &dmamux->dmamux_requests);
> + if (ret)
> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res)
> + return -ENODEV;
> +
> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
> + if (!dmamux->iomem)
> + return -ENOMEM;
> +
> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(dmamux->clk)) {
> + dev_err(&pdev->dev, "Missing controller clock\n");
> + return PTR_ERR(dmamux->clk);
> + }
> + ret = clk_prepare(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
> + return ret;
> + }
> +
> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
> + sizeof(struct stm32_dmamux),
> + GFP_KERNEL);
> + if (!dmamux->muxes)
> + return -ENOMEM;
> +
> + rst = devm_reset_control_get(&pdev->dev, NULL);
> + if (!IS_ERR(rst)) {
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ret;
> + }
> + reset_control_assert(rst);
> + udelay(2);
> + reset_control_deassert(rst);
> + clk_disable(dmamux->clk);
> + }
> +
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = stm32_dmamux_free;
> + platform_set_drvdata(pdev, dmamux);
> +
> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
> + &dmamux->dmarouter);
> + if (ret < 0) {
> + dev_err(&pdev->dev,
> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
> + return ret;
> + }
> +
> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_dmamux_match[] = {
> + { .compatible = "st,stm32-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver stm32_dmamux_driver = {
> + .probe = stm32_dmamux_probe,
> + .driver = {
> + .name = "stm32-dmamux",
> + .of_match_table = stm32_dmamux_match,
> + },
> +};
> +
> +static int __init stm32_dmamux_init(void)
> +{
> + return platform_driver_register(&stm32_dmamux_driver);
> +}
> +arch_initcall(stm32_dmamux_init);
why not module init, wouldnt defer probe solve the dependencies
--
~Vinod
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-04-06 6:40 ` Vinod Koul
0 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-04-06 6:40 UTC (permalink / raw)
To: M'boumba Cedric Madianga
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
dmaengine-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
> This patch implements the STM32 DMAMUX driver
Can you describe the controller here pls
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 241 insertions(+)
> create mode 100644 drivers/dma/stm32-dmamux.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index fc3435c..6ab80c9 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -461,6 +461,15 @@ config STM32_DMA
> If you have a board based on such a MCU and wish to use DMA say Y
> here.
>
> +config STM32_DMAMUX
> + bool "STMicroelectronics STM32 dma multiplexer support"
> + depends on STM32_DMA
can you add compile test here so that we can get better compile coverage
> + help
> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
> + STM32 MCUs.
> + If you have a board based on such a MCU and wish to use DMAMUX say Y
> + here.
> +
> config S3C24XX_DMAC
> bool "Samsung S3C24XX DMA support"
> depends on ARCH_S3C24XX || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 0b723e9..449c7a3 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
> new file mode 100644
> index 0000000..3003546
> --- /dev/null
> +++ b/drivers/dma/stm32-dmamux.c
> @@ -0,0 +1,231 @@
> +/*
> + * DMA Router driver for STM32 DMA MUX
> + *
> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
we are in '17 now :)
> + *
> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
> +#define STM32_DMAMUX_MAX_CHANNELS 32
> +#define STM32_DMAMUX_MAX_REQUESTS 255
> +
> +struct stm32_dmamux {
> + u32 chan_id;
> + u32 request;
> + bool busy;
> +};
> +
> +struct stm32_dmamux_data {
> + struct dma_router dmarouter;
> + struct stm32_dmamux *muxes;
> + struct clk *clk;
> + void __iomem *iomem;
> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
> + u32 dmamux_channels; /* Number of DMA channels supported */
> +};
> +
> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
> +{
> + return readl_relaxed(iomem + reg);
> +}
> +
> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
> +{
> + writel_relaxed(val, iomem + reg);
> +}
> +
> +static void stm32_dmamux_free(struct device *dev, void *route_data)
> +{
> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct stm32_dmamux *mux = route_data;
> +
> + /* Clear dma request for the right channel */
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
> + clk_disable(dmamux->clk);
> + mux->busy = false;
> +
> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
> + dev->id, mux->chan_id, mux->request);
> +}
> +
> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + struct stm32_dmamux *mux;
> + u32 chan_id;
> + int ret;
> +
> + if (dma_spec->args_count != 4) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
> + dev_err(&pdev->dev, "invalid channel id: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in of_dma_router_xlate function */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + chan_id = dma_spec->args[0];
> + mux = &dmamux->muxes[chan_id];
> + mux->chan_id = chan_id;
> + mux->request = dma_spec->args[1];
> +
> + if (mux->busy) {
> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
> + chan_id, mux->request);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ERR_PTR(ret);
> + }
> +
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
> + mux->request);
> + mux->busy = true;
> +
> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
> + pdev->dev.id, mux->chan_id, mux->request);
> +
> + return mux;
> +}
> +
> +static int stm32_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *dma_node, *node = pdev->dev.of_node;
> + struct stm32_dmamux_data *dmamux;
> + struct reset_control *rst;
> + struct resource *res;
> + int ret;
> +
> + if (!node)
> + return -ENODEV;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
> + GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dma_node = of_parse_phandle(node, "dma-masters", 0);
> + if (!dma_node) {
> + dev_err(&pdev->dev, "Can't get DMA master node\n");
> + return -ENODEV;
> + }
> + of_node_put(dma_node);
> +
> + ret = of_property_read_u32(node, "dma-channels",
> + &dmamux->dmamux_channels);
can we have property_xxx calls alone, that way driver is not strictly
dependent on of
> + if (ret)
> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
> +
> + ret = of_property_read_u32(node, "dma-requests",
> + &dmamux->dmamux_requests);
> + if (ret)
> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res)
> + return -ENODEV;
> +
> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
> + if (!dmamux->iomem)
> + return -ENOMEM;
> +
> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(dmamux->clk)) {
> + dev_err(&pdev->dev, "Missing controller clock\n");
> + return PTR_ERR(dmamux->clk);
> + }
> + ret = clk_prepare(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
> + return ret;
> + }
> +
> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
> + sizeof(struct stm32_dmamux),
> + GFP_KERNEL);
> + if (!dmamux->muxes)
> + return -ENOMEM;
> +
> + rst = devm_reset_control_get(&pdev->dev, NULL);
> + if (!IS_ERR(rst)) {
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ret;
> + }
> + reset_control_assert(rst);
> + udelay(2);
> + reset_control_deassert(rst);
> + clk_disable(dmamux->clk);
> + }
> +
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = stm32_dmamux_free;
> + platform_set_drvdata(pdev, dmamux);
> +
> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
> + &dmamux->dmarouter);
> + if (ret < 0) {
> + dev_err(&pdev->dev,
> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
> + return ret;
> + }
> +
> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_dmamux_match[] = {
> + { .compatible = "st,stm32-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver stm32_dmamux_driver = {
> + .probe = stm32_dmamux_probe,
> + .driver = {
> + .name = "stm32-dmamux",
> + .of_match_table = stm32_dmamux_match,
> + },
> +};
> +
> +static int __init stm32_dmamux_init(void)
> +{
> + return platform_driver_register(&stm32_dmamux_driver);
> +}
> +arch_initcall(stm32_dmamux_init);
why not module init, wouldnt defer probe solve the dependencies
--
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-04-06 6:40 ` Vinod Koul
0 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-04-06 6:40 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
> This patch implements the STM32 DMAMUX driver
Can you describe the controller here pls
>
> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
> ---
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 241 insertions(+)
> create mode 100644 drivers/dma/stm32-dmamux.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index fc3435c..6ab80c9 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -461,6 +461,15 @@ config STM32_DMA
> If you have a board based on such a MCU and wish to use DMA say Y
> here.
>
> +config STM32_DMAMUX
> + bool "STMicroelectronics STM32 dma multiplexer support"
> + depends on STM32_DMA
can you add compile test here so that we can get better compile coverage
> + help
> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
> + STM32 MCUs.
> + If you have a board based on such a MCU and wish to use DMAMUX say Y
> + here.
> +
> config S3C24XX_DMAC
> bool "Samsung S3C24XX DMA support"
> depends on ARCH_S3C24XX || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 0b723e9..449c7a3 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
> new file mode 100644
> index 0000000..3003546
> --- /dev/null
> +++ b/drivers/dma/stm32-dmamux.c
> @@ -0,0 +1,231 @@
> +/*
> + * DMA Router driver for STM32 DMA MUX
> + *
> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
we are in '17 now :)
> + *
> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
> +#define STM32_DMAMUX_MAX_CHANNELS 32
> +#define STM32_DMAMUX_MAX_REQUESTS 255
> +
> +struct stm32_dmamux {
> + u32 chan_id;
> + u32 request;
> + bool busy;
> +};
> +
> +struct stm32_dmamux_data {
> + struct dma_router dmarouter;
> + struct stm32_dmamux *muxes;
> + struct clk *clk;
> + void __iomem *iomem;
> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
> + u32 dmamux_channels; /* Number of DMA channels supported */
> +};
> +
> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
> +{
> + return readl_relaxed(iomem + reg);
> +}
> +
> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
> +{
> + writel_relaxed(val, iomem + reg);
> +}
> +
> +static void stm32_dmamux_free(struct device *dev, void *route_data)
> +{
> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct stm32_dmamux *mux = route_data;
> +
> + /* Clear dma request for the right channel */
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
> + clk_disable(dmamux->clk);
> + mux->busy = false;
> +
> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
> + dev->id, mux->chan_id, mux->request);
> +}
> +
> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + struct stm32_dmamux *mux;
> + u32 chan_id;
> + int ret;
> +
> + if (dma_spec->args_count != 4) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
> + dev_err(&pdev->dev, "invalid channel id: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in of_dma_router_xlate function */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + chan_id = dma_spec->args[0];
> + mux = &dmamux->muxes[chan_id];
> + mux->chan_id = chan_id;
> + mux->request = dma_spec->args[1];
> +
> + if (mux->busy) {
> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
> + chan_id, mux->request);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ERR_PTR(ret);
> + }
> +
> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
> + mux->request);
> + mux->busy = true;
> +
> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
> + pdev->dev.id, mux->chan_id, mux->request);
> +
> + return mux;
> +}
> +
> +static int stm32_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *dma_node, *node = pdev->dev.of_node;
> + struct stm32_dmamux_data *dmamux;
> + struct reset_control *rst;
> + struct resource *res;
> + int ret;
> +
> + if (!node)
> + return -ENODEV;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
> + GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dma_node = of_parse_phandle(node, "dma-masters", 0);
> + if (!dma_node) {
> + dev_err(&pdev->dev, "Can't get DMA master node\n");
> + return -ENODEV;
> + }
> + of_node_put(dma_node);
> +
> + ret = of_property_read_u32(node, "dma-channels",
> + &dmamux->dmamux_channels);
can we have property_xxx calls alone, that way driver is not strictly
dependent on of
> + if (ret)
> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
> +
> + ret = of_property_read_u32(node, "dma-requests",
> + &dmamux->dmamux_requests);
> + if (ret)
> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res)
> + return -ENODEV;
> +
> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
> + if (!dmamux->iomem)
> + return -ENOMEM;
> +
> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(dmamux->clk)) {
> + dev_err(&pdev->dev, "Missing controller clock\n");
> + return PTR_ERR(dmamux->clk);
> + }
> + ret = clk_prepare(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
> + return ret;
> + }
> +
> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
> + sizeof(struct stm32_dmamux),
> + GFP_KERNEL);
> + if (!dmamux->muxes)
> + return -ENOMEM;
> +
> + rst = devm_reset_control_get(&pdev->dev, NULL);
> + if (!IS_ERR(rst)) {
> + ret = clk_enable(dmamux->clk);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
> + return ret;
> + }
> + reset_control_assert(rst);
> + udelay(2);
> + reset_control_deassert(rst);
> + clk_disable(dmamux->clk);
> + }
> +
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = stm32_dmamux_free;
> + platform_set_drvdata(pdev, dmamux);
> +
> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
> + &dmamux->dmarouter);
> + if (ret < 0) {
> + dev_err(&pdev->dev,
> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
> + return ret;
> + }
> +
> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_dmamux_match[] = {
> + { .compatible = "st,stm32-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver stm32_dmamux_driver = {
> + .probe = stm32_dmamux_probe,
> + .driver = {
> + .name = "stm32-dmamux",
> + .of_match_table = stm32_dmamux_match,
> + },
> +};
> +
> +static int __init stm32_dmamux_init(void)
> +{
> + return platform_driver_register(&stm32_dmamux_driver);
> +}
> +arch_initcall(stm32_dmamux_init);
why not module init, wouldnt defer probe solve the dependencies
--
~Vinod
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
2017-03-20 21:34 ` Rob Herring
(?)
@ 2017-04-26 8:58 ` Pierre Yves MORDRET
-1 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 8:58 UTC (permalink / raw)
To: Rob Herring, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, vinod.koul,
linux-kernel, mcoquelin.stm32, dmaengine, dan.j.williams,
linux-arm-kernel
Hi Rob
On 03/20/2017 10:34 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds the documentation of device tree bindings for the STM32
>> DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
>> 1 file changed, 57 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> new file mode 100644
>> index 0000000..1039420
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> @@ -0,0 +1,57 @@
>> +STM32 DMA MUX (DMA request router)
>> +
>> +Required properties:
>> +- compatible: "st,stm32-dmamux"
>> +- reg: Memory map for accessing module
>> +- #dma-cells: Should be set to <4>.
>> + For more details about the four cells, please see stm32-dma.txt
>> + documentation binding file
>> +- dma-masters: Phandle pointing to the DMA controller
>> +- clocks: Input clock of the DMAMUX instance.
>> +
>> +Optional properties:
>> +- dma-channels : Number of DMA channels supported.
>> +- dma-requests : Number of DMA requests supported.
>> +- resets: Reference to a reset controller asserting the DMA controller
>> +
>> +Example:
>> +
>> +/* DMA controller */
>> +dma2: dma-controller@40026400 {
>> + compatible = "st,stm32-dma";
>> + reg = <0x40026400 0x400>;
>> + interrupts = <56>,
>> + <57>,
>> + <58>,
>> + <59>,
>> + <60>,
>> + <68>,
>> + <69>,
>> + <70>;
>> + clocks = <&clk_hclk>;
>> + #dma-cells = <4>;
>> + st,mem2mem;
>> + resets = <&rcc 150>;
>> + st,dmamux;
>> + dma-channels = <8>;
>> +};
>> +
>> +/* DMA mux */
>> +dmamux2: dma-router@40020820 {
>> + compatible = "st,stm32-dmamux";
>> + reg = <0x40020800 0x1c>;
>> + #dma-cells = <4>;
>> + dma-requests = <128>;
>> + dma-masters = <&dma2>;
>
> I think this should be modeled after the interrupt-map property (or
> Stephen Boyd's gpio-map support which additionally allows pass thru of
> cell values). Something like this:
>
> dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
> <1 42 0 0 &dma2 1 <req> 0 0>;
> dma-map-mask = <0xffffffff 0xffffffff 0 0>;
>
> <req> is the request number on dma2 controller.
>
> This is more generic and would work if you have a single mux with
> multiple DMA controllers.
>
Would you mind to detail a little bit more your thoughts please ?
Are dma-map & dma-map-mask part of an existing bindings ? or need to be
developed ?
I'm a little bit confused where come from values you used.
>> +};
>> +
>> +/* DMA client */
>> +usart1: serial@40011000 {
>> + compatible = "st,stm32-usart", "st,stm32-uart";
>> + reg = <0x40011000 0x400>;
>> + interrupts = <37>;
>> + clocks = <&clk_pclk2>;
>> + dmas = <&dmamux2 0 41 0x400 0x00>,
>> + <&dmamux2 1 42 0x400 0x00>;
>> + dma-names = "rx", "tx";
>> +};
>> --
>> 1.9.1
>>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-04-26 8:58 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 8:58 UTC (permalink / raw)
To: Rob Herring, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, vinod.koul,
linux-kernel, mcoquelin.stm32, dmaengine, dan.j.williams,
linux-arm-kernel
Hi Rob
On 03/20/2017 10:34 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds the documentation of device tree bindings for the STM32
>> DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
>> 1 file changed, 57 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> new file mode 100644
>> index 0000000..1039420
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> @@ -0,0 +1,57 @@
>> +STM32 DMA MUX (DMA request router)
>> +
>> +Required properties:
>> +- compatible: "st,stm32-dmamux"
>> +- reg: Memory map for accessing module
>> +- #dma-cells: Should be set to <4>.
>> + For more details about the four cells, please see stm32-dma.txt
>> + documentation binding file
>> +- dma-masters: Phandle pointing to the DMA controller
>> +- clocks: Input clock of the DMAMUX instance.
>> +
>> +Optional properties:
>> +- dma-channels : Number of DMA channels supported.
>> +- dma-requests : Number of DMA requests supported.
>> +- resets: Reference to a reset controller asserting the DMA controller
>> +
>> +Example:
>> +
>> +/* DMA controller */
>> +dma2: dma-controller@40026400 {
>> + compatible = "st,stm32-dma";
>> + reg = <0x40026400 0x400>;
>> + interrupts = <56>,
>> + <57>,
>> + <58>,
>> + <59>,
>> + <60>,
>> + <68>,
>> + <69>,
>> + <70>;
>> + clocks = <&clk_hclk>;
>> + #dma-cells = <4>;
>> + st,mem2mem;
>> + resets = <&rcc 150>;
>> + st,dmamux;
>> + dma-channels = <8>;
>> +};
>> +
>> +/* DMA mux */
>> +dmamux2: dma-router@40020820 {
>> + compatible = "st,stm32-dmamux";
>> + reg = <0x40020800 0x1c>;
>> + #dma-cells = <4>;
>> + dma-requests = <128>;
>> + dma-masters = <&dma2>;
>
> I think this should be modeled after the interrupt-map property (or
> Stephen Boyd's gpio-map support which additionally allows pass thru of
> cell values). Something like this:
>
> dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
> <1 42 0 0 &dma2 1 <req> 0 0>;
> dma-map-mask = <0xffffffff 0xffffffff 0 0>;
>
> <req> is the request number on dma2 controller.
>
> This is more generic and would work if you have a single mux with
> multiple DMA controllers.
>
Would you mind to detail a little bit more your thoughts please ?
Are dma-map & dma-map-mask part of an existing bindings ? or need to be
developed ?
I'm a little bit confused where come from values you used.
>> +};
>> +
>> +/* DMA client */
>> +usart1: serial@40011000 {
>> + compatible = "st,stm32-usart", "st,stm32-uart";
>> + reg = <0x40011000 0x400>;
>> + interrupts = <37>;
>> + clocks = <&clk_pclk2>;
>> + dmas = <&dmamux2 0 41 0x400 0x00>,
>> + <&dmamux2 1 42 0x400 0x00>;
>> + dma-names = "rx", "tx";
>> +};
>> --
>> 1.9.1
>>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings
@ 2017-04-26 8:58 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 8:58 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rob
On 03/20/2017 10:34 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:57PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds the documentation of device tree bindings for the STM32
>> DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> .../devicetree/bindings/dma/stm32-dmamux.txt | 57 ++++++++++++++++++++++
>> 1 file changed, 57 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dmamux.txt b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> new file mode 100644
>> index 0000000..1039420
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dmamux.txt
>> @@ -0,0 +1,57 @@
>> +STM32 DMA MUX (DMA request router)
>> +
>> +Required properties:
>> +- compatible: "st,stm32-dmamux"
>> +- reg: Memory map for accessing module
>> +- #dma-cells: Should be set to <4>.
>> + For more details about the four cells, please see stm32-dma.txt
>> + documentation binding file
>> +- dma-masters: Phandle pointing to the DMA controller
>> +- clocks: Input clock of the DMAMUX instance.
>> +
>> +Optional properties:
>> +- dma-channels : Number of DMA channels supported.
>> +- dma-requests : Number of DMA requests supported.
>> +- resets: Reference to a reset controller asserting the DMA controller
>> +
>> +Example:
>> +
>> +/* DMA controller */
>> +dma2: dma-controller at 40026400 {
>> + compatible = "st,stm32-dma";
>> + reg = <0x40026400 0x400>;
>> + interrupts = <56>,
>> + <57>,
>> + <58>,
>> + <59>,
>> + <60>,
>> + <68>,
>> + <69>,
>> + <70>;
>> + clocks = <&clk_hclk>;
>> + #dma-cells = <4>;
>> + st,mem2mem;
>> + resets = <&rcc 150>;
>> + st,dmamux;
>> + dma-channels = <8>;
>> +};
>> +
>> +/* DMA mux */
>> +dmamux2: dma-router at 40020820 {
>> + compatible = "st,stm32-dmamux";
>> + reg = <0x40020800 0x1c>;
>> + #dma-cells = <4>;
>> + dma-requests = <128>;
>> + dma-masters = <&dma2>;
>
> I think this should be modeled after the interrupt-map property (or
> Stephen Boyd's gpio-map support which additionally allows pass thru of
> cell values). Something like this:
>
> dma-map = <0 41 0 0 &dma2 0 <req> 0 0>,
> <1 42 0 0 &dma2 1 <req> 0 0>;
> dma-map-mask = <0xffffffff 0xffffffff 0 0>;
>
> <req> is the request number on dma2 controller.
>
> This is more generic and would work if you have a single mux with
> multiple DMA controllers.
>
Would you mind to detail a little bit more your thoughts please ?
Are dma-map & dma-map-mask part of an existing bindings ? or need to be
developed ?
I'm a little bit confused where come from values you used.
>> +};
>> +
>> +/* DMA client */
>> +usart1: serial at 40011000 {
>> + compatible = "st,stm32-usart", "st,stm32-uart";
>> + reg = <0x40011000 0x400>;
>> + interrupts = <37>;
>> + clocks = <&clk_pclk2>;
>> + dmas = <&dmamux2 0 41 0x400 0x00>,
>> + <&dmamux2 1 42 0x400 0x00>;
>> + dma-names = "rx", "tx";
>> +};
>> --
>> 1.9.1
>>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
2017-04-06 6:40 ` Vinod Koul
(?)
@ 2017-04-26 9:17 ` Pierre Yves MORDRET
-1 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:17 UTC (permalink / raw)
To: Vinod Koul, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, linux-kernel,
robh+dt, mcoquelin.stm32, dmaengine, dan.j.williams,
linux-arm-kernel, Pierre Yves MORDRET
On 04/06/2017 08:40 AM, Vinod Koul wrote:
> On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
>> This patch implements the STM32 DMAMUX driver
>
> Can you describe the controller here pls
OK. Will be done in V2
>
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> drivers/dma/Kconfig | 9 ++
>> drivers/dma/Makefile | 1 +
>> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 241 insertions(+)
>> create mode 100644 drivers/dma/stm32-dmamux.c
>>
>> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
>> index fc3435c..6ab80c9 100644
>> --- a/drivers/dma/Kconfig
>> +++ b/drivers/dma/Kconfig
>> @@ -461,6 +461,15 @@ config STM32_DMA
>> If you have a board based on such a MCU and wish to use DMA say Y
>> here.
>>
>> +config STM32_DMAMUX
>> + bool "STMicroelectronics STM32 dma multiplexer support"
>> + depends on STM32_DMA
>
> can you add compile test here so that we can get better compile coverage
OK. Will be done in V2
>
>> + help
>> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
>> + STM32 MCUs.
>> + If you have a board based on such a MCU and wish to use DMAMUX say Y
>> + here.
>> +
>> config S3C24XX_DMAC
>> bool "Samsung S3C24XX DMA support"
>> depends on ARCH_S3C24XX || COMPILE_TEST
>> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
>> index 0b723e9..449c7a3 100644
>> --- a/drivers/dma/Makefile
>> +++ b/drivers/dma/Makefile
>> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
>> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
>> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
>> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
>> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
>> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
>> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
>> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
>> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
>> new file mode 100644
>> index 0000000..3003546
>> --- /dev/null
>> +++ b/drivers/dma/stm32-dmamux.c
>> @@ -0,0 +1,231 @@
>> +/*
>> + * DMA Router driver for STM32 DMA MUX
>> + *
>> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
>
> we are in '17 now :)
OK. Will be done in V2
>
>> + *
>> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
>> + *
>> + * 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/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_dma.h>
>> +#include <linux/reset.h>
>> +#include <linux/slab.h>
>> +
>> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
>> +#define STM32_DMAMUX_MAX_CHANNELS 32
>> +#define STM32_DMAMUX_MAX_REQUESTS 255
>> +
>> +struct stm32_dmamux {
>> + u32 chan_id;
>> + u32 request;
>> + bool busy;
>> +};
>> +
>> +struct stm32_dmamux_data {
>> + struct dma_router dmarouter;
>> + struct stm32_dmamux *muxes;
>> + struct clk *clk;
>> + void __iomem *iomem;
>> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
>> + u32 dmamux_channels; /* Number of DMA channels supported */
>> +};
>> +
>> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
>> +{
>> + return readl_relaxed(iomem + reg);
>> +}
>> +
>> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
>> +{
>> + writel_relaxed(val, iomem + reg);
>> +}
>> +
>> +static void stm32_dmamux_free(struct device *dev, void *route_data)
>> +{
>> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
>> + struct stm32_dmamux *mux = route_data;
>> +
>> + /* Clear dma request for the right channel */
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
>> + clk_disable(dmamux->clk);
>> + mux->busy = false;
>> +
>> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
>> + dev->id, mux->chan_id, mux->request);
>> +}
>> +
>> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
>> + struct of_dma *ofdma)
>> +{
>> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
>> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
>> + struct stm32_dmamux *mux;
>> + u32 chan_id;
>> + int ret;
>> +
>> + if (dma_spec->args_count != 4) {
>> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
>> + dev_err(&pdev->dev, "invalid channel id: %d\n",
>> + dma_spec->args[0]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
>> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
>> + dma_spec->args[1]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + /* The of_node_put() will be done in of_dma_router_xlate function */
>> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
>> + if (!dma_spec->np) {
>> + dev_err(&pdev->dev, "can't get dma master\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + chan_id = dma_spec->args[0];
>> + mux = &dmamux->muxes[chan_id];
>> + mux->chan_id = chan_id;
>> + mux->request = dma_spec->args[1];
>> +
>> + if (mux->busy) {
>> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
>> + chan_id, mux->request);
>> + return ERR_PTR(-EBUSY);
>> + }
>> +
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
>> + mux->request);
>> + mux->busy = true;
>> +
>> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
>> + pdev->dev.id, mux->chan_id, mux->request);
>> +
>> + return mux;
>> +}
>> +
>> +static int stm32_dmamux_probe(struct platform_device *pdev)
>> +{
>> + struct device_node *dma_node, *node = pdev->dev.of_node;
>> + struct stm32_dmamux_data *dmamux;
>> + struct reset_control *rst;
>> + struct resource *res;
>> + int ret;
>> +
>> + if (!node)
>> + return -ENODEV;
>> +
>> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
>> + GFP_KERNEL);
>> + if (!dmamux)
>> + return -ENOMEM;
>> +
>> + dma_node = of_parse_phandle(node, "dma-masters", 0);
>> + if (!dma_node) {
>> + dev_err(&pdev->dev, "Can't get DMA master node\n");
>> + return -ENODEV;
>> + }
>> + of_node_put(dma_node);
>> +
>> + ret = of_property_read_u32(node, "dma-channels",
>> + &dmamux->dmamux_channels);
>
> can we have property_xxx calls alone, that way driver is not strictly
> dependent on of
Can you please explain what you are asking for ? Not sure to understand
correctly.
>
>> + if (ret)
>> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
>> +
>> + ret = of_property_read_u32(node, "dma-requests",
>> + &dmamux->dmamux_requests);
>> + if (ret)
>> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res)
>> + return -ENODEV;
>> +
>> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
>> + if (!dmamux->iomem)
>> + return -ENOMEM;
>> +
>> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
>> + if (IS_ERR(dmamux->clk)) {
>> + dev_err(&pdev->dev, "Missing controller clock\n");
>> + return PTR_ERR(dmamux->clk);
>> + }
>> + ret = clk_prepare(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
>> + sizeof(struct stm32_dmamux),
>> + GFP_KERNEL);
>> + if (!dmamux->muxes)
>> + return -ENOMEM;
>> +
>> + rst = devm_reset_control_get(&pdev->dev, NULL);
>> + if (!IS_ERR(rst)) {
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ret;
>> + }
>> + reset_control_assert(rst);
>> + udelay(2);
>> + reset_control_deassert(rst);
>> + clk_disable(dmamux->clk);
>> + }
>> +
>> + dmamux->dmarouter.dev = &pdev->dev;
>> + dmamux->dmarouter.route_free = stm32_dmamux_free;
>> + platform_set_drvdata(pdev, dmamux);
>> +
>> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
>> + &dmamux->dmarouter);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev,
>> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_dmamux_match[] = {
>> + { .compatible = "st,stm32-dmamux" },
>> + {},
>> +};
>> +
>> +static struct platform_driver stm32_dmamux_driver = {
>> + .probe = stm32_dmamux_probe,
>> + .driver = {
>> + .name = "stm32-dmamux",
>> + .of_match_table = stm32_dmamux_match,
>> + },
>> +};
>> +
>> +static int __init stm32_dmamux_init(void)
>> +{
>> + return platform_driver_register(&stm32_dmamux_driver);
>> +}
>> +arch_initcall(stm32_dmamux_init);
>
> why not module init, wouldnt defer probe solve the dependencies
>
The reason behind many devices (device_initcall level) rely on DMAs. If
init is deferred DMAMUX driver will be probed twice if dependents rely
on it. This sounds not a good call. This explains arch_initcall level.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-04-26 9:17 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:17 UTC (permalink / raw)
To: Vinod Koul, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, linux-kernel,
Pierre Yves MORDRET, robh+dt, mcoquelin.stm32, dmaengine,
dan.j.williams, linux-arm-kernel
On 04/06/2017 08:40 AM, Vinod Koul wrote:
> On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
>> This patch implements the STM32 DMAMUX driver
>
> Can you describe the controller here pls
OK. Will be done in V2
>
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> drivers/dma/Kconfig | 9 ++
>> drivers/dma/Makefile | 1 +
>> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 241 insertions(+)
>> create mode 100644 drivers/dma/stm32-dmamux.c
>>
>> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
>> index fc3435c..6ab80c9 100644
>> --- a/drivers/dma/Kconfig
>> +++ b/drivers/dma/Kconfig
>> @@ -461,6 +461,15 @@ config STM32_DMA
>> If you have a board based on such a MCU and wish to use DMA say Y
>> here.
>>
>> +config STM32_DMAMUX
>> + bool "STMicroelectronics STM32 dma multiplexer support"
>> + depends on STM32_DMA
>
> can you add compile test here so that we can get better compile coverage
OK. Will be done in V2
>
>> + help
>> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
>> + STM32 MCUs.
>> + If you have a board based on such a MCU and wish to use DMAMUX say Y
>> + here.
>> +
>> config S3C24XX_DMAC
>> bool "Samsung S3C24XX DMA support"
>> depends on ARCH_S3C24XX || COMPILE_TEST
>> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
>> index 0b723e9..449c7a3 100644
>> --- a/drivers/dma/Makefile
>> +++ b/drivers/dma/Makefile
>> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
>> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
>> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
>> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
>> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
>> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
>> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
>> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
>> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
>> new file mode 100644
>> index 0000000..3003546
>> --- /dev/null
>> +++ b/drivers/dma/stm32-dmamux.c
>> @@ -0,0 +1,231 @@
>> +/*
>> + * DMA Router driver for STM32 DMA MUX
>> + *
>> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
>
> we are in '17 now :)
OK. Will be done in V2
>
>> + *
>> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
>> + *
>> + * 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/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_dma.h>
>> +#include <linux/reset.h>
>> +#include <linux/slab.h>
>> +
>> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
>> +#define STM32_DMAMUX_MAX_CHANNELS 32
>> +#define STM32_DMAMUX_MAX_REQUESTS 255
>> +
>> +struct stm32_dmamux {
>> + u32 chan_id;
>> + u32 request;
>> + bool busy;
>> +};
>> +
>> +struct stm32_dmamux_data {
>> + struct dma_router dmarouter;
>> + struct stm32_dmamux *muxes;
>> + struct clk *clk;
>> + void __iomem *iomem;
>> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
>> + u32 dmamux_channels; /* Number of DMA channels supported */
>> +};
>> +
>> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
>> +{
>> + return readl_relaxed(iomem + reg);
>> +}
>> +
>> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
>> +{
>> + writel_relaxed(val, iomem + reg);
>> +}
>> +
>> +static void stm32_dmamux_free(struct device *dev, void *route_data)
>> +{
>> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
>> + struct stm32_dmamux *mux = route_data;
>> +
>> + /* Clear dma request for the right channel */
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
>> + clk_disable(dmamux->clk);
>> + mux->busy = false;
>> +
>> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
>> + dev->id, mux->chan_id, mux->request);
>> +}
>> +
>> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
>> + struct of_dma *ofdma)
>> +{
>> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
>> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
>> + struct stm32_dmamux *mux;
>> + u32 chan_id;
>> + int ret;
>> +
>> + if (dma_spec->args_count != 4) {
>> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
>> + dev_err(&pdev->dev, "invalid channel id: %d\n",
>> + dma_spec->args[0]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
>> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
>> + dma_spec->args[1]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + /* The of_node_put() will be done in of_dma_router_xlate function */
>> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
>> + if (!dma_spec->np) {
>> + dev_err(&pdev->dev, "can't get dma master\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + chan_id = dma_spec->args[0];
>> + mux = &dmamux->muxes[chan_id];
>> + mux->chan_id = chan_id;
>> + mux->request = dma_spec->args[1];
>> +
>> + if (mux->busy) {
>> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
>> + chan_id, mux->request);
>> + return ERR_PTR(-EBUSY);
>> + }
>> +
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
>> + mux->request);
>> + mux->busy = true;
>> +
>> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
>> + pdev->dev.id, mux->chan_id, mux->request);
>> +
>> + return mux;
>> +}
>> +
>> +static int stm32_dmamux_probe(struct platform_device *pdev)
>> +{
>> + struct device_node *dma_node, *node = pdev->dev.of_node;
>> + struct stm32_dmamux_data *dmamux;
>> + struct reset_control *rst;
>> + struct resource *res;
>> + int ret;
>> +
>> + if (!node)
>> + return -ENODEV;
>> +
>> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
>> + GFP_KERNEL);
>> + if (!dmamux)
>> + return -ENOMEM;
>> +
>> + dma_node = of_parse_phandle(node, "dma-masters", 0);
>> + if (!dma_node) {
>> + dev_err(&pdev->dev, "Can't get DMA master node\n");
>> + return -ENODEV;
>> + }
>> + of_node_put(dma_node);
>> +
>> + ret = of_property_read_u32(node, "dma-channels",
>> + &dmamux->dmamux_channels);
>
> can we have property_xxx calls alone, that way driver is not strictly
> dependent on of
Can you please explain what you are asking for ? Not sure to understand
correctly.
>
>> + if (ret)
>> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
>> +
>> + ret = of_property_read_u32(node, "dma-requests",
>> + &dmamux->dmamux_requests);
>> + if (ret)
>> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res)
>> + return -ENODEV;
>> +
>> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
>> + if (!dmamux->iomem)
>> + return -ENOMEM;
>> +
>> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
>> + if (IS_ERR(dmamux->clk)) {
>> + dev_err(&pdev->dev, "Missing controller clock\n");
>> + return PTR_ERR(dmamux->clk);
>> + }
>> + ret = clk_prepare(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
>> + sizeof(struct stm32_dmamux),
>> + GFP_KERNEL);
>> + if (!dmamux->muxes)
>> + return -ENOMEM;
>> +
>> + rst = devm_reset_control_get(&pdev->dev, NULL);
>> + if (!IS_ERR(rst)) {
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ret;
>> + }
>> + reset_control_assert(rst);
>> + udelay(2);
>> + reset_control_deassert(rst);
>> + clk_disable(dmamux->clk);
>> + }
>> +
>> + dmamux->dmarouter.dev = &pdev->dev;
>> + dmamux->dmarouter.route_free = stm32_dmamux_free;
>> + platform_set_drvdata(pdev, dmamux);
>> +
>> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
>> + &dmamux->dmarouter);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev,
>> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_dmamux_match[] = {
>> + { .compatible = "st,stm32-dmamux" },
>> + {},
>> +};
>> +
>> +static struct platform_driver stm32_dmamux_driver = {
>> + .probe = stm32_dmamux_probe,
>> + .driver = {
>> + .name = "stm32-dmamux",
>> + .of_match_table = stm32_dmamux_match,
>> + },
>> +};
>> +
>> +static int __init stm32_dmamux_init(void)
>> +{
>> + return platform_driver_register(&stm32_dmamux_driver);
>> +}
>> +arch_initcall(stm32_dmamux_init);
>
> why not module init, wouldnt defer probe solve the dependencies
>
The reason behind many devices (device_initcall level) rely on DMAs. If
init is deferred DMAMUX driver will be probed twice if dependents rely
on it. This sounds not a good call. This explains arch_initcall level.
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-04-26 9:17 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:17 UTC (permalink / raw)
To: linux-arm-kernel
On 04/06/2017 08:40 AM, Vinod Koul wrote:
> On Mon, Mar 13, 2017 at 03:15:58PM +0100, M'boumba Cedric Madianga wrote:
>> This patch implements the STM32 DMAMUX driver
>
> Can you describe the controller here pls
OK. Will be done in V2
>
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> drivers/dma/Kconfig | 9 ++
>> drivers/dma/Makefile | 1 +
>> drivers/dma/stm32-dmamux.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 241 insertions(+)
>> create mode 100644 drivers/dma/stm32-dmamux.c
>>
>> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
>> index fc3435c..6ab80c9 100644
>> --- a/drivers/dma/Kconfig
>> +++ b/drivers/dma/Kconfig
>> @@ -461,6 +461,15 @@ config STM32_DMA
>> If you have a board based on such a MCU and wish to use DMA say Y
>> here.
>>
>> +config STM32_DMAMUX
>> + bool "STMicroelectronics STM32 dma multiplexer support"
>> + depends on STM32_DMA
>
> can you add compile test here so that we can get better compile coverage
OK. Will be done in V2
>
>> + help
>> + Enable support for the on-chip DMA multiplexer on STMicroelectronics
>> + STM32 MCUs.
>> + If you have a board based on such a MCU and wish to use DMAMUX say Y
>> + here.
>> +
>> config S3C24XX_DMAC
>> bool "Samsung S3C24XX DMA support"
>> depends on ARCH_S3C24XX || COMPILE_TEST
>> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
>> index 0b723e9..449c7a3 100644
>> --- a/drivers/dma/Makefile
>> +++ b/drivers/dma/Makefile
>> @@ -57,6 +57,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
>> obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
>> obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
>> obj-$(CONFIG_STM32_DMA) += stm32-dma.o
>> +obj-$(CONFIG_STM32_DMAMUX) += stm32-dmamux.o
>> obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
>> obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
>> obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
>> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
>> new file mode 100644
>> index 0000000..3003546
>> --- /dev/null
>> +++ b/drivers/dma/stm32-dmamux.c
>> @@ -0,0 +1,231 @@
>> +/*
>> + * DMA Router driver for STM32 DMA MUX
>> + *
>> + * Copyright (C) 2015 M'Boumba Cedric Madianga <cedric.madianga@gmail.com>
>
> we are in '17 now :)
OK. Will be done in V2
>
>> + *
>> + * Based on LPC18xx/43xx DMA MUX and TI DMA XBAR
>> + *
>> + * 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/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_dma.h>
>> +#include <linux/reset.h>
>> +#include <linux/slab.h>
>> +
>> +#define STM32_DMAMUX_CCR(x) (0x4 * (x))
>> +#define STM32_DMAMUX_MAX_CHANNELS 32
>> +#define STM32_DMAMUX_MAX_REQUESTS 255
>> +
>> +struct stm32_dmamux {
>> + u32 chan_id;
>> + u32 request;
>> + bool busy;
>> +};
>> +
>> +struct stm32_dmamux_data {
>> + struct dma_router dmarouter;
>> + struct stm32_dmamux *muxes;
>> + struct clk *clk;
>> + void __iomem *iomem;
>> + u32 dmamux_requests; /* number of DMA requests connected to DMAMUX */
>> + u32 dmamux_channels; /* Number of DMA channels supported */
>> +};
>> +
>> +static inline u32 stm32_dmamux_read(void __iomem *iomem, u32 reg)
>> +{
>> + return readl_relaxed(iomem + reg);
>> +}
>> +
>> +static inline void stm32_dmamux_write(void __iomem *iomem, u32 reg, u32 val)
>> +{
>> + writel_relaxed(val, iomem + reg);
>> +}
>> +
>> +static void stm32_dmamux_free(struct device *dev, void *route_data)
>> +{
>> + struct stm32_dmamux_data *dmamux = dev_get_drvdata(dev);
>> + struct stm32_dmamux *mux = route_data;
>> +
>> + /* Clear dma request for the right channel */
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id), 0);
>> + clk_disable(dmamux->clk);
>> + mux->busy = false;
>> +
>> + dev_dbg(dev, "Unmapping dma-router%dchan%d (was routed to request%d)\n",
>> + dev->id, mux->chan_id, mux->request);
>> +}
>> +
>> +static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
>> + struct of_dma *ofdma)
>> +{
>> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
>> + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
>> + struct stm32_dmamux *mux;
>> + u32 chan_id;
>> + int ret;
>> +
>> + if (dma_spec->args_count != 4) {
>> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[0] >= dmamux->dmamux_channels) {
>> + dev_err(&pdev->dev, "invalid channel id: %d\n",
>> + dma_spec->args[0]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (dma_spec->args[1] > dmamux->dmamux_requests) {
>> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
>> + dma_spec->args[1]);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + /* The of_node_put() will be done in of_dma_router_xlate function */
>> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
>> + if (!dma_spec->np) {
>> + dev_err(&pdev->dev, "can't get dma master\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + chan_id = dma_spec->args[0];
>> + mux = &dmamux->muxes[chan_id];
>> + mux->chan_id = chan_id;
>> + mux->request = dma_spec->args[1];
>> +
>> + if (mux->busy) {
>> + dev_err(&pdev->dev, "dma channel %d busy with request %d\n",
>> + chan_id, mux->request);
>> + return ERR_PTR(-EBUSY);
>> + }
>> +
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + stm32_dmamux_write(dmamux->iomem, STM32_DMAMUX_CCR(mux->chan_id),
>> + mux->request);
>> + mux->busy = true;
>> +
>> + dev_dbg(&pdev->dev, "Mapping dma-router%dchan%d to request%d\n",
>> + pdev->dev.id, mux->chan_id, mux->request);
>> +
>> + return mux;
>> +}
>> +
>> +static int stm32_dmamux_probe(struct platform_device *pdev)
>> +{
>> + struct device_node *dma_node, *node = pdev->dev.of_node;
>> + struct stm32_dmamux_data *dmamux;
>> + struct reset_control *rst;
>> + struct resource *res;
>> + int ret;
>> +
>> + if (!node)
>> + return -ENODEV;
>> +
>> + dmamux = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dmamux_data),
>> + GFP_KERNEL);
>> + if (!dmamux)
>> + return -ENOMEM;
>> +
>> + dma_node = of_parse_phandle(node, "dma-masters", 0);
>> + if (!dma_node) {
>> + dev_err(&pdev->dev, "Can't get DMA master node\n");
>> + return -ENODEV;
>> + }
>> + of_node_put(dma_node);
>> +
>> + ret = of_property_read_u32(node, "dma-channels",
>> + &dmamux->dmamux_channels);
>
> can we have property_xxx calls alone, that way driver is not strictly
> dependent on of
Can you please explain what you are asking for ? Not sure to understand
correctly.
>
>> + if (ret)
>> + dmamux->dmamux_channels = STM32_DMAMUX_MAX_CHANNELS;
>> +
>> + ret = of_property_read_u32(node, "dma-requests",
>> + &dmamux->dmamux_requests);
>> + if (ret)
>> + dmamux->dmamux_requests = STM32_DMAMUX_MAX_REQUESTS;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res)
>> + return -ENODEV;
>> +
>> + dmamux->iomem = devm_ioremap_resource(&pdev->dev, res);
>> + if (!dmamux->iomem)
>> + return -ENOMEM;
>> +
>> + dmamux->clk = devm_clk_get(&pdev->dev, NULL);
>> + if (IS_ERR(dmamux->clk)) {
>> + dev_err(&pdev->dev, "Missing controller clock\n");
>> + return PTR_ERR(dmamux->clk);
>> + }
>> + ret = clk_prepare(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_prep failed: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dmamux->muxes = devm_kcalloc(&pdev->dev, dmamux->dmamux_channels,
>> + sizeof(struct stm32_dmamux),
>> + GFP_KERNEL);
>> + if (!dmamux->muxes)
>> + return -ENOMEM;
>> +
>> + rst = devm_reset_control_get(&pdev->dev, NULL);
>> + if (!IS_ERR(rst)) {
>> + ret = clk_enable(dmamux->clk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
>> + return ret;
>> + }
>> + reset_control_assert(rst);
>> + udelay(2);
>> + reset_control_deassert(rst);
>> + clk_disable(dmamux->clk);
>> + }
>> +
>> + dmamux->dmarouter.dev = &pdev->dev;
>> + dmamux->dmarouter.route_free = stm32_dmamux_free;
>> + platform_set_drvdata(pdev, dmamux);
>> +
>> + ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
>> + &dmamux->dmarouter);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev,
>> + "STM32 DMAMUX DMA OF registration failed %d\n", ret);
>> + return ret;
>> + }
>> +
>> + dev_info(&pdev->dev, "STM32 DMAMUX driver registered\n");
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_dmamux_match[] = {
>> + { .compatible = "st,stm32-dmamux" },
>> + {},
>> +};
>> +
>> +static struct platform_driver stm32_dmamux_driver = {
>> + .probe = stm32_dmamux_probe,
>> + .driver = {
>> + .name = "stm32-dmamux",
>> + .of_match_table = stm32_dmamux_match,
>> + },
>> +};
>> +
>> +static int __init stm32_dmamux_init(void)
>> +{
>> + return platform_driver_register(&stm32_dmamux_driver);
>> +}
>> +arch_initcall(stm32_dmamux_init);
>
> why not module init, wouldnt defer probe solve the dependencies
>
The reason behind many devices (device_initcall level) rely on DMAs. If
init is deferred DMAMUX driver will be probed twice if dependents rely
on it. This sounds not a good call. This explains arch_initcall level.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
2017-03-20 21:37 ` Rob Herring
(?)
@ 2017-04-26 9:23 ` Pierre Yves MORDRET
-1 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:23 UTC (permalink / raw)
To: Rob Herring, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, vinod.koul,
linux-kernel, mcoquelin.stm32, dmaengine, dan.j.williams,
linux-arm-kernel, Pierre Yves MORDRET
On 03/20/2017 10:37 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds an optional property needed for STM32 DMA controller
>> addressed via STM32 DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> index 4408af6..7b5e91a 100644
>> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> @@ -16,6 +16,9 @@ Optional properties:
>> - resets: Reference to a reset controller asserting the DMA controller
>> - st,mem2mem: boolean; if defined, it indicates that the controller supports
>> memory-to-memory transfer
>> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
>> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
>> + clients. They have to use dma-router instances.
>
> This should not be needed for the same reason we don't need anything
> like this for chained interrupt controllers.
>
> Also, the compatible string should be specific enough to provide this
> information.
>
> Rob
I don't understand what you're meant here. Our DMAs can work with or
without DMAMUX driver. Driver uses this binding to use it or not.
Py
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-04-26 9:23 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:23 UTC (permalink / raw)
To: Rob Herring, M'boumba Cedric Madianga
Cc: mark.rutland, devicetree, Alexandre TORGUE, vinod.koul,
linux-kernel, Pierre Yves MORDRET, mcoquelin.stm32, dmaengine,
dan.j.williams, linux-arm-kernel
On 03/20/2017 10:37 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds an optional property needed for STM32 DMA controller
>> addressed via STM32 DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> index 4408af6..7b5e91a 100644
>> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> @@ -16,6 +16,9 @@ Optional properties:
>> - resets: Reference to a reset controller asserting the DMA controller
>> - st,mem2mem: boolean; if defined, it indicates that the controller supports
>> memory-to-memory transfer
>> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
>> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
>> + clients. They have to use dma-router instances.
>
> This should not be needed for the same reason we don't need anything
> like this for chained interrupt controllers.
>
> Also, the compatible string should be specific enough to provide this
> information.
>
> Rob
I don't understand what you're meant here. Our DMAs can work with or
without DMAMUX driver. Driver uses this binding to use it or not.
Py
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX
@ 2017-04-26 9:23 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-04-26 9:23 UTC (permalink / raw)
To: linux-arm-kernel
On 03/20/2017 10:37 PM, Rob Herring wrote:
> On Mon, Mar 13, 2017 at 03:15:59PM +0100, M'boumba Cedric Madianga wrote:
>> This patch adds an optional property needed for STM32 DMA controller
>> addressed via STM32 DMAMUX.
>>
>> Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
>> ---
>> Documentation/devicetree/bindings/dma/stm32-dma.txt | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/dma/stm32-dma.txt b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> index 4408af6..7b5e91a 100644
>> --- a/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> +++ b/Documentation/devicetree/bindings/dma/stm32-dma.txt
>> @@ -16,6 +16,9 @@ Optional properties:
>> - resets: Reference to a reset controller asserting the DMA controller
>> - st,mem2mem: boolean; if defined, it indicates that the controller supports
>> memory-to-memory transfer
>> +- st,dmamux: boolean; if defined, it indicates that the controller is behind a
>> + DMA multiplexer. In that case, using dma instances doesn't work for DMA
>> + clients. They have to use dma-router instances.
>
> This should not be needed for the same reason we don't need anything
> like this for chained interrupt controllers.
>
> Also, the compatible string should be specific enough to provide this
> information.
>
> Rob
I don't understand what you're meant here. Our DMAs can work with or
without DMAMUX driver. Driver uses this binding to use it or not.
Py
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
2017-04-26 9:17 ` Pierre Yves MORDRET
(?)
@ 2017-05-01 6:03 ` Vinod Koul
-1 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-05-01 6:03 UTC (permalink / raw)
To: Pierre Yves MORDRET
Cc: M'boumba Cedric Madianga, mark.rutland, devicetree,
Alexandre TORGUE, linux-kernel, robh+dt, mcoquelin.stm32,
dmaengine, dan.j.williams, linux-arm-kernel
On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
> >> +
> >> + ret = of_property_read_u32(node, "dma-channels",
> >> + &dmamux->dmamux_channels);
> >
> > can we have property_xxx calls alone, that way driver is not strictly
> > dependent on of
>
> Can you please explain what you are asking for ? Not sure to understand
> correctly.
Use device_property_read_u32() which is a generic property API.
> >> +static int __init stm32_dmamux_init(void)
> >> +{
> >> + return platform_driver_register(&stm32_dmamux_driver);
> >> +}
> >> +arch_initcall(stm32_dmamux_init);
> >
> > why not module init, wouldnt defer probe solve the dependencies
> >
>
> The reason behind many devices (device_initcall level) rely on DMAs. If
> init is deferred DMAMUX driver will be probed twice if dependents rely
> on it. This sounds not a good call. This explains arch_initcall level.
Why not deferred probe was introduced to help with dependencies...
--
~Vinod
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-05-01 6:03 ` Vinod Koul
0 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-05-01 6:03 UTC (permalink / raw)
To: Pierre Yves MORDRET
Cc: M'boumba Cedric Madianga, mark.rutland, devicetree,
Alexandre TORGUE, linux-kernel, robh+dt, mcoquelin.stm32,
dmaengine, dan.j.williams, linux-arm-kernel
On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
> >> +
> >> + ret = of_property_read_u32(node, "dma-channels",
> >> + &dmamux->dmamux_channels);
> >
> > can we have property_xxx calls alone, that way driver is not strictly
> > dependent on of
>
> Can you please explain what you are asking for ? Not sure to understand
> correctly.
Use device_property_read_u32() which is a generic property API.
> >> +static int __init stm32_dmamux_init(void)
> >> +{
> >> + return platform_driver_register(&stm32_dmamux_driver);
> >> +}
> >> +arch_initcall(stm32_dmamux_init);
> >
> > why not module init, wouldnt defer probe solve the dependencies
> >
>
> The reason behind many devices (device_initcall level) rely on DMAs. If
> init is deferred DMAMUX driver will be probed twice if dependents rely
> on it. This sounds not a good call. This explains arch_initcall level.
Why not deferred probe was introduced to help with dependencies...
--
~Vinod
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-05-01 6:03 ` Vinod Koul
0 siblings, 0 replies; 40+ messages in thread
From: Vinod Koul @ 2017-05-01 6:03 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
> >> +
> >> + ret = of_property_read_u32(node, "dma-channels",
> >> + &dmamux->dmamux_channels);
> >
> > can we have property_xxx calls alone, that way driver is not strictly
> > dependent on of
>
> Can you please explain what you are asking for ? Not sure to understand
> correctly.
Use device_property_read_u32() which is a generic property API.
> >> +static int __init stm32_dmamux_init(void)
> >> +{
> >> + return platform_driver_register(&stm32_dmamux_driver);
> >> +}
> >> +arch_initcall(stm32_dmamux_init);
> >
> > why not module init, wouldnt defer probe solve the dependencies
> >
>
> The reason behind many devices (device_initcall level) rely on DMAs. If
> init is deferred DMAMUX driver will be probed twice if dependents rely
> on it. This sounds not a good call. This explains arch_initcall level.
Why not deferred probe was introduced to help with dependencies...
--
~Vinod
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
2017-05-01 6:03 ` Vinod Koul
(?)
@ 2017-05-04 15:28 ` Pierre Yves MORDRET
-1 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-05-04 15:28 UTC (permalink / raw)
To: Vinod Koul
Cc: M'boumba Cedric Madianga, mark.rutland, devicetree,
Alexandre TORGUE, linux-kernel, robh+dt, mcoquelin.stm32,
dmaengine, dan.j.williams, linux-arm-kernel
On 05/01/2017 08:03 AM, Vinod Koul wrote:
> On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
>>>> +
>>>> + ret = of_property_read_u32(node, "dma-channels",
>>>> + &dmamux->dmamux_channels);
>>>
>>> can we have property_xxx calls alone, that way driver is not strictly
>>> dependent on of
>>
>> Can you please explain what you are asking for ? Not sure to understand
>> correctly.
>
> Use device_property_read_u32() which is a generic property API.
OK Will be done in V2
>
>
>>>> +static int __init stm32_dmamux_init(void)
>>>> +{
>>>> + return platform_driver_register(&stm32_dmamux_driver);
>>>> +}
>>>> +arch_initcall(stm32_dmamux_init);
>>>
>>> why not module init, wouldnt defer probe solve the dependencies
>>>
>>
>> The reason behind many devices (device_initcall level) rely on DMAs. If
>> init is deferred DMAMUX driver will be probed twice if dependents rely
>> on it. This sounds not a good call. This explains arch_initcall level.
>
> Why not deferred probe was introduced to help with dependencies...
>
Most DMAs devices are already in subsys_initcall to avoid multiple
useless probe when clients are deferred. This DMAMUx is itself on top of
DMAs.
DMAMUX ---> DMA#1 ---> Device Client #1
| |--> Device Client #2
| [...]
| |--> Device Client #N
| [...]
|--> DMA#N ---> Device Client #1
|--> Device Client #2
[...]
|--> Device Client #N
arch_initcall might a good call in this case for DMAMUX.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-05-04 15:28 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-05-04 15:28 UTC (permalink / raw)
To: Vinod Koul
Cc: M'boumba Cedric Madianga, mark.rutland, devicetree,
Alexandre TORGUE, linux-kernel, robh+dt, mcoquelin.stm32,
dmaengine, dan.j.williams, linux-arm-kernel
On 05/01/2017 08:03 AM, Vinod Koul wrote:
> On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
>>>> +
>>>> + ret = of_property_read_u32(node, "dma-channels",
>>>> + &dmamux->dmamux_channels);
>>>
>>> can we have property_xxx calls alone, that way driver is not strictly
>>> dependent on of
>>
>> Can you please explain what you are asking for ? Not sure to understand
>> correctly.
>
> Use device_property_read_u32() which is a generic property API.
OK Will be done in V2
>
>
>>>> +static int __init stm32_dmamux_init(void)
>>>> +{
>>>> + return platform_driver_register(&stm32_dmamux_driver);
>>>> +}
>>>> +arch_initcall(stm32_dmamux_init);
>>>
>>> why not module init, wouldnt defer probe solve the dependencies
>>>
>>
>> The reason behind many devices (device_initcall level) rely on DMAs. If
>> init is deferred DMAMUX driver will be probed twice if dependents rely
>> on it. This sounds not a good call. This explains arch_initcall level.
>
> Why not deferred probe was introduced to help with dependencies...
>
Most DMAs devices are already in subsys_initcall to avoid multiple
useless probe when clients are deferred. This DMAMUx is itself on top of
DMAs.
DMAMUX ---> DMA#1 ---> Device Client #1
| |--> Device Client #2
| [...]
| |--> Device Client #N
| [...]
|--> DMA#N ---> Device Client #1
|--> Device Client #2
[...]
|--> Device Client #N
arch_initcall might a good call in this case for DMAMUX.
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver
@ 2017-05-04 15:28 ` Pierre Yves MORDRET
0 siblings, 0 replies; 40+ messages in thread
From: Pierre Yves MORDRET @ 2017-05-04 15:28 UTC (permalink / raw)
To: linux-arm-kernel
On 05/01/2017 08:03 AM, Vinod Koul wrote:
> On Wed, Apr 26, 2017 at 09:17:37AM +0000, Pierre Yves MORDRET wrote:
>>>> +
>>>> + ret = of_property_read_u32(node, "dma-channels",
>>>> + &dmamux->dmamux_channels);
>>>
>>> can we have property_xxx calls alone, that way driver is not strictly
>>> dependent on of
>>
>> Can you please explain what you are asking for ? Not sure to understand
>> correctly.
>
> Use device_property_read_u32() which is a generic property API.
OK Will be done in V2
>
>
>>>> +static int __init stm32_dmamux_init(void)
>>>> +{
>>>> + return platform_driver_register(&stm32_dmamux_driver);
>>>> +}
>>>> +arch_initcall(stm32_dmamux_init);
>>>
>>> why not module init, wouldnt defer probe solve the dependencies
>>>
>>
>> The reason behind many devices (device_initcall level) rely on DMAs. If
>> init is deferred DMAMUX driver will be probed twice if dependents rely
>> on it. This sounds not a good call. This explains arch_initcall level.
>
> Why not deferred probe was introduced to help with dependencies...
>
Most DMAs devices are already in subsys_initcall to avoid multiple
useless probe when clients are deferred. This DMAMUx is itself on top of
DMAs.
DMAMUX ---> DMA#1 ---> Device Client #1
| |--> Device Client #2
| [...]
| |--> Device Client #N
| [...]
|--> DMA#N ---> Device Client #1
|--> Device Client #2
[...]
|--> Device Client #N
arch_initcall might a good call in this case for DMAMUX.
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2017-05-04 15:29 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-13 14:15 [PATCH 0/5] Add STM32 DMAMUX support M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-13 14:15 ` [PATCH 1/5] dt-bindings: Document the STM32 DMAMUX bindings M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-20 21:34 ` Rob Herring
2017-03-20 21:34 ` Rob Herring
2017-03-20 21:34 ` Rob Herring
2017-04-26 8:58 ` Pierre Yves MORDRET
2017-04-26 8:58 ` Pierre Yves MORDRET
2017-04-26 8:58 ` Pierre Yves MORDRET
2017-03-13 14:15 ` [PATCH 2/5] dmaengine: Add STM32 DMAMUX driver M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-04-06 6:40 ` Vinod Koul
2017-04-06 6:40 ` Vinod Koul
2017-04-06 6:40 ` Vinod Koul
2017-04-26 9:17 ` Pierre Yves MORDRET
2017-04-26 9:17 ` Pierre Yves MORDRET
2017-04-26 9:17 ` Pierre Yves MORDRET
2017-05-01 6:03 ` Vinod Koul
2017-05-01 6:03 ` Vinod Koul
2017-05-01 6:03 ` Vinod Koul
2017-05-04 15:28 ` Pierre Yves MORDRET
2017-05-04 15:28 ` Pierre Yves MORDRET
2017-05-04 15:28 ` Pierre Yves MORDRET
2017-03-13 14:15 ` [PATCH 3/5] dt-bindings: stm32-dma: Add property to handle STM32 DMAMUX M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-13 14:15 ` M'boumba Cedric Madianga
2017-03-20 21:37 ` Rob Herring
2017-03-20 21:37 ` Rob Herring
2017-03-20 21:37 ` Rob Herring
2017-04-26 9:23 ` Pierre Yves MORDRET
2017-04-26 9:23 ` Pierre Yves MORDRET
2017-04-26 9:23 ` Pierre Yves MORDRET
2017-03-13 14:16 ` [PATCH 4/5] dmaengine: stm32-dma: Add support for " M'boumba Cedric Madianga
2017-03-13 14:16 ` M'boumba Cedric Madianga
2017-03-13 14:16 ` M'boumba Cedric Madianga
2017-03-13 14:16 ` [PATCH 5/5] ARM: configs: stm32: Add DMAMUX support in STM32 defconfig M'boumba Cedric Madianga
2017-03-13 14:16 ` M'boumba Cedric Madianga
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.