* Re: [PATCH -next] input: keyboard: remove duplicated include from mtk-pmic-keys.c
From: YueHaibing @ 2018-12-10 7:16 UTC (permalink / raw)
To: Lee Jones
Cc: dmitry.torokhov, linux-kernel, linux-mediatek, linux-input,
matthias.bgg, chen.zhong, linux-arm-kernel
In-Reply-To: <20181210061557.GL26661@dell>
On 2018/12/10 14:15, Lee Jones wrote:
> On Sun, 09 Dec 2018, YueHaibing wrote:
>
>> Remove duplicated include.
>>
>> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
>> ---
>> drivers/input/keyboard/mtk-pmic-keys.c | 1 -
>> 1 file changed, 1 deletion(-)
>>
>> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
>> index 02c67a1..5027ebb 100644
>> --- a/drivers/input/keyboard/mtk-pmic-keys.c
>> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
>> @@ -19,7 +19,6 @@
>> #include <linux/input.h>
>> #include <linux/interrupt.h>
>> #include <linux/platform_device.h>
>> -#include <linux/kernel.h>
>> #include <linux/of.h>
>> #include <linux/of_device.h>
>> #include <linux/regmap.h>
>
> You are removing the wrong one.
No, linux/kernel.h is a duplicated include indeed.
>
> Please convert this patch's main intent to alphabetise the header
> files. Then you can remove any obvious duplicates.
I can alphabetize it in v2 if need be.
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [resend PATCH v4 2/2] arm: dts: mt2712: add uart APDMA to device tree
From: Long Cheng @ 2018-12-10 3:47 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland, Ryder Lee
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In-Reply-To: <1544413665-1222-1-git-send-email-long.cheng@mediatek.com>
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function
Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 50 +++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 10
+ &apdma 11>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -378,6 +381,38 @@
status = "disabled";
};
+ apdma: dma-controller@11000400 {
+ compatible = "mediatek,mt2712-uart-dma",
+ "mediatek,mt6577-uart-dma";
+ reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_AP_DMA>;
+ clock-names = "apdma";
+ #dma-cells = <1>;
+ };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
"mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 0
+ &apdma 1>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -395,6 +433,9 @@
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 2
+ &apdma 3>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -405,6 +446,9 @@
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 4
+ &apdma 5>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -415,6 +459,9 @@
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 6
+ &apdma 7>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -629,6 +676,9 @@
interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 8
+ &apdma 9>;
+ dma-names = "tx", "rx";
status = "disabled";
};
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [resend PATCH v4 0/2] add uart DMA function
From: Long Cheng @ 2018-12-10 3:47 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland, Ryder Lee
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the code under drivers/dma.
This series contains document bindings, Kconfig to control the function enable or not,
device tree including interrupt and dma device node, the code of UART DM
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation
Long Cheng (2):
dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
arm: dts: mt2712: add uart APDMA to device tree
arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 50 ++
drivers/dma/mediatek/8250_mtk_dma.c | 830 +++++++++++++++++++++++++++++
drivers/dma/mediatek/Kconfig | 11 +
drivers/dma/mediatek/Makefile | 1 +
4 files changed, 892 insertions(+)
create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [resend PATCH v4 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
From: Long Cheng @ 2018-12-10 3:47 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland, Ryder Lee
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In-Reply-To: <1544413665-1222-1-git-send-email-long.cheng@mediatek.com>
In DMA engine framework, add 8250 mtk dma to support it.
Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
drivers/dma/mediatek/8250_mtk_dma.c | 830 +++++++++++++++++++++++++++++++++++
drivers/dma/mediatek/Kconfig | 11 +
drivers/dma/mediatek/Makefile | 1 +
3 files changed, 842 insertions(+)
create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
diff --git a/drivers/dma/mediatek/8250_mtk_dma.c b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 0000000..f79d180
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng <long.cheng@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_B BIT(0)
+#define VFF_4G_SUPPORT_B BIT(0)
+#define VFF_RX_INT_EN0_B BIT(0) /*rx valid size >= vff thre*/
+#define VFF_RX_INT_EN1_B BIT(1)
+#define VFF_TX_INT_EN_B BIT(0) /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B 0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B 0
+#define VFF_INT_EN_CLR_B 0
+#define VFF_4G_SUPPORT_CLR_B 0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE 0xffffU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP 0x10000U
+
+#define VFF_INT_FLAG 0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST 0x0c
+#define VFF_STOP 0x10
+#define VFF_FLUSH 0x14
+#define VFF_ADDR 0x1c
+#define VFF_LEN 0x24
+#define VFF_THRE 0x28
+#define VFF_WPT 0x2c
+#define VFF_RPT 0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE 0x40
+#define VFF_DEBUG_STATUS 0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+ struct dma_device ddev;
+ void __iomem *mem_base[MTK_APDMA_CHANNELS];
+ spinlock_t lock; /* dma dev lock */
+ struct tasklet_struct task;
+ struct list_head pending;
+ struct clk *clk;
+ unsigned int dma_requests;
+ bool support_33bits;
+ unsigned int dma_irq[MTK_APDMA_CHANNELS];
+ struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+ struct virt_dma_chan vc;
+ struct list_head node;
+ struct dma_slave_config cfg;
+ void __iomem *base;
+ struct mtk_dma_desc *desc;
+
+ bool stop;
+ bool requested;
+
+ unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+ dma_addr_t addr;
+ unsigned int en; /* number of elements (24-bit) */
+ unsigned int fn; /* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+ struct virt_dma_desc vd;
+ enum dma_transfer_direction dir;
+
+ unsigned int sglen;
+ struct mtk_dma_sg sg[0];
+
+ unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+ return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+ (struct dma_async_tx_descriptor *t)
+{
+ return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+ unsigned int reg, unsigned int val)
+{
+ writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+ return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+ struct dma_chan *chan = vd->tx.chan;
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ kfree(c->desc);
+ c->desc = NULL;
+}
+
+static void mtk_dma_tx_flush(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ if (mtk_dma_chan_read(c, VFF_FLUSH) == 0U)
+ mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_dma_tx_write(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned int txcount = c->desc->len;
+ unsigned int len, send, left, wpt, wrap;
+
+ len = mtk_dma_chan_read(c, VFF_LEN);
+
+ while ((left = mtk_dma_chan_read(c, VFF_LEFT_SIZE)) > 0U) {
+ if (c->desc->len == 0U)
+ break;
+ send = min_t(unsigned int, left, c->desc->len);
+ wpt = mtk_dma_chan_read(c, VFF_WPT);
+ wrap = wpt & MTK_DMA_RING_WRAP ? 0U : MTK_DMA_RING_WRAP;
+
+ if ((wpt & (len - 1U)) + send < len)
+ mtk_dma_chan_write(c, VFF_WPT, wpt + send);
+ else
+ mtk_dma_chan_write(c, VFF_WPT,
+ ((wpt + send) & (len - 1U))
+ | wrap);
+
+ c->desc->len -= send;
+ }
+
+ if (txcount != c->desc->len) {
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+ mtk_dma_tx_flush(chan);
+ }
+}
+
+static void mtk_dma_start_tx(struct mtk_chan *c)
+{
+ if (mtk_dma_chan_read(c, VFF_LEFT_SIZE) == 0U)
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+ else
+ mtk_dma_tx_write(&c->vc.chan);
+
+ c->stop = false;
+}
+
+static void mtk_dma_get_rx_size(struct mtk_chan *c)
+{
+ unsigned int rx_size = mtk_dma_chan_read(c, VFF_LEN);
+ unsigned int rdptr, wrptr, wrreg, rdreg, count;
+
+ rdreg = mtk_dma_chan_read(c, VFF_RPT);
+ wrreg = mtk_dma_chan_read(c, VFF_WPT);
+ rdptr = rdreg & MTK_DMA_RING_SIZE;
+ wrptr = wrreg & MTK_DMA_RING_SIZE;
+ count = ((rdreg ^ wrreg) & MTK_DMA_RING_WRAP) ?
+ (wrptr + rx_size - rdptr) : (wrptr - rdptr);
+
+ c->rx_status = count;
+
+ mtk_dma_chan_write(c, VFF_RPT, wrreg);
+}
+
+static void mtk_dma_start_rx(struct mtk_chan *c)
+{
+ struct dma_chan *chan = &c->vc.chan;
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_dma_desc *d = c->desc;
+
+ if (mtk_dma_chan_read(c, VFF_VALID_SIZE) == 0U)
+ return;
+
+ if (d && vchan_next_desc(&c->vc)) {
+ mtk_dma_get_rx_size(c);
+ list_del(&d->vd.node);
+ vchan_cookie_complete(&d->vd);
+ } else {
+ spin_lock(&mtkd->lock);
+ if (list_empty(&mtkd->pending))
+ list_add_tail(&c->node, &mtkd->pending);
+ spin_unlock(&mtkd->lock);
+ tasklet_schedule(&mtkd->task);
+ }
+}
+
+static void mtk_dma_reset(struct mtk_chan *c)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(c->vc.chan.device);
+ u32 status;
+ int ret;
+
+ mtk_dma_chan_write(c, VFF_ADDR, 0);
+ mtk_dma_chan_write(c, VFF_THRE, 0);
+ mtk_dma_chan_write(c, VFF_LEN, 0);
+ mtk_dma_chan_write(c, VFF_RST, VFF_WARM_RST_B);
+
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_EN,
+ status, status == 0, 10, 100);
+ if (ret) {
+ dev_err(c->vc.chan.device->dev,
+ "dma reset: fail, timeout\n");
+ return;
+ }
+
+ if (c->cfg.direction == DMA_DEV_TO_MEM)
+ mtk_dma_chan_write(c, VFF_RPT, 0);
+ else if (c->cfg.direction == DMA_MEM_TO_DEV)
+ mtk_dma_chan_write(c, VFF_WPT, 0);
+
+ if (mtkd->support_33bits)
+ mtk_dma_chan_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
+}
+
+static void mtk_dma_stop(struct mtk_chan *c)
+{
+ u32 status;
+ int ret;
+
+ mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_CLR_B);
+ /* Wait for flush */
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_FLUSH,
+ status,
+ (status & VFF_FLUSH_B) != VFF_FLUSH_B,
+ 10, 100);
+ if (ret)
+ dev_err(c->vc.chan.device->dev,
+ "dma stop: polling FLUSH fail, DEBUG=0x%x\n",
+ mtk_dma_chan_read(c, VFF_DEBUG_STATUS));
+
+ /*set stop as 1 -> wait until en is 0 -> set stop as 0*/
+ mtk_dma_chan_write(c, VFF_STOP, VFF_STOP_B);
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_EN,
+ status, status == 0, 10, 100);
+ if (ret)
+ dev_err(c->vc.chan.device->dev,
+ "dma stop: polling VFF_EN fail, DEBUG=0x%x\n",
+ mtk_dma_chan_read(c, VFF_DEBUG_STATUS));
+
+ mtk_dma_chan_write(c, VFF_STOP, VFF_STOP_CLR_B);
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
+
+ if (c->cfg.direction == DMA_DEV_TO_MEM)
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+ else
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+ c->stop = true;
+}
+
+/*
+ * This callback schedules all pending channels. We could be more
+ * clever here by postponing allocation of the real DMA channels to
+ * this point, and freeing them when our virtual channel becomes idle.
+ *
+ * We would then need to deal with 'all channels in-use'
+ */
+static void mtk_dma_sched(unsigned long data)
+{
+ struct mtk_dmadev *mtkd = (struct mtk_dmadev *)data;
+ struct virt_dma_desc *vd;
+ struct mtk_chan *c;
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irq(&mtkd->lock);
+ list_splice_tail_init(&mtkd->pending, &head);
+ spin_unlock_irq(&mtkd->lock);
+
+ if (!list_empty(&head)) {
+ c = list_first_entry(&head, struct mtk_chan, node);
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->cfg.direction == DMA_DEV_TO_MEM) {
+ list_del_init(&c->node);
+ mtk_dma_start_rx(c);
+ } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ list_del_init(&c->node);
+ mtk_dma_start_tx(c);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+ }
+}
+
+static int mtk_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ int ret = -EBUSY;
+
+ pm_runtime_get_sync(mtkd->ddev.dev);
+
+ if (!mtkd->ch[chan->chan_id]) {
+ c->base = mtkd->mem_base[chan->chan_id];
+ mtkd->ch[chan->chan_id] = c;
+ ret = 1;
+ }
+ c->requested = false;
+ mtk_dma_reset(c);
+
+ return ret;
+}
+
+static void mtk_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ if (c->requested) {
+ c->requested = false;
+ free_irq(mtkd->dma_irq[chan->chan_id], chan);
+ }
+
+ tasklet_kill(&mtkd->task);
+ tasklet_kill(&c->vc.task);
+
+ c->base = NULL;
+ mtkd->ch[chan->chan_id] = NULL;
+ vchan_free_chan_resources(&c->vc);
+
+ pm_runtime_put_sync(mtkd->ddev.dev);
+}
+
+static enum dma_status mtk_dma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ enum dma_status ret;
+ unsigned long flags;
+
+ if (!txstate)
+ return DMA_ERROR;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (ret == DMA_IN_PROGRESS) {
+ c->rx_status = mtk_dma_chan_read(c, VFF_RPT)
+ & MTK_DMA_RING_SIZE;
+ dma_set_residue(txstate, c->rx_status);
+ } else if (ret == DMA_COMPLETE && c->cfg.direction == DMA_DEV_TO_MEM) {
+ dma_set_residue(txstate, c->rx_status);
+ } else {
+ dma_set_residue(txstate, 0);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *mtk_dma_prep_slave_sg
+ (struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sglen, enum dma_transfer_direction dir,
+ unsigned long tx_flags, void *context)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct scatterlist *sgent;
+ struct mtk_dma_desc *d;
+ struct mtk_dma_sg *sg;
+ unsigned int size, i, j, en;
+
+ en = 1;
+
+ if ((dir != DMA_DEV_TO_MEM) &&
+ (dir != DMA_MEM_TO_DEV)) {
+ dev_err(chan->device->dev, "bad direction\n");
+ return NULL;
+ }
+
+ /* Now allocate and setup the descriptor. */
+ d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
+ if (!d)
+ return NULL;
+
+ d->dir = dir;
+
+ j = 0;
+ for_each_sg(sgl, sgent, sglen, i) {
+ d->sg[j].addr = sg_dma_address(sgent);
+ d->sg[j].en = en;
+ d->sg[j].fn = sg_dma_len(sgent) / en;
+ j++;
+ }
+
+ d->sglen = j;
+
+ if (dir == DMA_MEM_TO_DEV) {
+ for (size = i = 0; i < d->sglen; i++) {
+ sg = &d->sg[i];
+ size += sg->en * sg->fn;
+ }
+ d->len = size;
+ }
+
+ return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
+}
+
+static void mtk_dma_issue_pending(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct virt_dma_desc *vd;
+ struct mtk_dmadev *mtkd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->cfg.direction == DMA_DEV_TO_MEM) {
+ mtkd = to_mtk_dma_dev(chan->device);
+ if (vchan_issue_pending(&c->vc) && !c->desc) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ }
+ } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+ if (vchan_issue_pending(&c->vc) && !c->desc) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ mtk_dma_start_tx(c);
+ }
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+}
+
+static irqreturn_t mtk_dma_rx_interrupt(int irq, void *dev_id)
+{
+ struct dma_chan *chan = (struct dma_chan *)dev_id;
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+
+ mtk_dma_start_rx(c);
+
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dma_tx_interrupt(int irq, void *dev_id)
+{
+ struct dma_chan *chan = (struct dma_chan *)dev_id;
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct mtk_dma_desc *d = c->desc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (d->len != 0U) {
+ list_add_tail(&c->node, &mtkd->pending);
+ tasklet_schedule(&mtkd->task);
+ } else {
+ list_del(&d->vd.node);
+ vchan_cookie_complete(&d->vd);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+ return IRQ_HANDLED;
+}
+
+static int mtk_dma_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(c->vc.chan.device);
+ int ret;
+
+ c->cfg = *cfg;
+
+ if (cfg->direction == DMA_DEV_TO_MEM) {
+ unsigned int rx_len = cfg->src_addr_width * 1024;
+
+ mtk_dma_chan_write(c, VFF_ADDR, cfg->src_addr);
+ mtk_dma_chan_write(c, VFF_LEN, rx_len);
+ mtk_dma_chan_write(c, VFF_THRE, VFF_RX_THRE(rx_len));
+ mtk_dma_chan_write(c,
+ VFF_INT_EN, VFF_RX_INT_EN0_B
+ | VFF_RX_INT_EN1_B);
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+ mtk_dma_chan_write(c, VFF_EN, VFF_EN_B);
+
+ if (!c->requested) {
+ c->requested = true;
+ ret = request_irq(mtkd->dma_irq[chan->chan_id],
+ mtk_dma_rx_interrupt,
+ IRQF_TRIGGER_NONE,
+ KBUILD_MODNAME, chan);
+ if (ret < 0) {
+ dev_err(chan->device->dev, "Can't request rx dma IRQ\n");
+ return -EINVAL;
+ }
+ }
+ } else if (cfg->direction == DMA_MEM_TO_DEV) {
+ unsigned int tx_len = cfg->dst_addr_width * 1024;
+
+ mtk_dma_chan_write(c, VFF_ADDR, cfg->dst_addr);
+ mtk_dma_chan_write(c, VFF_LEN, tx_len);
+ mtk_dma_chan_write(c, VFF_THRE, VFF_TX_THRE(tx_len));
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+ mtk_dma_chan_write(c, VFF_EN, VFF_EN_B);
+
+ if (!c->requested) {
+ c->requested = true;
+ ret = request_irq(mtkd->dma_irq[chan->chan_id],
+ mtk_dma_tx_interrupt,
+ IRQF_TRIGGER_NONE,
+ KBUILD_MODNAME, chan);
+ if (ret < 0) {
+ dev_err(chan->device->dev, "Can't request tx dma IRQ\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (mtkd->support_33bits)
+ mtk_dma_chan_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_B);
+
+ if (mtk_dma_chan_read(c, VFF_EN) != VFF_EN_B) {
+ dev_err(chan->device->dev,
+ "config dma dir[%d] fail\n", cfg->direction);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_dma_terminate_all(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ list_del_init(&c->node);
+ mtk_dma_stop(c);
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return 0;
+}
+
+static int mtk_dma_device_pause(struct dma_chan *chan)
+{
+ /* just for check caps pass */
+ return -EINVAL;
+}
+
+static int mtk_dma_device_resume(struct dma_chan *chan)
+{
+ /* just for check caps pass */
+ return -EINVAL;
+}
+
+static void mtk_dma_free(struct mtk_dmadev *mtkd)
+{
+ tasklet_kill(&mtkd->task);
+ while (list_empty(&mtkd->ddev.channels) == 0) {
+ struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels,
+ struct mtk_chan, vc.chan.device_node);
+
+ list_del(&c->vc.chan.device_node);
+ tasklet_kill(&c->vc.task);
+ devm_kfree(mtkd->ddev.dev, c);
+ }
+}
+
+static const struct of_device_id mtk_uart_dma_match[] = {
+ { .compatible = "mediatek,mt6577-uart-dma", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_uart_dma_match);
+
+static int mtk_apdma_probe(struct platform_device *pdev)
+{
+ struct mtk_dmadev *mtkd;
+ struct resource *res;
+ struct mtk_chan *c;
+ unsigned int i;
+ int rc;
+
+ mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL);
+ if (!mtkd)
+ return -ENOMEM;
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ return -ENODEV;
+ mtkd->mem_base[i] = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mtkd->mem_base[i]))
+ return PTR_ERR(mtkd->mem_base[i]);
+ }
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ mtkd->dma_irq[i] = platform_get_irq(pdev, i);
+ if ((int)mtkd->dma_irq[i] < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i);
+ return -EINVAL;
+ }
+ }
+
+ mtkd->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(mtkd->clk)) {
+ dev_err(&pdev->dev, "No clock specified\n");
+ return PTR_ERR(mtkd->clk);
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) {
+ dev_info(&pdev->dev, "Support dma 33bits\n");
+ mtkd->support_33bits = true;
+ }
+
+ if (mtkd->support_33bits)
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
+ else
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (rc)
+ return rc;
+
+ dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask);
+ mtkd->ddev.device_alloc_chan_resources = mtk_dma_alloc_chan_resources;
+ mtkd->ddev.device_free_chan_resources = mtk_dma_free_chan_resources;
+ mtkd->ddev.device_tx_status = mtk_dma_tx_status;
+ mtkd->ddev.device_issue_pending = mtk_dma_issue_pending;
+ mtkd->ddev.device_prep_slave_sg = mtk_dma_prep_slave_sg;
+ mtkd->ddev.device_config = mtk_dma_slave_config;
+ mtkd->ddev.device_pause = mtk_dma_device_pause;
+ mtkd->ddev.device_resume = mtk_dma_device_resume;
+ mtkd->ddev.device_terminate_all = mtk_dma_terminate_all;
+ mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+ mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+ mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+ mtkd->ddev.dev = &pdev->dev;
+ INIT_LIST_HEAD(&mtkd->ddev.channels);
+ INIT_LIST_HEAD(&mtkd->pending);
+
+ spin_lock_init(&mtkd->lock);
+ tasklet_init(&mtkd->task, mtk_dma_sched, (unsigned long)mtkd);
+
+ mtkd->dma_requests = MTK_APDMA_DEFAULT_REQUESTS;
+ if (of_property_read_u32(pdev->dev.of_node,
+ "dma-requests", &mtkd->dma_requests)) {
+ dev_info(&pdev->dev,
+ "Missing dma-requests property, using %u.\n",
+ MTK_APDMA_DEFAULT_REQUESTS);
+ }
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL);
+ if (!c)
+ goto err_no_dma;
+
+ c->vc.desc_free = mtk_dma_desc_free;
+ vchan_init(&c->vc, &mtkd->ddev);
+ INIT_LIST_HEAD(&c->node);
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+
+ rc = dma_async_device_register(&mtkd->ddev);
+ if (rc)
+ goto rpm_disable;
+
+ platform_set_drvdata(pdev, mtkd);
+
+ if (pdev->dev.of_node) {
+ /* Device-tree DMA controller registration */
+ rc = of_dma_controller_register(pdev->dev.of_node,
+ of_dma_xlate_by_chan_id,
+ mtkd);
+ if (rc)
+ goto dma_remove;
+ }
+
+ return rc;
+
+dma_remove:
+ dma_async_device_unregister(&mtkd->ddev);
+rpm_disable:
+ pm_runtime_disable(&pdev->dev);
+err_no_dma:
+ mtk_dma_free(mtkd);
+ return rc;
+}
+
+static int mtk_apdma_remove(struct platform_device *pdev)
+{
+ struct mtk_dmadev *mtkd = platform_get_drvdata(pdev);
+
+ if (pdev->dev.of_node)
+ of_dma_controller_free(pdev->dev.of_node);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
+ dma_async_device_unregister(&mtkd->ddev);
+
+ mtk_dma_free(mtkd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dma_suspend(struct device *dev)
+{
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ if (!pm_runtime_suspended(dev))
+ clk_disable_unprepare(mtkd->clk);
+
+ return 0;
+}
+
+static int mtk_dma_resume(struct device *dev)
+{
+ int ret;
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ if (!pm_runtime_suspended(dev)) {
+ ret = clk_prepare_enable(mtkd->clk);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int mtk_dma_runtime_suspend(struct device *dev)
+{
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(mtkd->clk);
+
+ return 0;
+}
+
+static int mtk_dma_runtime_resume(struct device *dev)
+{
+ int ret;
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ ret = clk_prepare_enable(mtkd->clk);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_dma_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mtk_dma_suspend, mtk_dma_resume)
+ SET_RUNTIME_PM_OPS(mtk_dma_runtime_suspend,
+ mtk_dma_runtime_resume, NULL)
+};
+
+static struct platform_driver mtk_dma_driver = {
+ .probe = mtk_apdma_probe,
+ .remove = mtk_apdma_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .pm = &mtk_dma_pm_ops,
+ .of_match_table = of_match_ptr(mtk_uart_dma_match),
+ },
+};
+
+module_platform_driver(mtk_dma_driver);
+
+MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");
+MODULE_AUTHOR("Long Cheng <long.cheng@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 27bac0b..bef436e 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -1,4 +1,15 @@
+config DMA_MTK_UART
+ tristate "MediaTek SoCs APDMA support for UART"
+ depends on OF
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ when 8250 mtk uart is enabled, and if you want to using DMA,
+ you can enable the config. the DMA engine just only be used
+ with MediaTek Socs.
+
config MTK_HSDMA
tristate "MediaTek High-Speed DMA controller support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 6e778f8..2f2efd9 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_DMA_MTK_UART) += 8250_mtk_dma.o
obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v6 8/8] mfd: axp20x: Add supported cells for AXP803
From: Lee Jones @ 2018-12-10 6:27 UTC (permalink / raw)
To: Oskari Lemmela
Cc: Mark Rutland, devicetree, Quentin Schulz, linux-pm, Maxime Ripard,
Sebastian Reichel, linux-kernel, Vasily Khoruzhick, Chen-Yu Tsai,
Rob Herring, linux-arm-kernel
In-Reply-To: <20181120175211.3913-9-oskari@lemmela.net>
On Tue, 20 Nov 2018, Oskari Lemmela wrote:
> Parts of the AXP803 are compatible with their counterparts on the AXP813.
> These include the GPIO, ADC, AC and battery power supplies.
>
> Signed-off-by: Oskari Lemmela <oskari@lemmela.net>
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> Tested-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
> drivers/mfd/axp20x.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
Applied, thanks.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 8/8] mfd: axp20x: Add supported cells for AXP803
From: Lee Jones @ 2018-12-10 6:27 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, linux-pm, Maxime Ripard,
Sebastian Reichel, linux-kernel, Vasily Khoruzhick, Chen-Yu Tsai,
Rob Herring, Oskari Lemmela, arm-linux
In-Reply-To: <20181208150526.uceviwfwqskfwovm@qschulz>
On Sat, 08 Dec 2018, Quentin Schulz wrote:
> Hi Lee,
>
> On Fri, Dec 07, 2018 at 07:22:37PM +0000, Lee Jones wrote:
> > On Fri, 07 Dec 2018, Vasily Khoruzhick wrote:
> >
> > > On Fri, Dec 7, 2018 at 8:40 AM Lee Jones <lee.jones@linaro.org> wrote:
> > >
> > > > My OCD-dar is going crazy.
> > > >
> > > > Why haven't you used the same alignment as is already there?
> > > >
> > > > If it starts to run over 80-chars then bring the others back.
> > > >
> > > > Also why is there a single liner shoved in the middle of the
> > > > multi-line entries? Please move the singles to the top or the
> > > > bottom.
> > >
> > > Hi Lee,
> > >
> > > Could you please reformat it in the way that makes your OCD-dar happy?
> > > It would be really nice to get
> >
> > I'm afraid not, for a multitude of reasons.
> >
> > The most important of which surround testing.
> >
> > > AC and battery support for APX8x3 merged -- it'll make Pinebook and
> > > Teres-I pretty well supported by mainline kernel.
> >
> > That's great. A worthy cause indeed. So I'm sure you guys will want
> > to turn the patch around in short order so that it's applied in time
> > for the next merge window.
> >
>
> Aren't the MFD cells probed in order?
>
> In that case, it makes little sense to short order them for this
> particular device (X-Powers PMICs in general). It will just make the
> system boot slower because of probe deferring.
>
> Why? As explained by Chen-Yu in v3[1], axp-gpios can be muxed as
> regulators, thus should be probed before axp-regulators. axp-adc is
> often used by axp-battery, axp-usb-power, axp-ac-power, thus should be
> probed beforehand as well.
If there are inter-dependencies between the devices, it makes sense to
keep them in the most efficient order.
> For the alignment that also triggered your OCD, I can send you a patch
> the day you merge this one if it can help. I sent a few patches for this
> driver that didn't respect the alignment so I'm fine fixing the mfd
> cells (and eventually re-order them as I saw a few axp-gpio cells being
> declared after axp-regulators).
That's fine. Please send the patch (based on this set) right away.
> Does that make this patch OK for you, Lee?
Yes, thank you.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 1/4] mfd: stmpe: Move ADC related defines to header of mfd
From: Lee Jones @ 2018-12-10 6:16 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Maxime Coquelin, Alexandre Torgue, marcel.ziswiler, linux-kernel,
stefan, linux-stm32, Philippe Schenker, linux-arm-kernel,
Max Krummenacher, linux-input, Philippe Schenker, jic23
In-Reply-To: <20181209045241.GF211094@dtor-ws>
On Sat, 08 Dec 2018, Dmitry Torokhov wrote:
> On Wed, Nov 28, 2018 at 09:15:32AM +0000, Lee Jones wrote:
> > On Fri, 23 Nov 2018, Philippe Schenker wrote:
> >
> > > Move defines that are ADC related to the header of the overlying mfd,
> > > so they can be used from multiple sub-devices.
> > >
> > > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
> > > ---
> > >
> > > Changes in v3:
> > > - None
> > >
> > > Changes in v2:
> > > - This is a new added commit. Separate commit for moving the defines out of
> > > drivers/input/touchscreen/stmpe-ts.c to overlying mfd-device drivers/mfd/stmpe.c
> > > - Pre-fix defines with STMPE_
> > >
> > > drivers/input/touchscreen/stmpe-ts.c | 34 +++++++++++-----------------
> > > include/linux/mfd/stmpe.h | 11 +++++++++
> >
> > Acked-by: Lee Jones <lee.jones@linaro.org>
>
> The series seem to be heading towards MFD or IIO, so I assume this patch
> will be merged through one of these trees.
>
> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
I'd be happy to take it.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH -next] input: keyboard: remove duplicated include from mtk-pmic-keys.c
From: Lee Jones @ 2018-12-10 6:15 UTC (permalink / raw)
To: YueHaibing
Cc: dmitry.torokhov, linux-kernel, linux-mediatek, linux-input,
matthias.bgg, chen.zhong, linux-arm-kernel
In-Reply-To: <20181209063440.27820-1-yuehaibing@huawei.com>
On Sun, 09 Dec 2018, YueHaibing wrote:
> Remove duplicated include.
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/input/keyboard/mtk-pmic-keys.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
> index 02c67a1..5027ebb 100644
> --- a/drivers/input/keyboard/mtk-pmic-keys.c
> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
> @@ -19,7 +19,6 @@
> #include <linux/input.h>
> #include <linux/interrupt.h>
> #include <linux/platform_device.h>
> -#include <linux/kernel.h>
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/regmap.h>
You are removing the wrong one.
Please convert this patch's main intent to alphabetise the header
files. Then you can remove any obvious duplicates.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 00/23] PCI: refactor the Mobiveil driver and add PCIe support for NXP LX SoCs
From: Subrahmanya Lingappa @ 2018-12-10 10:16 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: mark.rutland, devicetree, xiaowei.bao, linux-pci, Z.q. Hou,
linux-kernel, Leo Li, M.h. Lian, robh+dt, Mingkai Hu,
Bjorn Helgaas, shawnguo, linux-arm-kernel
In-Reply-To: <20181203115850.GB8040@e107981-ln.cambridge.arm.com>
Lorenzo,
You are right, I reviewed few DT files, will need some time to review
this train.
I will start doing it in a while.
Thanks for pitching in.
Thanks.
On Mon, Dec 3, 2018 at 8:58 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> On Tue, Nov 06, 2018 at 01:19:03PM +0000, Z.q. Hou wrote:
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > This patch set is aim to refactor the Mobiveil driver and add
> > PCIe support for NXP LX series SoCs.
> >
> > Hou Zhiqiang (23):
> > PCI: mobiveil: uniform the register accessors
> > PCI: mobiveil: format the code without function change
> > PCI: mobiveil: correct the returned error number
> > PCI: mobiveil: remove flag MSI_FLAG_MULTI_PCI_MSI
> > PCI: mobiveil: correct PCI base address in MEM/IO outbound windows
> > PCI: mobiveil: replace the resource list iteration function
> > PCI: mobiveil: use WIN_NUM_0 explicitly for CFG outbound window
> > PCI: mobiveil: use the 1st inbound window for MEM inbound transactions
> > PCI: mobiveil: correct the inbound/outbound window setup routine
> > PCI: mobiveil: fix the INTx process error
> > PCI: mobiveil: only fixup the Class Code field
> > PCI: mobiveil: move out the link up waiting from mobiveil_host_init
> > PCI: mobiveil: move irq chained handler setup out of DT parse
> > PCI: mobiveil: initialize Primary/Secondary/Subordinate bus number
> > dt-bindings: pci: mobiveil: change gpio_slave and apb_csr to optional
> > PCI: mobiveil: refactor the Mobiveil driver
> > PCI: mobiveil: continue to initialize the host upon no PCIe link
> > PCI: mobiveil: disabled IB and OB windows set by bootloader
> > PCI: mobiveil: add Byte and Half-Word width register accessors
> > PCI: mobiveil: change prototype of function mobiveil_host_init
> > dt-bindings: pci: Add NXP LX SoCs PCIe controller
> > PCI: mobiveil: add PCIe RC driver for NXP LX series SoCs
> > arm64: dts: freescale: lx2160a: add pcie DT nodes
> >
> > .../devicetree/bindings/pci/lx-pci.txt | 52 ++
> > .../devicetree/bindings/pci/mobiveil-pcie.txt | 2 +
> > MAINTAINERS | 10 +-
> > .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 157 ++++
> > drivers/pci/controller/Kconfig | 11 +-
> > drivers/pci/controller/Makefile | 2 +-
> > drivers/pci/controller/mobiveil/Kconfig | 34 +
> > drivers/pci/controller/mobiveil/Makefile | 5 +
> > drivers/pci/controller/mobiveil/pci-lx.c | 222 +++++
> > .../controller/mobiveil/pcie-mobiveil-host.c | 622 +++++++++++++
> > .../controller/mobiveil/pcie-mobiveil-plat.c | 54 ++
> > .../pci/controller/mobiveil/pcie-mobiveil.c | 245 +++++
> > .../pci/controller/mobiveil/pcie-mobiveil.h | 221 +++++
> > drivers/pci/controller/pcie-mobiveil.c | 861 ------------------
> > 14 files changed, 1625 insertions(+), 873 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/pci/lx-pci.txt
> > create mode 100644 drivers/pci/controller/mobiveil/Kconfig
> > create mode 100644 drivers/pci/controller/mobiveil/Makefile
> > create mode 100644 drivers/pci/controller/mobiveil/pci-lx.c
> > create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
> > create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
> > create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.c
> > create mode 100644 drivers/pci/controller/mobiveil/pcie-mobiveil.h
> > delete mode 100644 drivers/pci/controller/pcie-mobiveil.c
>
> Subrahmanya,
>
> for the records, this is the driver *you* are maintaining, aren't you ?
>
> We ask developers to be added to the MAINTAINERS list in order to hold
> them accountable, merging a driver upstream means that you need to
> actively maintain it, which in turn means reviewing series affecting
> its code, like this one.
>
> I will have a look too but it is your responsibility to review these
> patches and ACK them accordingly.
>
> So I strongly suggest you start doing it please.
>
> Thanks,
> Lorenzo
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v5 0/7] spi: add support for octal mode
From: Yogesh Narayan Gaur @ 2018-12-10 4:13 UTC (permalink / raw)
To: Mark Brown
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, Vignesh R,
marek.vasut@gmail.com, linux-kernel@vger.kernel.org,
linux-spi@vger.kernel.org, Boris Brezillon,
frieder.schrempf@exceet.de, linux-mtd@lists.infradead.org,
computersforpeace@gmail.com, shawnguo@kernel.org, robh@kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20181206202956.GG3084@sirena.org.uk>
Hi Mark,
Patch has been resend [1], this patch is depends on the series of patch[2] and this series has been applied by Boris already.
[1] https://patchwork.ozlabs.org/patch/1010253/
[2] https://patchwork.ozlabs.org/project/linux-mtd/list/?series=70384&state=*
--
Regards
Yogesh Gaur
> -----Original Message-----
> From: Mark Brown [mailto:broonie@kernel.org]
> Sent: Friday, December 7, 2018 2:00 AM
> To: Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com>
> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; Vignesh R <vigneshr@ti.com>;
> linux-mtd@lists.infradead.org; marek.vasut@gmail.com; linux-
> spi@vger.kernel.org; devicetree@vger.kernel.org; robh@kernel.org;
> mark.rutland@arm.com; shawnguo@kernel.org; linux-arm-
> kernel@lists.infradead.org; computersforpeace@gmail.com;
> frieder.schrempf@exceet.de; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v5 0/7] spi: add support for octal mode
>
> On Thu, Dec 06, 2018 at 06:49:08AM +0000, Yogesh Narayan Gaur wrote:
>
> > Sorry for ignorance. Did patches needs to be applied by Mark Brown, should I
> resend the patch series again?
> > Also can you please review the series [1] and add your Reviewed-by tag.
>
> As I said in my reply earlier today in the same thread:
>
> | I don't have this any more, it looked like this was stuck behind the
> | otehr MTD changes which seemed to have problems. If someone could
> | resend?
>
> so please resend.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RESEND PATCH v5 5/7] mtd: m25p80: add support of octal mode I/O transfer
From: Yogesh Narayan Gaur @ 2018-12-10 4:10 UTC (permalink / raw)
To: linux-mtd@lists.infradead.org, boris.brezillon@bootlin.com,
broonie@kernel.org, marek.vasut@gmail.com, vigneshr@ti.com,
linux-spi@vger.kernel.org, devicetree@vger.kernel.org
Cc: mark.rutland@arm.com, robh@kernel.org, Yogesh Narayan Gaur,
linux-kernel@vger.kernel.org, frieder.schrempf@exceet.de,
computersforpeace@gmail.com, shawnguo@kernel.org,
linux-arm-kernel@lists.infradead.org
Add support for octal mode I/O data transfer based on the controller (spi)
mode.
Assign hw-capability mask bits for octal transfer.
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
---
Changes for v5:
- Modified string 'octo' with 'octal'.
Changes for v4:
- None
Changes for v3:
- Modified string 'octal' with 'octo'.
Changes for v2:
- Incorporated review comments of Boris.
drivers/mtd/devices/m25p80.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index c4a1d04..651bab6 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -195,7 +195,14 @@ static int m25p_probe(struct spi_mem *spimem)
spi_mem_set_drvdata(spimem, flash);
flash->spimem = spimem;
- if (spi->mode & SPI_RX_QUAD) {
+ if (spi->mode & SPI_RX_OCTAL) {
+ hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
+
+ if (spi->mode & SPI_TX_OCTAL)
+ hwcaps.mask |= (SNOR_HWCAPS_READ_1_8_8 |
+ SNOR_HWCAPS_PP_1_1_8 |
+ SNOR_HWCAPS_PP_1_8_8);
+ } else if (spi->mode & SPI_RX_QUAD) {
hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
if (spi->mode & SPI_TX_QUAD)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v3 09/12] powerpc: perf/core: use PERF_PMU_CAP_NO_EXCLUDE for exclude incapable PMUs
From: Madhavan Srinivasan @ 2018-12-10 4:02 UTC (permalink / raw)
To: Andrew Murray, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Richard Henderson, Ivan Kokshaysky,
Matt Turner, Will Deacon, Mark Rutland, Shawn Guo, Sascha Hauer,
Benjamin Herrenschmidt, Paul Mackerras, Thomas Gleixner,
Borislav Petkov, Russell King, suzuki.poulose, robin.murphy,
Michael Ellerman
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-alpha
In-Reply-To: <1544114849-47266-10-git-send-email-andrew.murray@arm.com>
On 06/12/18 10:17 PM, Andrew Murray wrote:
> For PowerPC PMUs that do not support context exclusion let's
> advertise the PERF_PMU_CAP_NO_EXCLUDE capability. This ensures that
> perf will prevent us from handling events where any exclusion flags
> are set. Let's also remove the now unnecessary check for exclusion
> flags.
Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/powerpc/perf/hv-24x7.c | 10 +---------
> arch/powerpc/perf/hv-gpci.c | 10 +---------
> arch/powerpc/perf/imc-pmu.c | 19 +------------------
> 3 files changed, 3 insertions(+), 36 deletions(-)
>
> diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
> index 72238ee..d2b8e60 100644
> --- a/arch/powerpc/perf/hv-24x7.c
> +++ b/arch/powerpc/perf/hv-24x7.c
> @@ -1306,15 +1306,6 @@ static int h_24x7_event_init(struct perf_event *event)
> return -EINVAL;
> }
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> /* no branch sampling */
> if (has_branch_stack(event))
> return -EOPNOTSUPP;
> @@ -1577,6 +1568,7 @@ static struct pmu h_24x7_pmu = {
> .start_txn = h_24x7_event_start_txn,
> .commit_txn = h_24x7_event_commit_txn,
> .cancel_txn = h_24x7_event_cancel_txn,
> + .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> };
>
> static int hv_24x7_init(void)
> diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
> index 43fabb3..735e77b 100644
> --- a/arch/powerpc/perf/hv-gpci.c
> +++ b/arch/powerpc/perf/hv-gpci.c
> @@ -232,15 +232,6 @@ static int h_gpci_event_init(struct perf_event *event)
> return -EINVAL;
> }
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> /* no branch sampling */
> if (has_branch_stack(event))
> return -EOPNOTSUPP;
> @@ -285,6 +276,7 @@ static struct pmu h_gpci_pmu = {
> .start = h_gpci_event_start,
> .stop = h_gpci_event_stop,
> .read = h_gpci_event_update,
> + .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> };
>
> static int hv_gpci_init(void)
> diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
> index 1fafc32b..1dbb0ee 100644
> --- a/arch/powerpc/perf/imc-pmu.c
> +++ b/arch/powerpc/perf/imc-pmu.c
> @@ -473,15 +473,6 @@ static int nest_imc_event_init(struct perf_event *event)
> if (event->hw.sample_period)
> return -EINVAL;
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> if (event->cpu < 0)
> return -EINVAL;
>
> @@ -748,15 +739,6 @@ static int core_imc_event_init(struct perf_event *event)
> if (event->hw.sample_period)
> return -EINVAL;
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> if (event->cpu < 0)
> return -EINVAL;
>
> @@ -1069,6 +1051,7 @@ static int update_pmu_ops(struct imc_pmu *pmu)
> pmu->pmu.stop = imc_event_stop;
> pmu->pmu.read = imc_event_update;
> pmu->pmu.attr_groups = pmu->attr_groups;
> + pmu->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
> pmu->attr_groups[IMC_FORMAT_ATTR] = &imc_format_group;
>
> switch (pmu->domain) {
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 0/7] add UniPhier DVB Frontend system support
From: Katsuhiro Suzuki @ 2018-12-10 3:55 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Katsuhiro Suzuki
Cc: Sean Young, Masami Hiramatsu, Brad Love, linux-kernel, Jassi Brar,
Michael Ira Krufky, linux-arm-kernel, linux-media
In-Reply-To: <20181207121716.17521ac2@coco.lan>
Hello Mauro,
Thank you for reviewing. Actually, I leaved Socionext at October
this year. I tried to find next person that maintain these patches
before leaving Socionext but I could not find.
And unfortunately, I cannot test and refine these DVB patches
because Socionext evaluation boards that can receive ISDB are not
sell and SoC specification is not public.
So it's better to drop my UniPhier DVB patches, I think...
Best Regards,
---
Katsuhiro Suzuki
On 2018/12/07 23:17, Mauro Carvalho Chehab wrote:
> Hi Katsuhiro-san,
>
> Em Thu, 30 Aug 2018 10:13:11 +0900
> "Katsuhiro Suzuki" <suzuki.katsuhiro@socionext.com> escreveu:
>
>> Hello Mauro,
>>
>> This is ping...
>
> Sorry for taking a long time to look into it.
>
> Reviewing new drivers take some time, and need to be done right.
>
> I usually let the sub-maintainers to do a first look, but they
> probably missed this one. So, let me copy them. Hopefully they
> can do review on it soon.
>
> I'll try to do a review myself, but I won't be able to do it
> until mid next week.
>
> Regards,
> Mauro
>
>>
>>> -----Original Message-----
>>> From: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
>>> Sent: Wednesday, August 8, 2018 2:25 PM
>>> To: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>;
>>> linux-media@vger.kernel.org
>>> Cc: Masami Hiramatsu <masami.hiramatsu@linaro.org>; Jassi Brar
>>> <jaswinder.singh@linaro.org>; linux-arm-kernel@lists.infradead.org;
>>> linux-kernel@vger.kernel.org; Suzuki, Katsuhiro
>>> <suzuki.katsuhiro@socionext.com>
>>> Subject: [PATCH v2 0/7] add UniPhier DVB Frontend system support
>>>
>>> This series adds support for DVB Frontend system named HSC support
>>> for UniPhier LD11/LD20 SoCs. This driver supports MPEG2-TS serial
>>> signal input from external demodulator and DMA MPEG2-TS stream data
>>> onto memory.
>>>
>>> UniPhier HSC driver provides many ports of TS input. Since the HSC
>>> has mixed register map for those ports. It hard to split each register
>>> areas.
>>>
>>> ---
>>>
>>> Changes from v1:
>>> DT bindings
>>> - Fix mistakes of spelling
>>> - Rename uniphier,hsc.txt -> socionext,uniphier-hsc.txt
>>> Kconfig, Makefile
>>> - Add COMPILE_TEST, REGMAP_MMIO
>>> - Add $(srctree) to include path option
>>> Headers
>>> - Split large patch
>>> - Remove more unused definitions
>>> - Remove unneeded const
>>> - Replace enum that has special value into #define
>>> - Remove weird macro from register definitions
>>> - Remove field_get/prop inline functions
>>> Modules
>>> - Split register definitions, function prototypes
>>> - Fix include lines
>>> - Fix depended config
>>> - Remove redundant conditions
>>> - Drop adapter patches, and need no patches to build
>>> - Merge uniphier-adapter.o into each adapter drivers
>>> - Split 3 modules (core, ld11, ld20) to build adapter drivers as
>>> module
>>> - Fix compile error if build as module
>>> - Use hardware spec table to remove weird macro from register
>>> definitions
>>> - Use usleep_range instead of msleep
>>> - Use shift and mask instead of field_get/prop inline functions
>>>
>>> Katsuhiro Suzuki (7):
>>> media: uniphier: add DT bindings documentation for UniPhier HSC
>>> media: uniphier: add DMA common file of HSC
>>> media: uniphier: add CSS common file of HSC
>>> media: uniphier: add TS common file of HSC
>>> media: uniphier: add ucode load common file of HSC
>>> media: uniphier: add platform driver module of HSC
>>> media: uniphier: add LD11/LD20 HSC support
>>>
>>> .../bindings/media/socionext,uniphier-hsc.txt | 38 ++
>>> drivers/media/platform/Kconfig | 1 +
>>> drivers/media/platform/Makefile | 2 +
>>> drivers/media/platform/uniphier/Kconfig | 19 +
>>> drivers/media/platform/uniphier/Makefile | 5 +
>>> drivers/media/platform/uniphier/hsc-core.c | 515 ++++++++++++++++++
>>> drivers/media/platform/uniphier/hsc-css.c | 250 +++++++++
>>> drivers/media/platform/uniphier/hsc-dma.c | 212 +++++++
>>> drivers/media/platform/uniphier/hsc-ld11.c | 273 ++++++++++
>>> drivers/media/platform/uniphier/hsc-reg.h | 272 +++++++++
>>> drivers/media/platform/uniphier/hsc-ts.c | 127 +++++
>>> drivers/media/platform/uniphier/hsc-ucode.c | 416 ++++++++++++++
>>> drivers/media/platform/uniphier/hsc.h | 389 +++++++++++++
>>> 13 files changed, 2519 insertions(+)
>>> create mode 100644
>>> Documentation/devicetree/bindings/media/socionext,uniphier-hsc.txt
>>> create mode 100644 drivers/media/platform/uniphier/Kconfig
>>> create mode 100644 drivers/media/platform/uniphier/Makefile
>>> create mode 100644 drivers/media/platform/uniphier/hsc-core.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc-css.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc-dma.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc-ld11.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc-reg.h
>>> create mode 100644 drivers/media/platform/uniphier/hsc-ts.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc-ucode.c
>>> create mode 100644 drivers/media/platform/uniphier/hsc.h
>>>
>>> --
>>> 2.18.0
>>
>>
>>
>
>
>
> Thanks,
> Mauro
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 09/12] powerpc: perf/core: use PERF_PMU_CAP_NO_EXCLUDE for exclude incapable PMUs
From: Michael Ellerman @ 2018-12-10 3:51 UTC (permalink / raw)
To: Andrew Murray, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Richard Henderson, Ivan Kokshaysky,
Matt Turner, Will Deacon, Mark Rutland, Shawn Guo, Sascha Hauer,
Benjamin Herrenschmidt, Paul Mackerras, Thomas Gleixner,
Borislav Petkov, Russell King, suzuki.poulose, robin.murphy
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-alpha
In-Reply-To: <1544114849-47266-10-git-send-email-andrew.murray@arm.com>
Andrew Murray <andrew.murray@arm.com> writes:
> For PowerPC PMUs that do not support context exclusion let's
> advertise the PERF_PMU_CAP_NO_EXCLUDE capability. This ensures that
> perf will prevent us from handling events where any exclusion flags
> are set. Let's also remove the now unnecessary check for exclusion
> flags.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/powerpc/perf/hv-24x7.c | 10 +---------
> arch/powerpc/perf/hv-gpci.c | 10 +---------
> arch/powerpc/perf/imc-pmu.c | 19 +------------------
> 3 files changed, 3 insertions(+), 36 deletions(-)
Looks good.
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
cheers
> diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
> index 72238ee..d2b8e60 100644
> --- a/arch/powerpc/perf/hv-24x7.c
> +++ b/arch/powerpc/perf/hv-24x7.c
> @@ -1306,15 +1306,6 @@ static int h_24x7_event_init(struct perf_event *event)
> return -EINVAL;
> }
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> /* no branch sampling */
> if (has_branch_stack(event))
> return -EOPNOTSUPP;
> @@ -1577,6 +1568,7 @@ static struct pmu h_24x7_pmu = {
> .start_txn = h_24x7_event_start_txn,
> .commit_txn = h_24x7_event_commit_txn,
> .cancel_txn = h_24x7_event_cancel_txn,
> + .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> };
>
> static int hv_24x7_init(void)
> diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
> index 43fabb3..735e77b 100644
> --- a/arch/powerpc/perf/hv-gpci.c
> +++ b/arch/powerpc/perf/hv-gpci.c
> @@ -232,15 +232,6 @@ static int h_gpci_event_init(struct perf_event *event)
> return -EINVAL;
> }
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> /* no branch sampling */
> if (has_branch_stack(event))
> return -EOPNOTSUPP;
> @@ -285,6 +276,7 @@ static struct pmu h_gpci_pmu = {
> .start = h_gpci_event_start,
> .stop = h_gpci_event_stop,
> .read = h_gpci_event_update,
> + .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> };
>
> static int hv_gpci_init(void)
> diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
> index 1fafc32b..1dbb0ee 100644
> --- a/arch/powerpc/perf/imc-pmu.c
> +++ b/arch/powerpc/perf/imc-pmu.c
> @@ -473,15 +473,6 @@ static int nest_imc_event_init(struct perf_event *event)
> if (event->hw.sample_period)
> return -EINVAL;
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> if (event->cpu < 0)
> return -EINVAL;
>
> @@ -748,15 +739,6 @@ static int core_imc_event_init(struct perf_event *event)
> if (event->hw.sample_period)
> return -EINVAL;
>
> - /* unsupported modes and filters */
> - if (event->attr.exclude_user ||
> - event->attr.exclude_kernel ||
> - event->attr.exclude_hv ||
> - event->attr.exclude_idle ||
> - event->attr.exclude_host ||
> - event->attr.exclude_guest)
> - return -EINVAL;
> -
> if (event->cpu < 0)
> return -EINVAL;
>
> @@ -1069,6 +1051,7 @@ static int update_pmu_ops(struct imc_pmu *pmu)
> pmu->pmu.stop = imc_event_stop;
> pmu->pmu.read = imc_event_update;
> pmu->pmu.attr_groups = pmu->attr_groups;
> + pmu->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
> pmu->attr_groups[IMC_FORMAT_ATTR] = &imc_format_group;
>
> switch (pmu->domain) {
> --
> 2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
From: Long Cheng @ 2018-12-10 2:57 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In-Reply-To: <1544410636-31815-1-git-send-email-long.cheng@mediatek.com>
In DMA engine framework, add 8250 mtk dma to support it.
Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
drivers/dma/mediatek/8250_mtk_dma.c | 830 +++++++++++++++++++++++++++++++++++
drivers/dma/mediatek/Kconfig | 11 +
drivers/dma/mediatek/Makefile | 1 +
3 files changed, 842 insertions(+)
create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
diff --git a/drivers/dma/mediatek/8250_mtk_dma.c b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 0000000..f79d180
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng <long.cheng@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_B BIT(0)
+#define VFF_4G_SUPPORT_B BIT(0)
+#define VFF_RX_INT_EN0_B BIT(0) /*rx valid size >= vff thre*/
+#define VFF_RX_INT_EN1_B BIT(1)
+#define VFF_TX_INT_EN_B BIT(0) /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B 0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B 0
+#define VFF_INT_EN_CLR_B 0
+#define VFF_4G_SUPPORT_CLR_B 0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE 0xffffU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP 0x10000U
+
+#define VFF_INT_FLAG 0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST 0x0c
+#define VFF_STOP 0x10
+#define VFF_FLUSH 0x14
+#define VFF_ADDR 0x1c
+#define VFF_LEN 0x24
+#define VFF_THRE 0x28
+#define VFF_WPT 0x2c
+#define VFF_RPT 0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE 0x40
+#define VFF_DEBUG_STATUS 0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+ struct dma_device ddev;
+ void __iomem *mem_base[MTK_APDMA_CHANNELS];
+ spinlock_t lock; /* dma dev lock */
+ struct tasklet_struct task;
+ struct list_head pending;
+ struct clk *clk;
+ unsigned int dma_requests;
+ bool support_33bits;
+ unsigned int dma_irq[MTK_APDMA_CHANNELS];
+ struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+ struct virt_dma_chan vc;
+ struct list_head node;
+ struct dma_slave_config cfg;
+ void __iomem *base;
+ struct mtk_dma_desc *desc;
+
+ bool stop;
+ bool requested;
+
+ unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+ dma_addr_t addr;
+ unsigned int en; /* number of elements (24-bit) */
+ unsigned int fn; /* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+ struct virt_dma_desc vd;
+ enum dma_transfer_direction dir;
+
+ unsigned int sglen;
+ struct mtk_dma_sg sg[0];
+
+ unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+ return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+ (struct dma_async_tx_descriptor *t)
+{
+ return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+ unsigned int reg, unsigned int val)
+{
+ writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+ return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+ struct dma_chan *chan = vd->tx.chan;
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ kfree(c->desc);
+ c->desc = NULL;
+}
+
+static void mtk_dma_tx_flush(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ if (mtk_dma_chan_read(c, VFF_FLUSH) == 0U)
+ mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_dma_tx_write(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned int txcount = c->desc->len;
+ unsigned int len, send, left, wpt, wrap;
+
+ len = mtk_dma_chan_read(c, VFF_LEN);
+
+ while ((left = mtk_dma_chan_read(c, VFF_LEFT_SIZE)) > 0U) {
+ if (c->desc->len == 0U)
+ break;
+ send = min_t(unsigned int, left, c->desc->len);
+ wpt = mtk_dma_chan_read(c, VFF_WPT);
+ wrap = wpt & MTK_DMA_RING_WRAP ? 0U : MTK_DMA_RING_WRAP;
+
+ if ((wpt & (len - 1U)) + send < len)
+ mtk_dma_chan_write(c, VFF_WPT, wpt + send);
+ else
+ mtk_dma_chan_write(c, VFF_WPT,
+ ((wpt + send) & (len - 1U))
+ | wrap);
+
+ c->desc->len -= send;
+ }
+
+ if (txcount != c->desc->len) {
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+ mtk_dma_tx_flush(chan);
+ }
+}
+
+static void mtk_dma_start_tx(struct mtk_chan *c)
+{
+ if (mtk_dma_chan_read(c, VFF_LEFT_SIZE) == 0U)
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+ else
+ mtk_dma_tx_write(&c->vc.chan);
+
+ c->stop = false;
+}
+
+static void mtk_dma_get_rx_size(struct mtk_chan *c)
+{
+ unsigned int rx_size = mtk_dma_chan_read(c, VFF_LEN);
+ unsigned int rdptr, wrptr, wrreg, rdreg, count;
+
+ rdreg = mtk_dma_chan_read(c, VFF_RPT);
+ wrreg = mtk_dma_chan_read(c, VFF_WPT);
+ rdptr = rdreg & MTK_DMA_RING_SIZE;
+ wrptr = wrreg & MTK_DMA_RING_SIZE;
+ count = ((rdreg ^ wrreg) & MTK_DMA_RING_WRAP) ?
+ (wrptr + rx_size - rdptr) : (wrptr - rdptr);
+
+ c->rx_status = count;
+
+ mtk_dma_chan_write(c, VFF_RPT, wrreg);
+}
+
+static void mtk_dma_start_rx(struct mtk_chan *c)
+{
+ struct dma_chan *chan = &c->vc.chan;
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_dma_desc *d = c->desc;
+
+ if (mtk_dma_chan_read(c, VFF_VALID_SIZE) == 0U)
+ return;
+
+ if (d && vchan_next_desc(&c->vc)) {
+ mtk_dma_get_rx_size(c);
+ list_del(&d->vd.node);
+ vchan_cookie_complete(&d->vd);
+ } else {
+ spin_lock(&mtkd->lock);
+ if (list_empty(&mtkd->pending))
+ list_add_tail(&c->node, &mtkd->pending);
+ spin_unlock(&mtkd->lock);
+ tasklet_schedule(&mtkd->task);
+ }
+}
+
+static void mtk_dma_reset(struct mtk_chan *c)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(c->vc.chan.device);
+ u32 status;
+ int ret;
+
+ mtk_dma_chan_write(c, VFF_ADDR, 0);
+ mtk_dma_chan_write(c, VFF_THRE, 0);
+ mtk_dma_chan_write(c, VFF_LEN, 0);
+ mtk_dma_chan_write(c, VFF_RST, VFF_WARM_RST_B);
+
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_EN,
+ status, status == 0, 10, 100);
+ if (ret) {
+ dev_err(c->vc.chan.device->dev,
+ "dma reset: fail, timeout\n");
+ return;
+ }
+
+ if (c->cfg.direction == DMA_DEV_TO_MEM)
+ mtk_dma_chan_write(c, VFF_RPT, 0);
+ else if (c->cfg.direction == DMA_MEM_TO_DEV)
+ mtk_dma_chan_write(c, VFF_WPT, 0);
+
+ if (mtkd->support_33bits)
+ mtk_dma_chan_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
+}
+
+static void mtk_dma_stop(struct mtk_chan *c)
+{
+ u32 status;
+ int ret;
+
+ mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_CLR_B);
+ /* Wait for flush */
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_FLUSH,
+ status,
+ (status & VFF_FLUSH_B) != VFF_FLUSH_B,
+ 10, 100);
+ if (ret)
+ dev_err(c->vc.chan.device->dev,
+ "dma stop: polling FLUSH fail, DEBUG=0x%x\n",
+ mtk_dma_chan_read(c, VFF_DEBUG_STATUS));
+
+ /*set stop as 1 -> wait until en is 0 -> set stop as 0*/
+ mtk_dma_chan_write(c, VFF_STOP, VFF_STOP_B);
+ ret = readx_poll_timeout(readl,
+ c->base + VFF_EN,
+ status, status == 0, 10, 100);
+ if (ret)
+ dev_err(c->vc.chan.device->dev,
+ "dma stop: polling VFF_EN fail, DEBUG=0x%x\n",
+ mtk_dma_chan_read(c, VFF_DEBUG_STATUS));
+
+ mtk_dma_chan_write(c, VFF_STOP, VFF_STOP_CLR_B);
+ mtk_dma_chan_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
+
+ if (c->cfg.direction == DMA_DEV_TO_MEM)
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+ else
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+ c->stop = true;
+}
+
+/*
+ * This callback schedules all pending channels. We could be more
+ * clever here by postponing allocation of the real DMA channels to
+ * this point, and freeing them when our virtual channel becomes idle.
+ *
+ * We would then need to deal with 'all channels in-use'
+ */
+static void mtk_dma_sched(unsigned long data)
+{
+ struct mtk_dmadev *mtkd = (struct mtk_dmadev *)data;
+ struct virt_dma_desc *vd;
+ struct mtk_chan *c;
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irq(&mtkd->lock);
+ list_splice_tail_init(&mtkd->pending, &head);
+ spin_unlock_irq(&mtkd->lock);
+
+ if (!list_empty(&head)) {
+ c = list_first_entry(&head, struct mtk_chan, node);
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->cfg.direction == DMA_DEV_TO_MEM) {
+ list_del_init(&c->node);
+ mtk_dma_start_rx(c);
+ } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ list_del_init(&c->node);
+ mtk_dma_start_tx(c);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+ }
+}
+
+static int mtk_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ int ret = -EBUSY;
+
+ pm_runtime_get_sync(mtkd->ddev.dev);
+
+ if (!mtkd->ch[chan->chan_id]) {
+ c->base = mtkd->mem_base[chan->chan_id];
+ mtkd->ch[chan->chan_id] = c;
+ ret = 1;
+ }
+ c->requested = false;
+ mtk_dma_reset(c);
+
+ return ret;
+}
+
+static void mtk_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+ if (c->requested) {
+ c->requested = false;
+ free_irq(mtkd->dma_irq[chan->chan_id], chan);
+ }
+
+ tasklet_kill(&mtkd->task);
+ tasklet_kill(&c->vc.task);
+
+ c->base = NULL;
+ mtkd->ch[chan->chan_id] = NULL;
+ vchan_free_chan_resources(&c->vc);
+
+ pm_runtime_put_sync(mtkd->ddev.dev);
+}
+
+static enum dma_status mtk_dma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ enum dma_status ret;
+ unsigned long flags;
+
+ if (!txstate)
+ return DMA_ERROR;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (ret == DMA_IN_PROGRESS) {
+ c->rx_status = mtk_dma_chan_read(c, VFF_RPT)
+ & MTK_DMA_RING_SIZE;
+ dma_set_residue(txstate, c->rx_status);
+ } else if (ret == DMA_COMPLETE && c->cfg.direction == DMA_DEV_TO_MEM) {
+ dma_set_residue(txstate, c->rx_status);
+ } else {
+ dma_set_residue(txstate, 0);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *mtk_dma_prep_slave_sg
+ (struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sglen, enum dma_transfer_direction dir,
+ unsigned long tx_flags, void *context)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct scatterlist *sgent;
+ struct mtk_dma_desc *d;
+ struct mtk_dma_sg *sg;
+ unsigned int size, i, j, en;
+
+ en = 1;
+
+ if ((dir != DMA_DEV_TO_MEM) &&
+ (dir != DMA_MEM_TO_DEV)) {
+ dev_err(chan->device->dev, "bad direction\n");
+ return NULL;
+ }
+
+ /* Now allocate and setup the descriptor. */
+ d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
+ if (!d)
+ return NULL;
+
+ d->dir = dir;
+
+ j = 0;
+ for_each_sg(sgl, sgent, sglen, i) {
+ d->sg[j].addr = sg_dma_address(sgent);
+ d->sg[j].en = en;
+ d->sg[j].fn = sg_dma_len(sgent) / en;
+ j++;
+ }
+
+ d->sglen = j;
+
+ if (dir == DMA_MEM_TO_DEV) {
+ for (size = i = 0; i < d->sglen; i++) {
+ sg = &d->sg[i];
+ size += sg->en * sg->fn;
+ }
+ d->len = size;
+ }
+
+ return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
+}
+
+static void mtk_dma_issue_pending(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct virt_dma_desc *vd;
+ struct mtk_dmadev *mtkd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->cfg.direction == DMA_DEV_TO_MEM) {
+ mtkd = to_mtk_dma_dev(chan->device);
+ if (vchan_issue_pending(&c->vc) && !c->desc) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ }
+ } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+ if (vchan_issue_pending(&c->vc) && !c->desc) {
+ vd = vchan_next_desc(&c->vc);
+ c->desc = to_mtk_dma_desc(&vd->tx);
+ mtk_dma_start_tx(c);
+ }
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+}
+
+static irqreturn_t mtk_dma_rx_interrupt(int irq, void *dev_id)
+{
+ struct dma_chan *chan = (struct dma_chan *)dev_id;
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+
+ mtk_dma_start_rx(c);
+
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dma_tx_interrupt(int irq, void *dev_id)
+{
+ struct dma_chan *chan = (struct dma_chan *)dev_id;
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(chan->device);
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct mtk_dma_desc *d = c->desc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (d->len != 0U) {
+ list_add_tail(&c->node, &mtkd->pending);
+ tasklet_schedule(&mtkd->task);
+ } else {
+ list_del(&d->vd.node);
+ vchan_cookie_complete(&d->vd);
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+ return IRQ_HANDLED;
+}
+
+static int mtk_dma_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ struct mtk_dmadev *mtkd = to_mtk_dma_dev(c->vc.chan.device);
+ int ret;
+
+ c->cfg = *cfg;
+
+ if (cfg->direction == DMA_DEV_TO_MEM) {
+ unsigned int rx_len = cfg->src_addr_width * 1024;
+
+ mtk_dma_chan_write(c, VFF_ADDR, cfg->src_addr);
+ mtk_dma_chan_write(c, VFF_LEN, rx_len);
+ mtk_dma_chan_write(c, VFF_THRE, VFF_RX_THRE(rx_len));
+ mtk_dma_chan_write(c,
+ VFF_INT_EN, VFF_RX_INT_EN0_B
+ | VFF_RX_INT_EN1_B);
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+ mtk_dma_chan_write(c, VFF_EN, VFF_EN_B);
+
+ if (!c->requested) {
+ c->requested = true;
+ ret = request_irq(mtkd->dma_irq[chan->chan_id],
+ mtk_dma_rx_interrupt,
+ IRQF_TRIGGER_NONE,
+ KBUILD_MODNAME, chan);
+ if (ret < 0) {
+ dev_err(chan->device->dev, "Can't request rx dma IRQ\n");
+ return -EINVAL;
+ }
+ }
+ } else if (cfg->direction == DMA_MEM_TO_DEV) {
+ unsigned int tx_len = cfg->dst_addr_width * 1024;
+
+ mtk_dma_chan_write(c, VFF_ADDR, cfg->dst_addr);
+ mtk_dma_chan_write(c, VFF_LEN, tx_len);
+ mtk_dma_chan_write(c, VFF_THRE, VFF_TX_THRE(tx_len));
+ mtk_dma_chan_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+ mtk_dma_chan_write(c, VFF_EN, VFF_EN_B);
+
+ if (!c->requested) {
+ c->requested = true;
+ ret = request_irq(mtkd->dma_irq[chan->chan_id],
+ mtk_dma_tx_interrupt,
+ IRQF_TRIGGER_NONE,
+ KBUILD_MODNAME, chan);
+ if (ret < 0) {
+ dev_err(chan->device->dev, "Can't request tx dma IRQ\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (mtkd->support_33bits)
+ mtk_dma_chan_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_B);
+
+ if (mtk_dma_chan_read(c, VFF_EN) != VFF_EN_B) {
+ dev_err(chan->device->dev,
+ "config dma dir[%d] fail\n", cfg->direction);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_dma_terminate_all(struct dma_chan *chan)
+{
+ struct mtk_chan *c = to_mtk_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->vc.lock, flags);
+ list_del_init(&c->node);
+ mtk_dma_stop(c);
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
+ return 0;
+}
+
+static int mtk_dma_device_pause(struct dma_chan *chan)
+{
+ /* just for check caps pass */
+ return -EINVAL;
+}
+
+static int mtk_dma_device_resume(struct dma_chan *chan)
+{
+ /* just for check caps pass */
+ return -EINVAL;
+}
+
+static void mtk_dma_free(struct mtk_dmadev *mtkd)
+{
+ tasklet_kill(&mtkd->task);
+ while (list_empty(&mtkd->ddev.channels) == 0) {
+ struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels,
+ struct mtk_chan, vc.chan.device_node);
+
+ list_del(&c->vc.chan.device_node);
+ tasklet_kill(&c->vc.task);
+ devm_kfree(mtkd->ddev.dev, c);
+ }
+}
+
+static const struct of_device_id mtk_uart_dma_match[] = {
+ { .compatible = "mediatek,mt6577-uart-dma", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_uart_dma_match);
+
+static int mtk_apdma_probe(struct platform_device *pdev)
+{
+ struct mtk_dmadev *mtkd;
+ struct resource *res;
+ struct mtk_chan *c;
+ unsigned int i;
+ int rc;
+
+ mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL);
+ if (!mtkd)
+ return -ENOMEM;
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ return -ENODEV;
+ mtkd->mem_base[i] = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mtkd->mem_base[i]))
+ return PTR_ERR(mtkd->mem_base[i]);
+ }
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ mtkd->dma_irq[i] = platform_get_irq(pdev, i);
+ if ((int)mtkd->dma_irq[i] < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i);
+ return -EINVAL;
+ }
+ }
+
+ mtkd->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(mtkd->clk)) {
+ dev_err(&pdev->dev, "No clock specified\n");
+ return PTR_ERR(mtkd->clk);
+ }
+
+ if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) {
+ dev_info(&pdev->dev, "Support dma 33bits\n");
+ mtkd->support_33bits = true;
+ }
+
+ if (mtkd->support_33bits)
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
+ else
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (rc)
+ return rc;
+
+ dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask);
+ mtkd->ddev.device_alloc_chan_resources = mtk_dma_alloc_chan_resources;
+ mtkd->ddev.device_free_chan_resources = mtk_dma_free_chan_resources;
+ mtkd->ddev.device_tx_status = mtk_dma_tx_status;
+ mtkd->ddev.device_issue_pending = mtk_dma_issue_pending;
+ mtkd->ddev.device_prep_slave_sg = mtk_dma_prep_slave_sg;
+ mtkd->ddev.device_config = mtk_dma_slave_config;
+ mtkd->ddev.device_pause = mtk_dma_device_pause;
+ mtkd->ddev.device_resume = mtk_dma_device_resume;
+ mtkd->ddev.device_terminate_all = mtk_dma_terminate_all;
+ mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+ mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+ mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+ mtkd->ddev.dev = &pdev->dev;
+ INIT_LIST_HEAD(&mtkd->ddev.channels);
+ INIT_LIST_HEAD(&mtkd->pending);
+
+ spin_lock_init(&mtkd->lock);
+ tasklet_init(&mtkd->task, mtk_dma_sched, (unsigned long)mtkd);
+
+ mtkd->dma_requests = MTK_APDMA_DEFAULT_REQUESTS;
+ if (of_property_read_u32(pdev->dev.of_node,
+ "dma-requests", &mtkd->dma_requests)) {
+ dev_info(&pdev->dev,
+ "Missing dma-requests property, using %u.\n",
+ MTK_APDMA_DEFAULT_REQUESTS);
+ }
+
+ for (i = 0; i < MTK_APDMA_CHANNELS; i++) {
+ c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL);
+ if (!c)
+ goto err_no_dma;
+
+ c->vc.desc_free = mtk_dma_desc_free;
+ vchan_init(&c->vc, &mtkd->ddev);
+ INIT_LIST_HEAD(&c->node);
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+
+ rc = dma_async_device_register(&mtkd->ddev);
+ if (rc)
+ goto rpm_disable;
+
+ platform_set_drvdata(pdev, mtkd);
+
+ if (pdev->dev.of_node) {
+ /* Device-tree DMA controller registration */
+ rc = of_dma_controller_register(pdev->dev.of_node,
+ of_dma_xlate_by_chan_id,
+ mtkd);
+ if (rc)
+ goto dma_remove;
+ }
+
+ return rc;
+
+dma_remove:
+ dma_async_device_unregister(&mtkd->ddev);
+rpm_disable:
+ pm_runtime_disable(&pdev->dev);
+err_no_dma:
+ mtk_dma_free(mtkd);
+ return rc;
+}
+
+static int mtk_apdma_remove(struct platform_device *pdev)
+{
+ struct mtk_dmadev *mtkd = platform_get_drvdata(pdev);
+
+ if (pdev->dev.of_node)
+ of_dma_controller_free(pdev->dev.of_node);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
+ dma_async_device_unregister(&mtkd->ddev);
+
+ mtk_dma_free(mtkd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dma_suspend(struct device *dev)
+{
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ if (!pm_runtime_suspended(dev))
+ clk_disable_unprepare(mtkd->clk);
+
+ return 0;
+}
+
+static int mtk_dma_resume(struct device *dev)
+{
+ int ret;
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ if (!pm_runtime_suspended(dev)) {
+ ret = clk_prepare_enable(mtkd->clk);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int mtk_dma_runtime_suspend(struct device *dev)
+{
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(mtkd->clk);
+
+ return 0;
+}
+
+static int mtk_dma_runtime_resume(struct device *dev)
+{
+ int ret;
+ struct mtk_dmadev *mtkd = dev_get_drvdata(dev);
+
+ ret = clk_prepare_enable(mtkd->clk);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_dma_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mtk_dma_suspend, mtk_dma_resume)
+ SET_RUNTIME_PM_OPS(mtk_dma_runtime_suspend,
+ mtk_dma_runtime_resume, NULL)
+};
+
+static struct platform_driver mtk_dma_driver = {
+ .probe = mtk_apdma_probe,
+ .remove = mtk_apdma_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .pm = &mtk_dma_pm_ops,
+ .of_match_table = of_match_ptr(mtk_uart_dma_match),
+ },
+};
+
+module_platform_driver(mtk_dma_driver);
+
+MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");
+MODULE_AUTHOR("Long Cheng <long.cheng@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 27bac0b..bef436e 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -1,4 +1,15 @@
+config DMA_MTK_UART
+ tristate "MediaTek SoCs APDMA support for UART"
+ depends on OF
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ when 8250 mtk uart is enabled, and if you want to using DMA,
+ you can enable the config. the DMA engine just only be used
+ with MediaTek Socs.
+
config MTK_HSDMA
tristate "MediaTek High-Speed DMA controller support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 6e778f8..2f2efd9 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_DMA_MTK_UART) += 8250_mtk_dma.o
obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 2/2] arm: dts: mt2701: add uart APDMA to device tree
From: Long Cheng @ 2018-12-10 2:57 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In-Reply-To: <1544410636-31815-1-git-send-email-long.cheng@mediatek.com>
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function
Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 50 +++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 10
+ &apdma 11>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -378,6 +381,38 @@
status = "disabled";
};
+ apdma: dma-controller@11000400 {
+ compatible = "mediatek,mt2712-uart-dma",
+ "mediatek,mt6577-uart-dma";
+ reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_AP_DMA>;
+ clock-names = "apdma";
+ #dma-cells = <1>;
+ };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
"mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 0
+ &apdma 1>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -395,6 +433,9 @@
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 2
+ &apdma 3>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -405,6 +446,9 @@
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 4
+ &apdma 5>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -415,6 +459,9 @@
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 6
+ &apdma 7>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -629,6 +676,9 @@
interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>;
clocks = <&baud_clk>, <&sys_clk>;
clock-names = "baud", "bus";
+ dmas = <&apdma 8
+ &apdma 9>;
+ dma-names = "tx", "rx";
status = "disabled";
};
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 0/2] add uart DMA function
From: Long Cheng @ 2018-12-10 2:57 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Mark Rutland
Cc: devicetree, Sean Wang, srv_heupstream, Greg Kroah-Hartman,
Sean Wang, linux-kernel, YT Shen, dmaengine, Long Cheng,
linux-mediatek, linux-serial, Jiri Slaby, Matthias Brugger,
Yingjoe Chen, Dan Williams, linux-arm-kernel
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the code under drivers/dma.
This series contains document bindings, Kconfig to control the function enable or not,
device tree including interrupt and dma device node, the code of UART DM
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation
Long Cheng (2):
dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
arm: dts: mt2701: add uart APDMA to device tree
arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 50 ++
drivers/dma/mediatek/8250_mtk_dma.c | 830 +++++++++++++++++++++++++++++
drivers/dma/mediatek/Kconfig | 11 +
drivers/dma/mediatek/Makefile | 1 +
4 files changed, 892 insertions(+)
create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [GIT PULL] ARM: SoC fixes
From: Olof Johansson @ 2018-12-10 1:23 UTC (permalink / raw)
To: torvalds; +Cc: olof, arm, linux-kernel, linux-arm-kernel
Hi Linus,
The following changes since commit 2595646791c319cadfdbf271563aac97d0843dc7:
Linux 4.20-rc5 (2018-12-02 15:07:55 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-fixes
for you to fetch changes up to 0603a9a84679eb12d9dadb97f4e0ba017e684c7b:
Merge tag 'mvebu-fixes-4.20-1' of git://git.infradead.org/linux-mvebu into fixes (2018-12-09 10:28:02 -0800)
----------------------------------------------------------------
ARM: SoC fixes
The usual batch; most of them are DT tweaks to fix misdescribed
hardware. Beyond that:
- A bugfix for MMP2 CPU detection, it's been there quite a while but
makes sense to fix now anyway.
- Some power management tweaks;
+ disabling of CPU idle power state on Marvell Armada 7K/8K (Macchiatobin et al)
+ Increase of minimum voltage on BananaPi M3
+ Tweak of power ramp time for DVFS on NXP/Freescale i.MX7SX
- A couple of MAINTAINER updates; MMP has a new volunteer to look after
it, and Mediatek adds a few keywords, IRC channel and wiki URL.
----------------------------------------------------------------
Anson Huang (1):
ARM: imx: update the cpu power up timing setting on i.mx6sx
Baruch Siach (1):
Revert "arm64: dts: marvell: add CPU Idle power state support on Armada 7K/8K"
Corentin Labbe (1):
ARM: dts: sun8i: a83t: bananapi-m3: increase vcc-pd voltage to 3.3V
Fabio Estevam (2):
ARM: dts: imx7d-pico: Describe the Wifi clock
ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock
Lubomir Rintel (2):
ARM: mmp/mmp2: fix cpu_is_mmp2() on mmp2-dt
MAINTAINERS: update entry for MMP platform
Matthias Brugger (1):
MAINTAINERS: mediatek: Update SoC entry
Olof Johansson (5):
Merge tag 'v4.19-next-fixes' of https://git.kernel.org/.../matthias.bgg/linux into fixes
Merge tag 'arm-soc/for-4.20/devicetree-fixes' of https://github.com/Broadcom/stblinux into fixes
Merge tag 'imx-fixes-4.20-3' of git://git.kernel.org/.../shawnguo/linux into fixes
Merge tag 'sunxi-fixes-for-4.20' of https://git.kernel.org/.../sunxi/linux into fixes
Merge tag 'mvebu-fixes-4.20-1' of git://git.infradead.org/linux-mvebu into fixes
Rob Herring (1):
ARM: dts: realview: Fix some more duplicate regulator nodes
Ryder Lee (3):
arm64: dts: mt7622: fix no more console output on rfb1
arm64: dts: mt7622: fix no more console output on BPI-R64 board
arm64: dts: mt7622: Drop the general purpose timer node
Stefan Wahren (1):
ARM: dts: bcm2837: Fix polarity of wifi reset GPIOs
CREDITS | 8 +++++++
MAINTAINERS | 11 +++++----
arch/arm/boot/dts/arm-realview-pb1176.dts | 4 ++--
arch/arm/boot/dts/arm-realview-pb11mp.dts | 4 ++--
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +-
arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 2 +-
arch/arm/boot/dts/imx7d-nitrogen7.dts | 9 ++++++--
arch/arm/boot/dts/imx7d-pico.dtsi | 22 +++++++++++++++++-
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts | 4 ++--
arch/arm/mach-imx/cpuidle-imx6sx.c | 2 +-
arch/arm/mach-mmp/cputype.h | 6 +++--
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi | 4 ----
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 27 ----------------------
.../boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 7 +++++-
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 7 +++++-
arch/arm64/boot/dts/mediatek/mt7622.dtsi | 10 --------
16 files changed, 67 insertions(+), 62 deletions(-)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [GIT PULL] Allwinner fixes for 4.20
From: Olof Johansson @ 2018-12-09 18:27 UTC (permalink / raw)
To: Maxime Ripard; +Cc: Chen-Yu Tsai, arm, linux-arm-kernel
In-Reply-To: <20181207141819.3sg63se2pgbcaqgi@flea>
On Fri, Dec 07, 2018 at 03:18:19PM +0100, Maxime Ripard wrote:
> Hi Arnd, Kevin, Olof,
>
> Here is a fix for the 4.20 release.
>
> Thanks!
> Maxime
>
> The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a:
>
> Linux 4.20-rc1 (2018-11-04 15:37:52 -0800)
>
> are available in the Git repository at:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-fixes-for-4.20
>
> for you to fetch changes up to 5f8208f557065163f9a8089ea2ea7888f9d96922:
>
> ARM: dts: sun8i: a83t: bananapi-m3: increase vcc-pd voltage to 3.3V (2018-11-14 15:10:57 +0800)
>
> ----------------------------------------------------------------
> Allwinner fixes for 4.20
>
> One small fix for a regulator range on the Banana Pi M3
Merged, thanks!
-Olof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [GIT PULL] ARM: mvebu: fixes for v4.20 (#1)
From: Olof Johansson @ 2018-12-09 18:28 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: Andrew Lunn, Jason Cooper, Arnd Bergmann, arm, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <87efasv2cn.fsf@bootlin.com>
On Sat, Dec 08, 2018 at 09:39:52AM +0100, Gregory CLEMENT wrote:
> Hi,
>
> Here is the first pull request for fixes for mvebu for v4.20.
>
> Gregory
>
> The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a:
>
> Linux 4.20-rc1 (2018-11-04 15:37:52 -0800)
>
> are available in the Git repository at:
>
> git://git.infradead.org/linux-mvebu.git tags/mvebu-fixes-4.20-1
>
> for you to fetch changes up to dae522045094ebfa9a10cf7951a8f79b02da8e15:
>
> Revert "arm64: dts: marvell: add CPU Idle power state support on Armada 7K/8K" (2018-12-05 09:28:17 +0100)
>
> ----------------------------------------------------------------
> mvebu fixes for 4.20
>
> Adding CPU Idle state in the device tree for Armada 8040 seems to
> breaks boot on some board, so let's revert it waiting for a better
> solution.
Merged, thanks!
-Olof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [GIT PULL] i.MX fixes for 4.20, round 3
From: Olof Johansson @ 2018-12-09 18:26 UTC (permalink / raw)
To: Shawn Guo; +Cc: Fabio Estevam, arm, linux-imx, kernel, linux-arm-kernel
In-Reply-To: <20181206151625.GH12929@dragon>
On Thu, Dec 06, 2018 at 11:16:27PM +0800, Shawn Guo wrote:
> The following changes since commit 512cab3e7e0be11234f965d9898936dce2325382:
>
> ARM: dts: imx51-zii-rdu1: Remove EEPROM node (2018-11-19 22:35:45 +0800)
>
> are available in the Git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-4.20-3
>
> for you to fetch changes up to f15096f12a4e9340168df5fdd9201aa8ed60d59e:
>
> ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock (2018-12-06 15:38:28 +0800)
>
> ----------------------------------------------------------------
> i.MX fixes for 4.20, round 3:
> - A couple of fixes on imx7d-pico and imx7d-nitrogen7 boards to correct
> the description of the Wifi clock.
> - Change SW2ISO count to get a safer ARM LDO ramp-up time, so that
> different boards can be covered. This fixes the ARM LDO failure seen
> on some customer boards.
>
> ----------------------------------------------------------------
> Anson Huang (1):
> ARM: imx: update the cpu power up timing setting on i.mx6sx
>
> Fabio Estevam (2):
> ARM: dts: imx7d-pico: Describe the Wifi clock
> ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock
Merged, thanks!
-Olof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v6 3/3] mm: Add /sys/kernel/slab/cache/cache_dma32
From: Nicolas Boichat @ 2018-12-10 1:15 UTC (permalink / raw)
To: Will Deacon
Cc: Michal Hocko, Levin Alexander, linux-mm, Christoph Lameter,
Huaisheng Ye, Joerg Roedel, Matthew Wilcox, hch, linux-arm-kernel,
David Rientjes, yingjoe.chen, Vlastimil Babka, Tomasz Figa,
Mike Rapoport, hsinyi, Matthias Brugger, Joonsoo Kim, Yong Wu,
Robin Murphy, linux-kernel, stable, Pekka Enberg, iommu,
Andrew Morton, Mel Gorman
In-Reply-To: <20181210011504.122604-1-drinkcat@chromium.org>
A previous patch in this series adds support for SLAB_CACHE_DMA32
kmem caches. This adds the corresponding
/sys/kernel/slab/cache/cache_dma32 entries, and fixes slabinfo
tool.
Cc: stable@vger.kernel.org
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
---
There were different opinions on whether this sysfs entry should
be added, so I'll leave it up to the mm/slub maintainers to decide
whether they want to pick this up, or drop it.
No change since v5.
Documentation/ABI/testing/sysfs-kernel-slab | 9 +++++++++
mm/slub.c | 11 +++++++++++
tools/vm/slabinfo.c | 7 ++++++-
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-kernel-slab b/Documentation/ABI/testing/sysfs-kernel-slab
index 29601d93a1c2ea..d742c6cfdffbe9 100644
--- a/Documentation/ABI/testing/sysfs-kernel-slab
+++ b/Documentation/ABI/testing/sysfs-kernel-slab
@@ -106,6 +106,15 @@ Description:
are from ZONE_DMA.
Available when CONFIG_ZONE_DMA is enabled.
+What: /sys/kernel/slab/cache/cache_dma32
+Date: December 2018
+KernelVersion: 4.21
+Contact: Nicolas Boichat <drinkcat@chromium.org>
+Description:
+ The cache_dma32 file is read-only and specifies whether objects
+ are from ZONE_DMA32.
+ Available when CONFIG_ZONE_DMA32 is enabled.
+
What: /sys/kernel/slab/cache/cpu_slabs
Date: May 2007
KernelVersion: 2.6.22
diff --git a/mm/slub.c b/mm/slub.c
index 4caadb926838ef..840f3719d9d543 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5104,6 +5104,14 @@ static ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
SLAB_ATTR_RO(cache_dma);
#endif
+#ifdef CONFIG_ZONE_DMA32
+static ssize_t cache_dma32_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_CACHE_DMA32));
+}
+SLAB_ATTR_RO(cache_dma32);
+#endif
+
static ssize_t usersize_show(struct kmem_cache *s, char *buf)
{
return sprintf(buf, "%u\n", s->usersize);
@@ -5444,6 +5452,9 @@ static struct attribute *slab_attrs[] = {
#ifdef CONFIG_ZONE_DMA
&cache_dma_attr.attr,
#endif
+#ifdef CONFIG_ZONE_DMA32
+ &cache_dma32_attr.attr,
+#endif
#ifdef CONFIG_NUMA
&remote_node_defrag_ratio_attr.attr,
#endif
diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 334b16db0ebbe9..4ee1bf6e498dfa 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -29,7 +29,7 @@ struct slabinfo {
char *name;
int alias;
int refs;
- int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
+ int aliases, align, cache_dma, cache_dma32, cpu_slabs, destroy_by_rcu;
unsigned int hwcache_align, object_size, objs_per_slab;
unsigned int sanity_checks, slab_size, store_user, trace;
int order, poison, reclaim_account, red_zone;
@@ -531,6 +531,8 @@ static void report(struct slabinfo *s)
printf("** Hardware cacheline aligned\n");
if (s->cache_dma)
printf("** Memory is allocated in a special DMA zone\n");
+ if (s->cache_dma32)
+ printf("** Memory is allocated in a special DMA32 zone\n");
if (s->destroy_by_rcu)
printf("** Slabs are destroyed via RCU\n");
if (s->reclaim_account)
@@ -599,6 +601,8 @@ static void slabcache(struct slabinfo *s)
*p++ = '*';
if (s->cache_dma)
*p++ = 'd';
+ if (s->cache_dma32)
+ *p++ = 'D';
if (s->hwcache_align)
*p++ = 'A';
if (s->poison)
@@ -1205,6 +1209,7 @@ static void read_slab_dir(void)
slab->aliases = get_obj("aliases");
slab->align = get_obj("align");
slab->cache_dma = get_obj("cache_dma");
+ slab->cache_dma32 = get_obj("cache_dma32");
slab->cpu_slabs = get_obj("cpu_slabs");
slab->destroy_by_rcu = get_obj("destroy_by_rcu");
slab->hwcache_align = get_obj("hwcache_align");
--
2.20.0.rc2.403.gdbc3b29805-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 1/3] mm: Add support for kmem caches in DMA32 zone
From: Nicolas Boichat @ 2018-12-10 1:15 UTC (permalink / raw)
To: Will Deacon
Cc: Michal Hocko, Levin Alexander, linux-mm, Christoph Lameter,
Huaisheng Ye, Joerg Roedel, Matthew Wilcox, hch, linux-arm-kernel,
David Rientjes, yingjoe.chen, Vlastimil Babka, Tomasz Figa,
Mike Rapoport, hsinyi, Matthias Brugger, Joonsoo Kim, Yong Wu,
Robin Murphy, linux-kernel, stable, Pekka Enberg, iommu,
Andrew Morton, Mel Gorman
In-Reply-To: <20181210011504.122604-1-drinkcat@chromium.org>
IOMMUs using ARMv7 short-descriptor format require page tables
to be allocated within the first 4GB of RAM, even on 64-bit systems.
On arm64, this is done by passing GFP_DMA32 flag to memory allocation
functions.
For IOMMU L2 tables that only take 1KB, it would be a waste to allocate
a full page using get_free_pages, so we considered 3 approaches:
1. This patch, adding support for GFP_DMA32 slab caches.
2. genalloc, which requires pre-allocating the maximum number of L2
page tables (4096, so 4MB of memory).
3. page_frag, which is not very memory-efficient as it is unable
to reuse freed fragments until the whole page is freed.
This change makes it possible to create a custom cache in DMA32 zone
using kmem_cache_create, then allocate memory using kmem_cache_alloc.
We do not create a DMA32 kmalloc cache array, as there are currently
no users of kmalloc(..., GFP_DMA32). These calls will continue to
trigger a warning, as we keep GFP_DMA32 in GFP_SLAB_BUG_MASK.
This implies that calls to kmem_cache_*alloc on a SLAB_CACHE_DMA32
kmem_cache must _not_ use GFP_DMA32 (it is anyway redundant and
unnecessary).
Cc: stable@vger.kernel.org
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
---
Changes since v2:
- Clarified commit message
- Add entry in sysfs-kernel-slab to document the new sysfs file
(v3 used the page_frag approach)
Changes since v4:
- Added details to commit message
- Dropped change that removed GFP_DMA32 from GFP_SLAB_BUG_MASK:
instead we can just call kmem_cache_*alloc without GFP_DMA32
parameter. This also means that we can drop PATCH 1/3, as we
do not make any changes in GFP flag verification.
- Dropped hunks that added cache_dma32 sysfs file, and moved
the hunks to PATCH 3/3, so that maintainer can decide whether
to pick the change independently.
(no change since v5)
include/linux/slab.h | 2 ++
mm/slab.c | 2 ++
mm/slab.h | 3 ++-
mm/slab_common.c | 2 +-
mm/slub.c | 5 +++++
5 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 11b45f7ae4057c..9449b19c5f107a 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -32,6 +32,8 @@
#define SLAB_HWCACHE_ALIGN ((slab_flags_t __force)0x00002000U)
/* Use GFP_DMA memory */
#define SLAB_CACHE_DMA ((slab_flags_t __force)0x00004000U)
+/* Use GFP_DMA32 memory */
+#define SLAB_CACHE_DMA32 ((slab_flags_t __force)0x00008000U)
/* DEBUG: Store the last owner for bug hunting */
#define SLAB_STORE_USER ((slab_flags_t __force)0x00010000U)
/* Panic if kmem_cache_create() fails */
diff --git a/mm/slab.c b/mm/slab.c
index 73fe23e649c91a..124f8c556d27fb 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2109,6 +2109,8 @@ int __kmem_cache_create(struct kmem_cache *cachep, slab_flags_t flags)
cachep->allocflags = __GFP_COMP;
if (flags & SLAB_CACHE_DMA)
cachep->allocflags |= GFP_DMA;
+ if (flags & SLAB_CACHE_DMA32)
+ cachep->allocflags |= GFP_DMA32;
if (flags & SLAB_RECLAIM_ACCOUNT)
cachep->allocflags |= __GFP_RECLAIMABLE;
cachep->size = size;
diff --git a/mm/slab.h b/mm/slab.h
index 4190c24ef0e9df..fcf717e12f0a86 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -127,7 +127,8 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
/* Legal flag mask for kmem_cache_create(), for various configurations */
-#define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | SLAB_PANIC | \
+#define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
+ SLAB_CACHE_DMA32 | SLAB_PANIC | \
SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
#if defined(CONFIG_DEBUG_SLAB)
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 70b0cc85db67f8..18b7b809c8d064 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -53,7 +53,7 @@ static DECLARE_WORK(slab_caches_to_rcu_destroy_work,
SLAB_FAILSLAB | SLAB_KASAN)
#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \
- SLAB_ACCOUNT)
+ SLAB_CACHE_DMA32 | SLAB_ACCOUNT)
/*
* Merge control. If this is set then no merging of slab caches will occur.
diff --git a/mm/slub.c b/mm/slub.c
index c229a9b7dd5448..4caadb926838ef 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3583,6 +3583,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
if (s->flags & SLAB_CACHE_DMA)
s->allocflags |= GFP_DMA;
+ if (s->flags & SLAB_CACHE_DMA32)
+ s->allocflags |= GFP_DMA32;
+
if (s->flags & SLAB_RECLAIM_ACCOUNT)
s->allocflags |= __GFP_RECLAIMABLE;
@@ -5671,6 +5674,8 @@ static char *create_unique_id(struct kmem_cache *s)
*/
if (s->flags & SLAB_CACHE_DMA)
*p++ = 'd';
+ if (s->flags & SLAB_CACHE_DMA32)
+ *p++ = 'D';
if (s->flags & SLAB_RECLAIM_ACCOUNT)
*p++ = 'a';
if (s->flags & SLAB_CONSISTENCY_CHECKS)
--
2.20.0.rc2.403.gdbc3b29805-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 2/3] iommu/io-pgtable-arm-v7s: Request DMA32 memory, and improve debugging
From: Nicolas Boichat @ 2018-12-10 1:15 UTC (permalink / raw)
To: Will Deacon
Cc: Michal Hocko, Levin Alexander, linux-mm, Christoph Lameter,
Huaisheng Ye, Joerg Roedel, Matthew Wilcox, hch, linux-arm-kernel,
David Rientjes, yingjoe.chen, Vlastimil Babka, Tomasz Figa,
Mike Rapoport, hsinyi, Matthias Brugger, Joonsoo Kim, Yong Wu,
Robin Murphy, linux-kernel, stable, Pekka Enberg, iommu,
Andrew Morton, Mel Gorman
In-Reply-To: <20181210011504.122604-1-drinkcat@chromium.org>
IOMMUs using ARMv7 short-descriptor format require page tables
(level 1 and 2) to be allocated within the first 4GB of RAM, even
on 64-bit systems.
For level 1/2 pages, ensure GFP_DMA32 is used if CONFIG_ZONE_DMA32
is defined (e.g. on arm64 platforms).
For level 2 pages, allocate a slab cache in SLAB_CACHE_DMA32. Note
that we do not explicitly pass GFP_DMA[32] to kmem_cache_zalloc,
as this is not strictly necessary, and would cause a warning
in mm/sl*b.c, as we did not update GFP_SLAB_BUG_MASK.
Also, print an error when the physical address does not fit in
32-bit, to make debugging easier in the future.
Cc: stable@vger.kernel.org
Fixes: ad67f5a6545f ("arm64: replace ZONE_DMA with ZONE_DMA32")
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
---
Changes since v2:
- Commit message
(v3 used the page_frag approach)
Changes since v4:
- Do not pass ARM_V7S_TABLE_GFP_DMA to kmem_cache_zalloc, as this
is unnecessary, and would trigger a warning.
Changes since v5:
- Rename ARM_V7S_TABLE_SLAB_CACHE to ARM_V7S_TABLE_SLAB_FLAGS.
drivers/iommu/io-pgtable-arm-v7s.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 445c3bde04800c..d2fdb192f7610f 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -161,6 +161,14 @@
#define ARM_V7S_TCR_PD1 BIT(5)
+#ifdef CONFIG_ZONE_DMA32
+#define ARM_V7S_TABLE_GFP_DMA GFP_DMA32
+#define ARM_V7S_TABLE_SLAB_FLAGS SLAB_CACHE_DMA32
+#else
+#define ARM_V7S_TABLE_GFP_DMA GFP_DMA
+#define ARM_V7S_TABLE_SLAB_FLAGS SLAB_CACHE_DMA
+#endif
+
typedef u32 arm_v7s_iopte;
static bool selftest_running;
@@ -198,13 +206,16 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
void *table = NULL;
if (lvl == 1)
- table = (void *)__get_dma_pages(__GFP_ZERO, get_order(size));
+ table = (void *)__get_free_pages(
+ __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size));
else if (lvl == 2)
- table = kmem_cache_zalloc(data->l2_tables, gfp | GFP_DMA);
+ table = kmem_cache_zalloc(data->l2_tables, gfp);
phys = virt_to_phys(table);
- if (phys != (arm_v7s_iopte)phys)
+ if (phys != (arm_v7s_iopte)phys) {
/* Doesn't fit in PTE */
+ dev_err(dev, "Page table does not fit in PTE: %pa", &phys);
goto out_free;
+ }
if (table && !(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
dma = dma_map_single(dev, table, size, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma))
@@ -737,7 +748,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
data->l2_tables = kmem_cache_create("io-pgtable_armv7s_l2",
ARM_V7S_TABLE_SIZE(2),
ARM_V7S_TABLE_SIZE(2),
- SLAB_CACHE_DMA, NULL);
+ ARM_V7S_TABLE_SLAB_FLAGS, NULL);
if (!data->l2_tables)
goto out_free_data;
--
2.20.0.rc2.403.gdbc3b29805-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 0/3] iommu/io-pgtable-arm-v7s: Use DMA32 zone for page tables
From: Nicolas Boichat @ 2018-12-10 1:15 UTC (permalink / raw)
To: Will Deacon
Cc: Michal Hocko, Levin Alexander, linux-mm, Christoph Lameter,
Huaisheng Ye, Joerg Roedel, Matthew Wilcox, hch, linux-arm-kernel,
David Rientjes, yingjoe.chen, Vlastimil Babka, Tomasz Figa,
Mike Rapoport, hsinyi, Matthias Brugger, Joonsoo Kim, Yong Wu,
Robin Murphy, linux-kernel, stable, Pekka Enberg, iommu,
Andrew Morton, Mel Gorman
This is a follow-up to the discussion in [1], [2].
IOMMUs using ARMv7 short-descriptor format require page tables
(level 1 and 2) to be allocated within the first 4GB of RAM, even
on 64-bit systems.
For L1 tables that are bigger than a page, we can just use __get_free_pages
with GFP_DMA32 (on arm64 systems only, arm would still use GFP_DMA).
For L2 tables that only take 1KB, it would be a waste to allocate a full
page, so we considered 3 approaches:
1. This series, adding support for GFP_DMA32 slab caches.
2. genalloc, which requires pre-allocating the maximum number of L2 page
tables (4096, so 4MB of memory).
3. page_frag, which is not very memory-efficient as it is unable to reuse
freed fragments until the whole page is freed. [3]
This series is the most memory-efficient approach.
stable@ note:
We confirmed that this is a regression, and IOMMU errors happen on 4.19
and linux-next/master on MT8173 (elm, Acer Chromebook R13). The issue
most likely starts from commit ad67f5a6545f ("arm64: replace ZONE_DMA
with ZONE_DMA32"), i.e. 4.15, and presumably breaks a number of Mediatek
platforms (and maybe others?).
[1] https://lists.linuxfoundation.org/pipermail/iommu/2018-November/030876.html
[2] https://lists.linuxfoundation.org/pipermail/iommu/2018-December/031696.html
[3] https://patchwork.codeaurora.org/patch/671639/
Changes since v1:
- Add support for SLAB_CACHE_DMA32 in slab and slub (patches 1/2)
- iommu/io-pgtable-arm-v7s (patch 3):
- Changed approach to use SLAB_CACHE_DMA32 added by the previous
commit.
- Use DMA or DMA32 depending on the architecture (DMA for arm,
DMA32 for arm64).
Changes since v2:
- Reworded and expanded commit messages
- Added cache_dma32 documentation in PATCH 2/3.
v3 used the page_frag approach, see [3].
Changes since v4:
- Dropped change that removed GFP_DMA32 from GFP_SLAB_BUG_MASK:
instead we can just call kmem_cache_*alloc without GFP_DMA32
parameter. This also means that we can drop PATCH v4 1/3, as we
do not make any changes in GFP flag verification.
- Dropped hunks that added cache_dma32 sysfs file, and moved
the hunks to PATCH v5 3/3, so that maintainer can decide whether
to pick the change independently.
Changes since v5:
- Rename ARM_V7S_TABLE_SLAB_CACHE to ARM_V7S_TABLE_SLAB_FLAGS.
- Add stable@ to cc.
Nicolas Boichat (3):
mm: Add support for kmem caches in DMA32 zone
iommu/io-pgtable-arm-v7s: Request DMA32 memory, and improve debugging
mm: Add /sys/kernel/slab/cache/cache_dma32
Documentation/ABI/testing/sysfs-kernel-slab | 9 +++++++++
drivers/iommu/io-pgtable-arm-v7s.c | 19 +++++++++++++++----
include/linux/slab.h | 2 ++
mm/slab.c | 2 ++
mm/slab.h | 3 ++-
mm/slab_common.c | 2 +-
mm/slub.c | 16 ++++++++++++++++
tools/vm/slabinfo.c | 7 ++++++-
8 files changed, 53 insertions(+), 7 deletions(-)
--
2.20.0.rc2.403.gdbc3b29805-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox