diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index c0c941a04ca2..9b7e427fc5bb 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -420,6 +420,8 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, prot |= IOMMU_PRIV; if (attrs & DMA_ATTR_SYS_CACHE_ONLY) prot |= IOMMU_SYS_CACHE_ONLY; + if (attrs & DMA_ATTR_SYS_CACHE_ONLY_NWA) + prot |= IOMMU_SYS_CACHE_ONLY_NWA; switch (dir) { case DMA_BIDIRECTIONAL: diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 562ee1670703..b6106938a94b 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -69,6 +69,15 @@ */ #define DMA_ATTR_SYS_CACHE_ONLY (1UL << 10) +/* + * DMA_ATTR_SYS_CACHE_ONLY_NWA: used to indicate that the buffer should be + * mapped with the correct memory attributes so that it can be cached in the + * system or last level cache, with a no write allocate cache policy. This is + * useful for buffers that are being mapped for devices that are non-coherent, + * but can use the system cache. + */ +#define DMA_ATTR_SYS_CACHE_ONLY_NWA (1UL << 11) + /* * A dma_addr_t can hold any valid DMA or bus address for the platform. It can * be given to a device to use as a DMA source or target. It is specific to a diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index d77f6afd4725..af338251e13e 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -419,7 +419,8 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs) if (attrs & DMA_ATTR_WRITE_COMBINE) return pgprot_writecombine(prot); #endif - if (attrs & DMA_ATTR_SYS_CACHE_ONLY) + if (attrs & DMA_ATTR_SYS_CACHE_ONLY || + attrs & DMA_ATTR_SYS_CACHE_ONLY_NWA) return pgprot_syscached(prot); return pgprot_dmacoherent(prot); }