diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-06 20:13:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-06 20:13:54 -0400 |
commit | 553911c67eb701d46e2dcd073f603c6f6546c38b (patch) | |
tree | ad5169ecc77a8e647550e2704b64e9a2a9ab3bce /arch | |
parent | 521f3970853a4b2ff7f833763532bdba2ea11257 (diff) | |
parent | c84750906b4818d4929fbf73a4ae6c113b94f52b (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.c | 35 | ||||
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 63 |
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 | ||
443 | static 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 | |||
442 | static struct s3c24xx_dma_platdata s3c2440_dma_platdata = { | 475 | static 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 | ||
448 | struct platform_device s3c2440_device_dma = { | 483 | struct 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 | */ | ||
2024 | static 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; | ||
2046 | fail: | ||
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 | */ | ||
2058 | static 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 | |||
2017 | static void arm_iommu_sync_single_for_cpu(struct device *dev, | 2074 | static 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 | ||
2062 | struct dma_map_ops iommu_coherent_ops = { | 2122 | struct 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 | /** |