aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 20:13:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 20:13:54 -0400
commit553911c67eb701d46e2dcd073f603c6f6546c38b (patch)
treead5169ecc77a8e647550e2704b64e9a2a9ab3bce /arch
parent521f3970853a4b2ff7f833763532bdba2ea11257 (diff)
parentc84750906b4818d4929fbf73a4ae6c113b94f52b (diff)
Merge tag 'dmaengine-4.9-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul: "This is bit large pile of code which bring in some nice additions: - Error reporting: we have added a new mechanism for users of dmaenegine to register a callback_result which tells them the result of the dma transaction. Right now only one user (ntb) is using it. - As we discussed on KS mailing list and pointed out NO_IRQ has no place in kernel, this also remove NO_IRQ from dmaengine subsystem (both arm and ppc users) - Support for IOMMU slave transfers and its implementation for arm. - To get better build coverage, enable COMPILE_TEST for bunch of driver, and fix the warning and sparse complaints on these. - Apart from above, usual updates spread across drivers" * tag 'dmaengine-4.9-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (169 commits) async_pq_val: fix DMA memory leak dmaengine: virt-dma: move function declarations dmaengine: omap-dma: Enable burst and data pack for SG DT: dmaengine: rcar-dmac: document R8A7743/5 support dmaengine: fsldma: Unmap region obtained by of_iomap dmaengine: jz4780: fix resource leaks on error exit return dma-debug: fix ia64 build, use PHYS_PFN dmaengine: coh901318: fix integer overflow when shifting more than 32 places dmaengine: edma: avoid uninitialized variable use dma-mapping: fix m32r build warning dma-mapping: fix ia64 build, use PHYS_PFN dmaengine: ti-dma-crossbar: enable COMPILE_TEST dmaengine: omap-dma: enable COMPILE_TEST dmaengine: edma: enable COMPILE_TEST dmaengine: ti-dma-crossbar: Fix of_device_id data parameter usage dmaengine: ti-dma-crossbar: Correct type for of_find_property() third parameter dmaengine/ARM: omap-dma: Fix the DMAengine compile test on non OMAP configs dmaengine: edma: Rename set_bits and remove unused clear_bits helper dmaengine: edma: Use correct type for of_find_property() third parameter dmaengine: edma: Fix of_device_id data parameter usage (legacy vs TPCC) ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c24xx/common.c35
-rw-r--r--arch/arm/mm/dma-mapping.c63
2 files changed, 98 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index bf50328107bd..ba0ceebdd73d 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -33,6 +33,7 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/io.h> 34#include <linux/io.h>
35#include <linux/platform_data/dma-s3c24xx.h> 35#include <linux/platform_data/dma-s3c24xx.h>
36#include <linux/dmaengine.h>
36 37
37#include <mach/hardware.h> 38#include <mach/hardware.h>
38#include <mach/regs-clock.h> 39#include <mach/regs-clock.h>
@@ -439,10 +440,44 @@ static struct s3c24xx_dma_channel s3c2440_dma_channels[DMACH_MAX] = {
439 [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), }, 440 [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
440}; 441};
441 442
443static const struct dma_slave_map s3c2440_dma_slave_map[] = {
444 /* TODO: DMACH_XD0 */
445 /* TODO: DMACH_XD1 */
446 { "s3c2440-sdi", "rx-tx", (void *)DMACH_SDI },
447 { "s3c2410-spi.0", "rx", (void *)DMACH_SPI0 },
448 { "s3c2410-spi.0", "tx", (void *)DMACH_SPI0 },
449 { "s3c2410-spi.1", "rx", (void *)DMACH_SPI1 },
450 { "s3c2410-spi.1", "tx", (void *)DMACH_SPI1 },
451 { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
452 { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
453 { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
454 { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
455 { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
456 { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
457 { "s3c2440-uart.3", "rx", (void *)DMACH_UART3 },
458 { "s3c2440-uart.3", "tx", (void *)DMACH_UART3 },
459 /* TODO: DMACH_TIMER */
460 { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
461 { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
462 { "samsung-ac97", "rx", (void *)DMACH_PCM_IN },
463 { "samsung-ac97", "tx", (void *)DMACH_PCM_OUT },
464 { "samsung-ac97", "rx", (void *)DMACH_MIC_IN },
465 { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
466 { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
467 { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
468 { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
469 { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
470 { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
471 { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
472 { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
473};
474
442static struct s3c24xx_dma_platdata s3c2440_dma_platdata = { 475static struct s3c24xx_dma_platdata s3c2440_dma_platdata = {
443 .num_phy_channels = 4, 476 .num_phy_channels = 4,
444 .channels = s3c2440_dma_channels, 477 .channels = s3c2440_dma_channels,
445 .num_channels = DMACH_MAX, 478 .num_channels = DMACH_MAX,
479 .slave_map = s3c2440_dma_slave_map,
480 .slavecnt = ARRAY_SIZE(s3c2440_dma_slave_map),
446}; 481};
447 482
448struct platform_device s3c2440_device_dma = { 483struct platform_device s3c2440_device_dma = {
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index a2302aba5df2..ab4f74536057 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2014,6 +2014,63 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
2014 __free_iova(mapping, iova, len); 2014 __free_iova(mapping, iova, len);
2015} 2015}
2016 2016
2017/**
2018 * arm_iommu_map_resource - map a device resource for DMA
2019 * @dev: valid struct device pointer
2020 * @phys_addr: physical address of resource
2021 * @size: size of resource to map
2022 * @dir: DMA transfer direction
2023 */
2024static dma_addr_t arm_iommu_map_resource(struct device *dev,
2025 phys_addr_t phys_addr, size_t size,
2026 enum dma_data_direction dir, unsigned long attrs)
2027{
2028 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
2029 dma_addr_t dma_addr;
2030 int ret, prot;
2031 phys_addr_t addr = phys_addr & PAGE_MASK;
2032 unsigned int offset = phys_addr & ~PAGE_MASK;
2033 size_t len = PAGE_ALIGN(size + offset);
2034
2035 dma_addr = __alloc_iova(mapping, len);
2036 if (dma_addr == DMA_ERROR_CODE)
2037 return dma_addr;
2038
2039 prot = __dma_direction_to_prot(dir) | IOMMU_MMIO;
2040
2041 ret = iommu_map(mapping->domain, dma_addr, addr, len, prot);
2042 if (ret < 0)
2043 goto fail;
2044
2045 return dma_addr + offset;
2046fail:
2047 __free_iova(mapping, dma_addr, len);
2048 return DMA_ERROR_CODE;
2049}
2050
2051/**
2052 * arm_iommu_unmap_resource - unmap a device DMA resource
2053 * @dev: valid struct device pointer
2054 * @dma_handle: DMA address to resource
2055 * @size: size of resource to map
2056 * @dir: DMA transfer direction
2057 */
2058static void arm_iommu_unmap_resource(struct device *dev, dma_addr_t dma_handle,
2059 size_t size, enum dma_data_direction dir,
2060 unsigned long attrs)
2061{
2062 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
2063 dma_addr_t iova = dma_handle & PAGE_MASK;
2064 unsigned int offset = dma_handle & ~PAGE_MASK;
2065 size_t len = PAGE_ALIGN(size + offset);
2066
2067 if (!iova)
2068 return;
2069
2070 iommu_unmap(mapping->domain, iova, len);
2071 __free_iova(mapping, iova, len);
2072}
2073
2017static void arm_iommu_sync_single_for_cpu(struct device *dev, 2074static void arm_iommu_sync_single_for_cpu(struct device *dev,
2018 dma_addr_t handle, size_t size, enum dma_data_direction dir) 2075 dma_addr_t handle, size_t size, enum dma_data_direction dir)
2019{ 2076{
@@ -2057,6 +2114,9 @@ struct dma_map_ops iommu_ops = {
2057 .unmap_sg = arm_iommu_unmap_sg, 2114 .unmap_sg = arm_iommu_unmap_sg,
2058 .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu, 2115 .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu,
2059 .sync_sg_for_device = arm_iommu_sync_sg_for_device, 2116 .sync_sg_for_device = arm_iommu_sync_sg_for_device,
2117
2118 .map_resource = arm_iommu_map_resource,
2119 .unmap_resource = arm_iommu_unmap_resource,
2060}; 2120};
2061 2121
2062struct dma_map_ops iommu_coherent_ops = { 2122struct dma_map_ops iommu_coherent_ops = {
@@ -2070,6 +2130,9 @@ struct dma_map_ops iommu_coherent_ops = {
2070 2130
2071 .map_sg = arm_coherent_iommu_map_sg, 2131 .map_sg = arm_coherent_iommu_map_sg,
2072 .unmap_sg = arm_coherent_iommu_unmap_sg, 2132 .unmap_sg = arm_coherent_iommu_unmap_sg,
2133
2134 .map_resource = arm_iommu_map_resource,
2135 .unmap_resource = arm_iommu_unmap_resource,
2073}; 2136};
2074 2137
2075/** 2138/**