2019-08-26 13:31:02

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 3/6] dma-mapping: remove arch_dma_mmap_pgprot

arch_dma_mmap_pgprot is used for two things:

1) to override the "normal" uncached page attributes for mapping
memory coherent to devices that can't snoop the CPU caches
2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
arm systems and some mips platforms

Replace one with the pgprot_dmacoherent macro that is already provided
by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
handling to common code with an explicit arch opt-in.

Signed-off-by: Christoph Hellwig <[email protected]>
Acked-by: Geert Uytterhoeven <[email protected]>
---
arch/arm/Kconfig | 2 +-
arch/arm/mm/dma-mapping.c | 6 ------
arch/arm64/Kconfig | 1 -
arch/arm64/include/asm/pgtable.h | 4 ++++
arch/arm64/mm/dma-mapping.c | 6 ------
arch/m68k/Kconfig | 1 -
arch/m68k/include/asm/pgtable_mm.h | 3 +++
arch/m68k/kernel/dma.c | 3 +--
arch/mips/Kconfig | 2 +-
arch/mips/mm/dma-noncoherent.c | 8 --------
include/linux/dma-noncoherent.h | 13 +++++++++++--
kernel/dma/Kconfig | 12 +++++++++---
kernel/dma/mapping.c | 8 +++++---
13 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24360211534a..217083caeabd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,7 +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_MMAP_PGPROT if SWIOTLB
+ select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..d27b12f61737 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return dma_to_pfn(dev, dma_addr);
}

-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return __get_dma_pgprot(attrs, prot);
-}
-
void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsigned long attrs)
{
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..dab9dda34206 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -13,7 +13,6 @@ config ARM64
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN
- select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e09760ece844..6700371227d1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, \
+ PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..676efcda51e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -11,12 +11,6 @@

#include <asm/cacheflush.h>

-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return pgprot_writecombine(prot);
-}
-
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
size_t size, enum dma_data_direction dir)
{
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..a9e564306d3e 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,7 +4,6 @@ config M68K
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT
- select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
index fe3ddd73a0cc..fde4534b974f 100644
--- a/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.h
@@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
: (prot)))

+pgprot_t pgprot_dmacoherent(pgprot_t prot);
+#define pgprot_dmacoherent(prot) pgprot_dmacoherent(prot)
+
#endif /* CONFIG_COLDFIRE */
#include <asm-generic/pgtable.h>
#endif /* !__ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 30cd59caf037..35064150e348 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -23,8 +23,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
cache_push(page_to_phys(page), size);
}

-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
+pgprot_t pgprot_dmacoherent(pgprot_t prot)
{
if (CPU_IS_040_OR_060) {
pgprot_val(prot) &= ~_PAGE_CACHE040;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d50fafd7bf3a..fc88f68ea1ee 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,7 +1119,7 @@ config DMA_PERDEV_COHERENT

config DMA_NONCOHERENT
bool
- select ARCH_HAS_DMA_MMAP_PGPROT
+ select ARCH_HAS_DMA_WRITE_COMBINE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_UNCACHED_SEGMENT
select NEED_DMA_MAP_STATE
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index ed56c6fa7be2..1d4d57dd9acf 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -65,14 +65,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr)));
}

-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- if (attrs & DMA_ATTR_WRITE_COMBINE)
- return pgprot_writecombine(prot);
- return pgprot_noncached(prot);
-}
-
static inline void dma_sync_virt(void *addr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 0bff3d7fac92..dd3de6d88fc0 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -3,6 +3,7 @@
#define _LINUX_DMA_NONCOHERENT_H 1

#include <linux/dma-mapping.h>
+#include <asm/pgtable.h>

#ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
#include <asm/dma-coherence.h>
@@ -42,10 +43,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs);
long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
dma_addr_t dma_addr);
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs);

#ifdef CONFIG_MMU
+/*
+ * Page protection so that devices that can't snoop CPU caches can use the
+ * memory coherently. We default to pgprot_noncached which is usually used
+ * for ioremap as a safe bet, but architectures can override this with less
+ * strict semantics if possible.
+ */
+#ifndef pgprot_dmacoherent
+#define pgprot_dmacoherent(prot) pgprot_noncached(prot)
+#endif
+
pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
#else
static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 9decbba255fc..73c5c2b8e824 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -20,6 +20,15 @@ config ARCH_HAS_DMA_COHERENCE_H
config ARCH_HAS_DMA_SET_MASK
bool

+#
+# Select this option if the architecture needs special handling for
+# DMA_ATTR_WRITE_COMBINE. Normally the "uncached" mapping should be what
+# people thing of when saying write combine, so very few platforms should
+# need to enable this.
+#
+config ARCH_HAS_DMA_WRITE_COMBINE
+ bool
+
config DMA_DECLARE_COHERENT
bool

