]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.51/dmaengine-idma64-use-actual-device-for-dma-transfers.patch
Linux 4.19.51
[thirdparty/kernel/stable-queue.git] / releases / 4.19.51 / dmaengine-idma64-use-actual-device-for-dma-transfers.patch
CommitLineData
37554d48
SL
1From 95b62ae2004cab12f3b0fdc71d58c66223b747b8 Mon Sep 17 00:00:00 2001
2From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
3Date: Mon, 18 Mar 2019 18:39:30 +0300
4Subject: dmaengine: idma64: Use actual device for DMA transfers
5
6[ Upstream commit 5ba846b1ee0792f5a596b9b0b86d6e8cdebfab06 ]
7
8Intel IOMMU, when enabled, tries to find the domain of the device,
9assuming it's a PCI one, during DMA operations, such as mapping or
10unmapping. Since we are splitting the actual PCI device to couple of
11children via MFD framework (see drivers/mfd/intel-lpss.c for details),
12the DMA device appears to be a platform one, and thus not an actual one
13that performs DMA. In a such situation IOMMU can't find or allocate
14a proper domain for its operations. As a result, all DMA operations are
15failed.
16
17In order to fix this, supply parent of the platform device
18to the DMA engine framework and fix filter functions accordingly.
19
20We may rely on the fact that parent is a real PCI device, because no
21other configuration is present in the wild.
22
23Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
24Acked-by: Mark Brown <broonie@kernel.org>
25Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [for tty parts]
26Signed-off-by: Vinod Koul <vkoul@kernel.org>
27Signed-off-by: Sasha Levin <sashal@kernel.org>
28---
29 drivers/dma/idma64.c | 6 ++++--
30 drivers/dma/idma64.h | 2 ++
31 drivers/spi/spi-pxa2xx.c | 7 +------
32 drivers/tty/serial/8250/8250_dw.c | 4 ++--
33 4 files changed, 9 insertions(+), 10 deletions(-)
34
35diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
36index 1fbf9cb9b742..89c5e5b46068 100644
37--- a/drivers/dma/idma64.c
38+++ b/drivers/dma/idma64.c
39@@ -597,7 +597,7 @@ static int idma64_probe(struct idma64_chip *chip)
40 idma64->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
41 idma64->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
42
43- idma64->dma.dev = chip->dev;
44+ idma64->dma.dev = chip->sysdev;
45
46 dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
47
48@@ -637,6 +637,7 @@ static int idma64_platform_probe(struct platform_device *pdev)
49 {
50 struct idma64_chip *chip;
51 struct device *dev = &pdev->dev;
52+ struct device *sysdev = dev->parent;
53 struct resource *mem;
54 int ret;
55
56@@ -653,11 +654,12 @@ static int idma64_platform_probe(struct platform_device *pdev)
57 if (IS_ERR(chip->regs))
58 return PTR_ERR(chip->regs);
59
60- ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
61+ ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
62 if (ret)
63 return ret;
64
65 chip->dev = dev;
66+ chip->sysdev = sysdev;
67
68 ret = idma64_probe(chip);
69 if (ret)
70diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h
71index 6b816878e5e7..baa32e1425de 100644
72--- a/drivers/dma/idma64.h
73+++ b/drivers/dma/idma64.h
74@@ -216,12 +216,14 @@ static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
75 /**
76 * struct idma64_chip - representation of iDMA 64-bit controller hardware
77 * @dev: struct device of the DMA controller
78+ * @sysdev: struct device of the physical device that does DMA
79 * @irq: irq line
80 * @regs: memory mapped I/O space
81 * @idma64: struct idma64 that is filed by idma64_probe()
82 */
83 struct idma64_chip {
84 struct device *dev;
85+ struct device *sysdev;
86 int irq;
87 void __iomem *regs;
88 struct idma64 *idma64;
89diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
90index 729be74621e3..f41333817c50 100644
91--- a/drivers/spi/spi-pxa2xx.c
92+++ b/drivers/spi/spi-pxa2xx.c
93@@ -1416,12 +1416,7 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
94
95 static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
96 {
97- struct device *dev = param;
98-
99- if (dev != chan->device->dev->parent)
100- return false;
101-
102- return true;
103+ return param == chan->device->dev;
104 }
105
106 static struct pxa2xx_spi_master *
107diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
108index d31b975dd3fd..284e8d052fc3 100644
109--- a/drivers/tty/serial/8250/8250_dw.c
110+++ b/drivers/tty/serial/8250/8250_dw.c
111@@ -365,7 +365,7 @@ static bool dw8250_fallback_dma_filter(struct dma_chan *chan, void *param)
112
113 static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
114 {
115- return param == chan->device->dev->parent;
116+ return param == chan->device->dev;
117 }
118
119 /*
120@@ -434,7 +434,7 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
121 data->uart_16550_compatible = true;
122 }
123
124- /* Platforms with iDMA */
125+ /* Platforms with iDMA 64-bit */
126 if (platform_get_resource_byname(to_platform_device(p->dev),
127 IORESOURCE_MEM, "lpss_priv")) {
128 data->dma.rx_param = p->dev->parent;
129--
1302.20.1
131