diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 752a3848ffdc..4be85c38250f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -8,6 +8,7 @@ config ARM select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB + select ARCH_HAS_DMA_PREP_COHERENT if IOMMU_DMA select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FORTIFY_SOURCE @@ -20,8 +21,8 @@ config ARM select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL select ARCH_HAS_STRICT_MODULE_RWX if MMU - select ARCH_HAS_SYNC_DMA_FOR_DEVICE if SWIOTLB - select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB + select ARCH_HAS_SYNC_DMA_FOR_DEVICE if SWIOTLB || IOMMU_DMA + select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB || IOMMU_DMA select ARCH_HAS_TEARDOWN_DMA_OPS if MMU select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H @@ -121,6 +122,7 @@ config ARM select REFCOUNT_FULL select RTC_LIB select SYS_SUPPORTS_APM_EMULATION + select IOMMU_DMA if IOMMU_SUPPORT # Above selects are sorted alphabetically; please add new ones # according to that. Thanks. help diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 75b5b4ee22e8..ba23f9059cf4 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -2489,8 +2490,9 @@ static void arm_iommu_get_dma_window(struct device *dev, u64 *dma_addr, *dma_size = of_read_number(ranges + naddr, nsize); } -static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, - const struct iommu_ops *iommu) +static bool __maybe_unused +arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, + const struct iommu_ops *iommu) { struct iommu_group *group; struct iommu_domain *domain; @@ -2550,8 +2552,9 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) } #else -static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, - const struct iommu_ops *iommu) +static bool __maybe_unused +arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, + const struct iommu_ops *iommu) { return false; } @@ -2566,10 +2569,9 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, const struct iommu_ops *iommu, bool coherent) { const struct dma_map_ops *dma_ops; - struct dma_iommu_mapping *mapping; dev->archdata.dma_coherent = coherent; -#ifdef CONFIG_SWIOTLB +#if defined(CONFIG_SWIOTLB) || defined(CONFIG_IOMMU_DMA) dev->dma_coherent = coherent; #endif @@ -2581,14 +2583,13 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (dev->dma_ops) return; - if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu)) { - mapping = to_dma_iommu_mapping(dev); - dma_ops = mapping->ops; - } else { - dma_ops = arm_get_dma_map_ops(coherent); - } + if (iommu) + iommu_setup_dma_ops(dev, dma_base, size); - set_dma_ops(dev, dma_ops); + if (!dev->dma_ops) { + dma_ops = arm_get_dma_map_ops(coherent); + set_dma_ops(dev, dma_ops); + } #ifdef CONFIG_XEN if (xen_initial_domain()) @@ -2606,7 +2607,7 @@ void arch_teardown_dma_ops(struct device *dev) arm_teardown_iommu_dma_ops(dev); } -#ifdef CONFIG_SWIOTLB +#if defined(CONFIG_SWIOTLB) || defined(CONFIG_IOMMU_DMA) void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir) { @@ -2620,7 +2621,9 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, __dma_page_dev_to_cpu(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), size, dir); } +#endif +#ifdef CONFIG_SWIOTLB long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, dma_addr_t dma_addr) { @@ -2641,3 +2644,10 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, __arm_dma_free(dev, size, cpu_addr, dma_handle, attrs, false); } #endif /* CONFIG_SWIOTLB */ + +#ifdef CONFIG_IOMMU_DMA +void arch_dma_prep_coherent(struct page *page, size_t size) +{ + __dma_page_cpu_to_dev(page, 0, size, DMA_BIDIRECTIONAL); +} +#endif /* CONFIG_IOMMU_DMA */ diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 329f8c15a1e0..3c482f6a978e 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -469,7 +469,6 @@ config ARM_SMMU depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y select IOMMU_API select IOMMU_IO_PGTABLE_LPAE - select ARM_DMA_USE_IOMMU if ARM help Support for implementations of the ARM System MMU architecture versions 1 and 2.