@@ -45,9 +54,6 @@ config ARCH_HAS_DMA_PREP_COHERENT
config ARCH_HAS_DMA_COHERENT_TO_PFN
bool

-config ARCH_HAS_DMA_MMAP_PGPROT
- bool
-
config ARCH_HAS_FORCE_DMA_UNENCRYPTED
bool

diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..1b96616c9f20 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -161,9 +161,11 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
(IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
(attrs & DMA_ATTR_NON_CONSISTENT)))
return prot;
- if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT))
- return arch_dma_mmap_pgprot(dev, prot, attrs);
- return pgprot_noncached(prot);
+#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE
+ if (attrs & DMA_ATTR_WRITE_COMBINE)
+ return pgprot_writecombine(prot);
+#endif
+ return pgprot_dmacoherent(prot);
}
#endif /* CONFIG_MMU */

--
2.20.1


2019-08-27 10:04:14

by Paul Burton

[permalink] [raw]
Subject: Re: [PATCH 3/6] dma-mapping: remove arch_dma_mmap_pgprot

Hi Christoph,

On Mon, Aug 26, 2019 at 03:25:50PM +0200, Christoph Hellwig wrote:
> arch_dma_mmap_pgprot is used for two things:
>
> 1) to override the "normal" uncached page attributes for mapping
> memory coherent to devices that can't snoop the CPU caches
> 2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
> arm systems and some mips platforms
>
> Replace one with the pgprot_dmacoherent macro that is already provided
> by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
> handling to common code with an explicit arch opt-in.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> Acked-by: Geert Uytterhoeven <[email protected]>

For the MIPS bits:

Acked-by: Paul Burton <[email protected]>

Thanks,
Paul

