Skip to content

Commit e09a5cb

Browse files
andy-shevgregkh
authored andcommitted
dmaengine: idma64: Use actual device for DMA transfers
[ Upstream commit 5ba846b ] Intel IOMMU, when enabled, tries to find the domain of the device, assuming it's a PCI one, during DMA operations, such as mapping or unmapping. Since we are splitting the actual PCI device to couple of children via MFD framework (see drivers/mfd/intel-lpss.c for details), the DMA device appears to be a platform one, and thus not an actual one that performs DMA. In a such situation IOMMU can't find or allocate a proper domain for its operations. As a result, all DMA operations are failed. In order to fix this, supply parent of the platform device to the DMA engine framework and fix filter functions accordingly. We may rely on the fact that parent is a real PCI device, because no other configuration is present in the wild. Signed-off-by: Andy Shevchenko <[email protected]> Acked-by: Mark Brown <[email protected]> Acked-by: Greg Kroah-Hartman <[email protected]> [for tty parts] Signed-off-by: Vinod Koul <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent fd8afa9 commit e09a5cb

File tree

4 files changed

+9
-10
lines changed

4 files changed

+9
-10
lines changed

drivers/dma/idma64.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ static int idma64_probe(struct idma64_chip *chip)
589589
idma64->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
590590
idma64->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
591591

592-
idma64->dma.dev = chip->dev;
592+
idma64->dma.dev = chip->sysdev;
593593

594594
dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
595595

@@ -629,6 +629,7 @@ static int idma64_platform_probe(struct platform_device *pdev)
629629
{
630630
struct idma64_chip *chip;
631631
struct device *dev = &pdev->dev;
632+
struct device *sysdev = dev->parent;
632633
struct resource *mem;
633634
int ret;
634635

@@ -645,11 +646,12 @@ static int idma64_platform_probe(struct platform_device *pdev)
645646
if (IS_ERR(chip->regs))
646647
return PTR_ERR(chip->regs);
647648

648-
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
649+
ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
649650
if (ret)
650651
return ret;
651652

652653
chip->dev = dev;
654+
chip->sysdev = sysdev;
653655

654656
ret = idma64_probe(chip);
655657
if (ret)

drivers/dma/idma64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,14 @@ static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
216216
/**
217217
* struct idma64_chip - representation of iDMA 64-bit controller hardware
218218
* @dev: struct device of the DMA controller
219+
* @sysdev: struct device of the physical device that does DMA
219220
* @irq: irq line
220221
* @regs: memory mapped I/O space
221222
* @idma64: struct idma64 that is filed by idma64_probe()
222223
*/
223224
struct idma64_chip {
224225
struct device *dev;
226+
struct device *sysdev;
225227
int irq;
226228
void __iomem *regs;
227229
struct idma64 *idma64;

drivers/spi/spi-pxa2xx.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,12 +1475,7 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
14751475

14761476
static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
14771477
{
1478-
struct device *dev = param;
1479-
1480-
if (dev != chan->device->dev->parent)
1481-
return false;
1482-
1483-
return true;
1478+
return param == chan->device->dev;
14841479
}
14851480

14861481
static struct pxa2xx_spi_master *

drivers/tty/serial/8250/8250_dw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ static bool dw8250_fallback_dma_filter(struct dma_chan *chan, void *param)
269269

270270
static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
271271
{
272-
return param == chan->device->dev->parent;
272+
return param == chan->device->dev;
273273
}
274274

275275
static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
@@ -311,7 +311,7 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
311311
p->set_termios = dw8250_set_termios;
312312
}
313313

314-
/* Platforms with iDMA */
314+
/* Platforms with iDMA 64-bit */
315315
if (platform_get_resource_byname(to_platform_device(p->dev),
316316
IORESOURCE_MEM, "lpss_priv")) {
317317
p->set_termios = dw8250_set_termios;

0 commit comments

Comments
 (0)