> ---
> arch/arm/Kconfig | 2 +-
> arch/arm/mm/dma-mapping.c | 6 ------
> arch/arm64/Kconfig | 1 -
> arch/arm64/include/asm/pgtable.h | 4 ++++
> arch/arm64/mm/dma-mapping.c | 6 ------
> arch/m68k/Kconfig | 1 -
> arch/m68k/include/asm/pgtable_mm.h | 3 +++
> arch/m68k/kernel/dma.c | 3 +--
> arch/mips/Kconfig | 2 +-
> arch/mips/mm/dma-noncoherent.c | 8 --------
> include/linux/dma-noncoherent.h | 13 +++++++++++--
> kernel/dma/Kconfig | 12 +++++++++---
> kernel/dma/mapping.c | 8 +++++---
> 13 files changed, 35 insertions(+), 34 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 24360211534a..217083caeabd 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -8,7 +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_MMAP_PGPROT if SWIOTLB
> + select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
> select ARCH_HAS_ELF_RANDOMIZE
> select ARCH_HAS_FORTIFY_SOURCE
> select ARCH_HAS_KEEPINITRD
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index d42557ee69c2..d27b12f61737 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
> return dma_to_pfn(dev, dma_addr);
> }
>
> -pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> - unsigned long attrs)
> -{
> - return __get_dma_pgprot(attrs, prot);
> -}
> -
> void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
> gfp_t gfp, unsigned long attrs)
> {
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 3adcec05b1f6..dab9dda34206 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -13,7 +13,6 @@ config ARM64
> select ARCH_HAS_DEBUG_VIRTUAL
> select ARCH_HAS_DEVMEM_IS_ALLOWED
> select ARCH_HAS_DMA_COHERENT_TO_PFN
> - select ARCH_HAS_DMA_MMAP_PGPROT
> select ARCH_HAS_DMA_PREP_COHERENT
> select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
> select ARCH_HAS_ELF_RANDOMIZE
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index e09760ece844..6700371227d1 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
> __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
> #define pgprot_device(prot) \
> __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
> +#define pgprot_dmacoherent(prot) \
> + __pgprot_modify(prot, PTE_ATTRINDX_MASK, \
> + PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
> +
> #define __HAVE_PHYS_MEM_ACCESS_PROT
> struct file;
> extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index bd2b039f43a6..676efcda51e6 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -11,12 +11,6 @@
>
> #include <asm/cacheflush.h>
>
> -pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> - unsigned long attrs)
> -{
> - return pgprot_writecombine(prot);
> -}
> -
> void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
> size_t size, enum dma_data_direction dir)
> {
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index c518d695c376..a9e564306d3e 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -4,7 +4,6 @@ config M68K
> default y
> select ARCH_32BIT_OFF_T
> select ARCH_HAS_BINFMT_FLAT
> - select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
> select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
> select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
> select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
> diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
> index fe3ddd73a0cc..fde4534b974f 100644
> --- a/arch/m68k/include/asm/pgtable_mm.h
> +++ b/arch/m68k/include/asm/pgtable_mm.h
> @@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
> ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
> : (prot)))
>
> +pgprot_t pgprot_dmacoherent(pgprot_t prot);
> +#define pgprot_dmacoherent(prot) pgprot_dmacoherent(prot)
> +
> #endif /* CONFIG_COLDFIRE */
> #include <asm-generic/pgtable.h>
> #endif /* !__ASSEMBLY__ */
> diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
> index 30cd59caf037..35064150e348 100644
> --- a/arch/m68k/kernel/dma.c
> +++ b/arch/m68k/kernel/dma.c
> @@ -23,8 +23,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
> cache_push(page_to_phys(page), size);
> }
>
> -pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> - unsigned long attrs)
> +pgprot_t pgprot_dmacoherent(pgprot_t prot)
> {
> if (CPU_IS_040_OR_060) {
> pgprot_val(prot) &= ~_PAGE_CACHE040;
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index d50fafd7bf3a..fc88f68ea1ee 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -1119,7 +1119,7 @@ config DMA_PERDEV_COHERENT
>
> config DMA_NONCOHERENT
> bool
> - select ARCH_HAS_DMA_MMAP_PGPROT
> + select ARCH_HAS_DMA_WRITE_COMBINE
> select ARCH_HAS_SYNC_DMA_FOR_DEVICE
> select ARCH_HAS_UNCACHED_SEGMENT
> select NEED_DMA_MAP_STATE
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
> index ed56c6fa7be2..1d4d57dd9acf 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -65,14 +65,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
> return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr)));
> }
>
> -pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> - unsigned long attrs)
> -{
> - if (attrs & DMA_ATTR_WRITE_COMBINE)
> - return pgprot_writecombine(prot);
> - return pgprot_noncached(prot);
> -}
> -
> static inline void dma_sync_virt(void *addr, size_t size,
> enum dma_data_direction dir)
> {
> diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
> index 0bff3d7fac92..dd3de6d88fc0 100644
> --- a/include/linux/dma-noncoherent.h
> +++ b/include/linux/dma-noncoherent.h
> @@ -3,6 +3,7 @@
> #define _LINUX_DMA_NONCOHERENT_H 1
>
> #include <linux/dma-mapping.h>
> +#include <asm/pgtable.h>
>
> #ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
> #include <asm/dma-coherence.h>
> @@ -42,10 +43,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t dma_addr, unsigned long attrs);
> long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
> dma_addr_t dma_addr);
> -pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> - unsigned long attrs);
>
> #ifdef CONFIG_MMU
> +/*
> + * Page protection so that devices that can't snoop CPU caches can use the
> + * memory coherently. We default to pgprot_noncached which is usually used
> + * for ioremap as a safe bet, but architectures can override this with less
> + * strict semantics if possible.
> + */
> +#ifndef pgprot_dmacoherent
> +#define pgprot_dmacoherent(prot) pgprot_noncached(prot)
> +#endif
> +
> pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
> #else
> static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,
> diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
> index 9decbba255fc..73c5c2b8e824 100644
> --- a/kernel/dma/Kconfig
> +++ b/kernel/dma/Kconfig
> @@ -20,6 +20,15 @@ config ARCH_HAS_DMA_COHERENCE_H
> config ARCH_HAS_DMA_SET_MASK
> bool
>
> +#
> +# Select this option if the architecture needs special handling for
> +# DMA_ATTR_WRITE_COMBINE. Normally the "uncached" mapping should be what
> +# people thing of when saying write combine, so very few platforms should
> +# need to enable this.
> +#
> +config ARCH_HAS_DMA_WRITE_COMBINE
> + bool
> +
> config DMA_DECLARE_COHERENT
> bool
>
> @@ -45,9 +54,6 @@ config ARCH_HAS_DMA_PREP_COHERENT
> config ARCH_HAS_DMA_COHERENT_TO_PFN
> bool
>
> -config ARCH_HAS_DMA_MMAP_PGPROT
> - bool
> -
> config ARCH_HAS_FORCE_DMA_UNENCRYPTED
> bool
>
> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> index b0038ca3aa92..1b96616c9f20 100644
> --- a/kernel/dma/mapping.c
> +++ b/kernel/dma/mapping.c
> @@ -161,9 +161,11 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
> (IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
> (attrs & DMA_ATTR_NON_CONSISTENT)))
> return prot;
> - if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT))
> - return arch_dma_mmap_pgprot(dev, prot, attrs);
> - return pgprot_noncached(prot);
> +#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE
> + if (attrs & DMA_ATTR_WRITE_COMBINE)
> + return pgprot_writecombine(prot);
> +#endif
> + return pgprot_dmacoherent(prot);
> }
> #endif /* CONFIG_MMU */
>
> --
> 2.20.1
>