All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2] Change dma_attrs from bitfield to unsigned long
@ 2016-05-30 11:54 ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu
  Cc: hch, sstabellini, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz

Hi,


This is second attempt to bring some safeness to dma_attrs.
In v1 [0] I added const to data pointed by attrs. However Christoph
Hellwig suggested getting rid of struct dma_attrs in favor of
some simpler data type.


Benefits of unsigned long for dma_attrs:
1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.


The problem is that the patch touches the dma-mapping API so all
the users have to be converted (ARM and ARM64 as of now).

Any ideas to split it per smaller patches?

The work is not finished yet, I would rather get some feedback before
progressing further.


Best regards,
Krzysztof


Krzysztof Kozlowski (1):
  dma-mapping: Use unsigned long for dma_attrs

 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] Change dma_attrs from bitfield to unsigned long
@ 2016-05-30 11:54 ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,


This is second attempt to bring some safeness to dma_attrs.
In v1 [0] I added const to data pointed by attrs. However Christoph
Hellwig suggested getting rid of struct dma_attrs in favor of
some simpler data type.


Benefits of unsigned long for dma_attrs:
1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.


The problem is that the patch touches the dma-mapping API so all
the users have to be converted (ARM and ARM64 as of now).

Any ideas to split it per smaller patches?

The work is not finished yet, I would rather get some feedback before
progressing further.


Best regards,
Krzysztof


Krzysztof Kozlowski (1):
  dma-mapping: Use unsigned long for dma_attrs

 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-30 11:54   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu
  Cc: hch, sstabellini, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz

The dma-mapping core and the implementations do not change the
DMA attributes passed by pointer.  Thus the pointer can point to const
data.  However the attributes do not have to be a bitfield. Instead
unsigned long will do fine:

1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.

Please have in mind that this is RFC, not finished yet.  Only ARM and
ARM64 are fixed (and not everywhere).
However other API users also have to be converted which is quite
intrusive.  I would rather avoid it until the overall approach is
accepted.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 45ef3f279c3b..0b55cb7c5aaa 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
 struct dma_attrs*.
 
 struct dma_attrs encapsulates a set of "DMA attributes". For the
-definition of struct dma_attrs see linux/dma-attrs.h.
+definition of struct dma_attrs see linux/dma-mapping.h.
 
 The interpretation of DMA attributes is architecture-specific, and
 each attribute should be documented in Documentation/DMA-attributes.txt.
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index e8cf9cf873b3..2d455a5cf671 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -2,7 +2,7 @@
 			==============
 
 This document describes the semantics of the DMA attributes that are
-defined in linux/dma-attrs.h.
+defined in linux/dma-mapping.h.
 
 DMA_ATTR_WRITE_BARRIER
 ----------------------
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a83570f10124..d009f7911ffc 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,7 +5,6 @@
 
 #include <linux/mm_types.h>
 #include <linux/scatterlist.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 
 #include <asm/memory.h>
@@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
  * to be the device-viewed address.
  */
 extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-			   gfp_t gfp, struct dma_attrs *attrs);
+			   gfp_t gfp, unsigned long attrs);
 
 /**
  * arm_dma_free - free memory allocated by arm_dma_alloc
@@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * during and after this call executing are illegal.
  */
 extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			 dma_addr_t handle, struct dma_attrs *attrs);
+			 dma_addr_t handle, unsigned long attrs);
 
 /**
  * arm_dma_mmap - map a coherent DMA allocation into user space
@@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
  */
 extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs);
+			unsigned long attrs);
 
 /*
  * This can be called during early boot to increase the size of the atomic
@@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
  * The scatter list versions of the above methods.
  */
 extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 9408a994cc91..95ce6ac3a971 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -2,15 +2,14 @@
 #define _ASM_ARM_XEN_PAGE_COHERENT_H
 
 #include <asm/page.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-mapping.h>
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs);
+	     enum dma_data_direction dir, unsigned long attrs);
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
@@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
 static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flags,
-		struct dma_attrs *attrs)
+		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
 {
 	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
 }
 
 static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-		void *cpu_addr, dma_addr_t dma_handle,
-		struct dma_attrs *attrs)
+		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
 {
 	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page_pfn = page_to_xen_pfn(page);
 	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
@@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 }
 
 static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long pfn = PFN_DOWN(handle);
 	/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ff7ed5697d3e..fe31fbfd926d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  */
 static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 
 static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 }
@@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  * whatever the device wrote there.
  */
 static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
@@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
 EXPORT_SYMBOL(arm_dma_ops);
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs);
+				  dma_addr_t handle, unsigned long attrs);
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs);
+		 unsigned long attrs);
 
 struct dma_map_ops arm_coherent_dma_ops = {
 	.alloc			= arm_coherent_dma_alloc,
@@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
-static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 {
 	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
 			    pgprot_writecombine(prot) :
@@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
 
 static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 			 gfp_t gfp, pgprot_t prot, bool is_coherent,
-			 struct dma_attrs *attrs, const void *caller)
+			 unsigned long attrs, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
 	struct page *page = NULL;
@@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * virtual and bus address for that space.
  */
 void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-		    gfp_t gfp, struct dma_attrs *attrs)
+		    gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 
@@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 }
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
 			   attrs, __builtin_return_address(0));
@@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
 
 static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	int ret = -ENXIO;
 #ifdef CONFIG_MMU
@@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  */
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
 int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 #ifdef CONFIG_MMU
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
@@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  * Free a buffer as defined by the above mapping.
  */
 static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			   dma_addr_t handle, struct dma_attrs *attrs,
+			   dma_addr_t handle, unsigned long attrs,
 			   bool is_coherent)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
@@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 }
 
 void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle, struct dma_attrs *attrs)
+		  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
 }
 
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs)
+				  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
 	int ret;
@@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
  * here.
  */
 int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 static const int iommu_order_array[] = { 9, 8, 4, 0 };
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					  gfp_t gfp, unsigned long attrs)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1342,7 +1341,7 @@ error:
 }
 
 static int __iommu_free_buffer(struct device *dev, struct page **pages,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	int count = size >> PAGE_SHIFT;
 	int i;
@@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
 	return (struct page **)page;
 }
 
-static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
 {
 	struct vm_struct *area;
 
@@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 }
 
 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1532,7 +1531,7 @@ err_buffer:
 
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		    struct dma_attrs *attrs)
+		    unsigned long attrs)
 {
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
@@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * Must not be called with IRQs disabled.
  */
 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+			  dma_addr_t handle, unsigned long attrs)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
@@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 
 static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t dma_addr,
-				 size_t size, struct dma_attrs *attrs)
+				 size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
@@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
  */
 static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
 			  size_t size, dma_addr_t *handle,
-			  enum dma_data_direction dir, struct dma_attrs *attrs,
+			  enum dma_data_direction dir, unsigned long attrs,
 			  bool is_coherent)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
@@ -1676,7 +1675,7 @@ fail:
 }
 
 static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		     enum dma_data_direction dir, struct dma_attrs *attrs,
+		     enum dma_data_direction dir, unsigned long attrs,
 		     bool is_coherent)
 {
 	struct scatterlist *s = sg, *dma = sg, *start = sg;
@@ -1734,7 +1733,7 @@ bad_mapping:
  * obtained via sg_dma_{address,length}.
  */
 int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
  * sg_dma_{address,length}.
  */
 int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
 }
 
 static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
-		bool is_coherent)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs, bool is_coherent)
 {
 	struct scatterlist *s;
 	int i;
@@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir, struct dma_attrs *attrs)
+			enum dma_data_direction dir,
+			unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
 }
@@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
  */
 static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t dma_addr;
@@ -1889,7 +1890,7 @@ fail:
  */
 static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
  * Coherent IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
  * IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
 	if (!iova)
 		return;
 
+	// FIXME: replace get with simple check
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(page, offset, size, dir);
 
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index c5f9a9e3d1f3..fc67ed236a10 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	if (is_device_dma_coherent(hwdev))
 		return;
@@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
 
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		unsigned long attrs)
 
 {
 	if (is_device_dma_coherent(hwdev))
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec83719f..a7686028dfeb 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -29,7 +29,7 @@
 
 #include <asm/cacheflush.h>
 
-static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
+static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
 				 bool coherent)
 {
 	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
@@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	if (dev == NULL) {
 		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
@@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
 
 static void __dma_free_coherent(struct device *dev, size_t size,
 				void *vaddr, dma_addr_t dma_handle,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool freed;
 	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
@@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
 
 static void *__dma_alloc(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t flags,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct page *page;
 	void *ptr, *coherent_ptr;
@@ -185,7 +185,7 @@ no_mem:
 
 static void __dma_free(struct device *dev, size_t size,
 		       void *vaddr, dma_addr_t dma_handle,
-		       struct dma_attrs *attrs)
+		       unsigned long attrs)
 {
 	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
 
@@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 				     unsigned long offset, size_t size,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	dma_addr_t dev_addr;
 
@@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 
 static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 				 size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	if (!is_device_dma_coherent(dev))
 		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
@@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 
 static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				  int nelems, enum dma_data_direction dir,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i, ret;
@@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __swiotlb_unmap_sg_attrs(struct device *dev,
 				     struct scatterlist *sgl, int nelems,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
 static int __swiotlb_mmap(struct device *dev,
 			  struct vm_area_struct *vma,
 			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	int ret = -ENXIO;
 	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
@@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
 
 static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t handle, size_t size,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
 
@@ -425,21 +425,21 @@ out:
 
 static void *__dummy_alloc(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	return NULL;
 }
 
 static void __dummy_free(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 }
 
 static int __dummy_mmap(struct device *dev,
 			struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	return -ENXIO;
 }
@@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
 static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	return DMA_ERROR_CODE;
 }
 
 static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 }
 
 static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 			  int nelems, enum dma_data_direction dir,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	return 0;
 }
@@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 static void __dummy_unmap_sg(struct device *dev,
 			     struct scatterlist *sgl, int nelems,
 			     enum dma_data_direction dir,
-			     struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 }
 
@@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
 
 static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 				 dma_addr_t *handle, gfp_t gfp,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
@@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 }
 
 static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			       dma_addr_t handle, struct dma_attrs *attrs)
+			       dma_addr_t handle,
+			       unsigned long attrs)
 {
 	size_t iosize = size;
 
@@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 	 * Hence how dodgy the below logic looks...
 	 */
 	if (__in_atomic_pool(cpu_addr, size)) {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_from_pool(cpu_addr, size);
 	} else if (is_vmalloc_addr(cpu_addr)){
 		struct vm_struct *area = find_vm_area(cpu_addr);
@@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 		iommu_dma_free(dev, area->pages, iosize, &handle);
 		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
 	} else {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_pages(virt_to_page(cpu_addr), get_order(size));
 	}
 }
 
 static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			      struct dma_attrs *attrs)
+			      unsigned long attrs)
 {
 	struct vm_struct *area;
 	int ret;
@@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 
 static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 			       void *cpu_addr, dma_addr_t dma_addr,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct vm_struct *area = find_vm_area(cpu_addr);
@@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
 static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int prot = dma_direction_to_prot(dir, coherent);
@@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 
 static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
@@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
 
 static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				int nelems, enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 
@@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __iommu_unmap_sg_attrs(struct device *dev,
 				   struct scatterlist *sgl, int nelems,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 67dcd6831291..dd091175fc2d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
 
 	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 493552368295..f65e6b7ef93b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-attrs.h>
 #include <linux/of.h>
 
 #include <drm/drmP.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cdf9f1af4347..f2ae72ba7d5a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -24,7 +24,7 @@
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
 	struct drm_device *dev = exynos_gem->base.dev;
-	enum dma_attr attr;
+	unsigned long attr;
 	unsigned int nr_pages;
 	struct sg_table sgt;
 	int ret = -ENOMEM;
@@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 		return 0;
 	}
 
-	init_dma_attrs(&exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs = 0;
 
 	/*
 	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
@@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	 * as possible.
 	 */
 	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
-		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
+		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
 
 	/*
 	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
@@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	else
 		attr = DMA_ATTR_NON_CONSISTENT;
 
-	dma_set_attr(attr, &exynos_gem->dma_attrs);
-	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs |= attr;
+	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
 
 	nr_pages = exynos_gem->size >> PAGE_SHIFT;
 
@@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
 					     &exynos_gem->dma_addr, GFP_KERNEL,
-					     &exynos_gem->dma_attrs);
+					     exynos_gem->dma_attrs);
 	if (!exynos_gem->cookie) {
 		DRM_ERROR("failed to allocate buffer.\n");
 		goto err_free;
@@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
 				    exynos_gem->dma_addr, exynos_gem->size,
-				    &exynos_gem->dma_attrs);
+				    exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to get sgtable.\n");
 		goto err_dma_free;
@@ -99,7 +99,7 @@ err_sgt_free:
 	sg_free_table(&sgt);
 err_dma_free:
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
-		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
+		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
 err_free:
 	drm_free_large(exynos_gem->pages);
 
@@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
 
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
 			(dma_addr_t)exynos_gem->dma_addr,
-			&exynos_gem->dma_attrs);
+			exynos_gem->dma_attrs);
 
 	drm_free_large(exynos_gem->pages);
 }
@@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
 
 	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 78100742281d..df7c543d6558 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -50,7 +50,7 @@ struct exynos_drm_gem {
 	void			*cookie;
 	void __iomem		*kvaddr;
 	dma_addr_t		dma_addr;
-	struct dma_attrs	dma_attrs;
+	unsigned long		dma_attrs;
 	struct page		**pages;
 	struct sg_table		*sgt;
 };
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ea5a9ebf0f78..6c1bda504fb1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
  *	   or NULL on failure.
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t))
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
@@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
 }
 
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
 }
@@ -560,7 +560,7 @@ out_restore_sg:
 }
 
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	/*
 	 * The scatterlist segments are mapped into a single
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 7399782c0998..87e6035c9e81 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -294,7 +294,7 @@ error:
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr, struct dma_attrs *attrs)
+			  dma_addr_t dev_addr, unsigned long attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
@@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
 dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				unsigned long offset, size_t size,
 				enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = xen_phys_to_bus(phys);
@@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
  */
 static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 			     size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
 
@@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			    size_t size, enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
 }
@@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
 int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
 void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
deleted file mode 100644
index 5246239a4953..000000000000
--- a/include/linux/dma-attrs.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _DMA_ATTR_H
-#define _DMA_ATTR_H
-
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
-#include <linux/bug.h>
-
-/**
- * an enum dma_attr represents an attribute associated with a DMA
- * mapping. The semantics of each attribute should be defined in
- * Documentation/DMA-attributes.txt.
- */
-enum dma_attr {
-	DMA_ATTR_WRITE_BARRIER,
-	DMA_ATTR_WEAK_ORDERING,
-	DMA_ATTR_WRITE_COMBINE,
-	DMA_ATTR_NON_CONSISTENT,
-	DMA_ATTR_NO_KERNEL_MAPPING,
-	DMA_ATTR_SKIP_CPU_SYNC,
-	DMA_ATTR_FORCE_CONTIGUOUS,
-	DMA_ATTR_ALLOC_SINGLE_PAGES,
-	DMA_ATTR_MAX,
-};
-
-#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
-
-/**
- * struct dma_attrs - an opaque container for DMA attributes
- * @flags - bitmask representing a collection of enum dma_attr
- */
-struct dma_attrs {
-	unsigned long flags[__DMA_ATTRS_LONGS];
-};
-
-#define DEFINE_DMA_ATTRS(x) 					\
-	struct dma_attrs x = {					\
-		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
-	}
-
-static inline void init_dma_attrs(struct dma_attrs *attrs)
-{
-	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
-}
-
-/**
- * dma_set_attr - set a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	__set_bit(attr, attrs->flags);
-}
-
-/**
- * dma_get_attr - check for a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return 0;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	return test_bit(attr, attrs->flags);
-}
-
-#endif /* _DMA_ATTR_H */
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 8443bbb5c071..81c5c8d167ad 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
  * the arch code to take care of attributes and cache maintenance
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t));
 void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
 		dma_addr_t *handle);
@@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
  * directly as DMA mapping callbacks for simplicity
  */
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 int iommu_dma_supported(struct device *dev, u64 mask);
 int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 71c1b215ef66..19e581d5f8b4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -5,13 +5,25 @@
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
 #include <linux/kmemcheck.h>
 #include <linux/bug.h>
 
+/**
+ * List of possible attributes associated with a DMA mapping. The semantics
+ * of each attribute should be defined in Documentation/DMA-attributes.txt.
+ */
+#define DMA_ATTR_WRITE_BARRIER		BIT(1)
+#define DMA_ATTR_WEAK_ORDERING		BIT(2)
+#define DMA_ATTR_WRITE_COMBINE		BIT(3)
+#define DMA_ATTR_NON_CONSISTENT		BIT(4)
+#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
+#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
+#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
+#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
+
 /*
  * 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.  A CPU cannot
@@ -21,34 +33,35 @@
 struct dma_map_ops {
 	void* (*alloc)(struct device *dev, size_t size,
 				dma_addr_t *dma_handle, gfp_t gfp,
-				struct dma_attrs *attrs);
+				unsigned long attrs);
 	void (*free)(struct device *dev, size_t size,
 			      void *vaddr, dma_addr_t dma_handle,
-			      struct dma_attrs *attrs);
+			      unsigned long attrs);
 	int (*mmap)(struct device *, struct vm_area_struct *,
-			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
+			  void *, dma_addr_t, size_t,
+			  unsigned long attrs);
 
 	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
-			   dma_addr_t, size_t, struct dma_attrs *attrs);
+			   dma_addr_t, size_t, unsigned long attrs);
 
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
 			   size_t size, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 	/*
 	 * map_sg returns 0 on error and a value > 0 on success.
 	 * It should never return a value < 0.
 	 */
 	int (*map_sg)(struct device *dev, struct scatterlist *sg,
 		      int nents, enum dma_data_direction dir,
-		      struct dma_attrs *attrs);
+		      unsigned long attrs);
 	void (*unmap_sg)(struct device *dev,
 			 struct scatterlist *sg, int nents,
 			 enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 	void (*sync_single_for_cpu)(struct device *dev,
 				    dma_addr_t dma_handle, size_t size,
 				    enum dma_data_direction dir);
@@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
 	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
 }
 
+/**
+ * dma_get_attr - check for a specific attribute
+ * @attr: attribute to look for
+ * @attrs: attributes to check within
+ */
+static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
+{
+	return !!(attr & attrs);
+}
+
 #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 /*
  * These three functions are only for dma allocator.
@@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 					      size_t size,
 					      enum dma_data_direction dir,
-					      struct dma_attrs *attrs)
+					      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	dma_addr_t addr;
@@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
 					  size_t size,
 					  enum dma_data_direction dir,
-					  struct dma_attrs *attrs)
+					  unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
  */
 static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 				   int nents, enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	int i, ents;
@@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 
 static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 				      int nents, enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
 	BUG_ON(!valid_dma_direction(dir));
-	addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	addr = ops->map_page(dev, page, offset, size, dir, 0);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
 
 	return addr;
@@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
 
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
-		ops->unmap_page(dev, addr, size, dir, NULL);
+		ops->unmap_page(dev, addr, size, dir, 0);
 	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
@@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 
 }
 
-#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
-#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
-#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
-#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
 
 extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
@@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
  */
 static inline int
 dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
-	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
 	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
 
 int
 dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
@@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 
 static inline int
 dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
-		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+		      dma_addr_t dma_addr, size_t size,
+		      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
 }
 
-#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
 
 #ifndef arch_dma_alloc_attrs
 #define arch_dma_alloc_attrs(dev, flag)	(true)
@@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 
 static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
-				       struct dma_attrs *attrs)
+				       unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
@@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 
 static inline void dma_free_attrs(struct device *dev, size_t size,
 				     void *cpu_addr, dma_addr_t dma_handle,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t flag)
 {
-	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
+	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
+	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
 }
 
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_handle, gfp,
+			       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline void dma_free_noncoherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+	dma_free_attrs(dev, size, cpu_addr, dma_handle,
+		       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
 static inline void *dma_alloc_wc(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_addr, gfp,
+			       DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_alloc_writecombine
 #define dma_alloc_writecombine dma_alloc_wc
@@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
 static inline void dma_free_wc(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
+	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_free_writecombine
 #define dma_free_writecombine dma_free_wc
@@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
 			      void *cpu_addr, dma_addr_t dma_addr,
 			      size_t size)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_mmap_writecombine
 #define dma_mmap_writecombine dma_mmap_wc
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 017fced60242..5f81f8a187f2 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -6,7 +6,6 @@
 #include <linux/types.h>
 
 struct device;
-struct dma_attrs;
 struct page;
 struct scatterlist;
 
@@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 
 extern int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 
 extern int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs);
+		     enum dma_data_direction dir,
+		     unsigned long attrs);
 
 extern void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 		       int nelems, enum dma_data_direction dir,
-		       struct dma_attrs *attrs);
+		       unsigned long attrs);
 
 extern void
 swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 8b2eb93ae8ba..7c35e279d1e3 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t flags,
-			    struct dma_attrs *attrs);
+			    unsigned long attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
 			  void *vaddr, dma_addr_t dma_handle,
-			  struct dma_attrs *attrs);
+			  unsigned long attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
 				       enum dma_data_direction dir,
-				       struct dma_attrs *attrs);
+				       unsigned long attrs);
 
 extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 				   size_t size, enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 
 extern void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 
 extern void
 xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/lib/dma-noop.c b/lib/dma-noop.c
index 72145646857e..3d766e78fbe2 100644
--- a/lib/dma-noop.c
+++ b/lib/dma-noop.c
@@ -10,7 +10,7 @@
 
 static void *dma_noop_alloc(struct device *dev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t gfp,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	void *ret;
 
@@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 
 static void dma_noop_free(struct device *dev, size_t size,
 			  void *cpu_addr, dma_addr_t dma_addr,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
@@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
 static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
 				      unsigned long offset, size_t size,
 				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	return page_to_phys(page) + offset;
 }
 
 static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
+			     enum dma_data_direction dir,
+			     unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 76f29ecba8f4..22e13a0e19d7 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
 dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 			    unsigned long offset, size_t size,
 			    enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = phys_to_dma(dev, phys);
@@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			size_t size, enum dma_data_direction dir,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	unmap_single(hwdev, dev_addr, size, dir);
 }
@@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  */
 int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs)
+		     enum dma_data_direction dir, unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -914,7 +914,7 @@ int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 	       enum dma_data_direction dir)
 {
-	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_map_sg);
 
@@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
  */
 void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
-		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
+		       int nelems, enum dma_data_direction dir,
+		       unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -941,7 +942,7 @@ void
 swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 		 enum dma_data_direction dir)
 {
-	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_unmap_sg);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-30 11:54   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: hch-wEGCiKHe2LqWVfeAwA7xHQ, Krzysztof Kozlowski,
	sstabellini-DgEjT+Ai2ygdnm+yROfE0A, Bartlomiej Zolnierkiewicz

The dma-mapping core and the implementations do not change the
DMA attributes passed by pointer.  Thus the pointer can point to const
data.  However the attributes do not have to be a bitfield. Instead
unsigned long will do fine:

1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.

Please have in mind that this is RFC, not finished yet.  Only ARM and
ARM64 are fixed (and not everywhere).
However other API users also have to be converted which is quite
intrusive.  I would rather avoid it until the overall approach is
accepted.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 45ef3f279c3b..0b55cb7c5aaa 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
 struct dma_attrs*.
 
 struct dma_attrs encapsulates a set of "DMA attributes". For the
-definition of struct dma_attrs see linux/dma-attrs.h.
+definition of struct dma_attrs see linux/dma-mapping.h.
 
 The interpretation of DMA attributes is architecture-specific, and
 each attribute should be documented in Documentation/DMA-attributes.txt.
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index e8cf9cf873b3..2d455a5cf671 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -2,7 +2,7 @@
 			==============
 
 This document describes the semantics of the DMA attributes that are
-defined in linux/dma-attrs.h.
+defined in linux/dma-mapping.h.
 
 DMA_ATTR_WRITE_BARRIER
 ----------------------
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a83570f10124..d009f7911ffc 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,7 +5,6 @@
 
 #include <linux/mm_types.h>
 #include <linux/scatterlist.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 
 #include <asm/memory.h>
@@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
  * to be the device-viewed address.
  */
 extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-			   gfp_t gfp, struct dma_attrs *attrs);
+			   gfp_t gfp, unsigned long attrs);
 
 /**
  * arm_dma_free - free memory allocated by arm_dma_alloc
@@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * during and after this call executing are illegal.
  */
 extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			 dma_addr_t handle, struct dma_attrs *attrs);
+			 dma_addr_t handle, unsigned long attrs);
 
 /**
  * arm_dma_mmap - map a coherent DMA allocation into user space
@@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
  */
 extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs);
+			unsigned long attrs);
 
 /*
  * This can be called during early boot to increase the size of the atomic
@@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
  * The scatter list versions of the above methods.
  */
 extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 9408a994cc91..95ce6ac3a971 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -2,15 +2,14 @@
 #define _ASM_ARM_XEN_PAGE_COHERENT_H
 
 #include <asm/page.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-mapping.h>
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs);
+	     enum dma_data_direction dir, unsigned long attrs);
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
@@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
 static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flags,
-		struct dma_attrs *attrs)
+		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
 {
 	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
 }
 
 static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-		void *cpu_addr, dma_addr_t dma_handle,
-		struct dma_attrs *attrs)
+		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
 {
 	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page_pfn = page_to_xen_pfn(page);
 	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
@@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 }
 
 static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long pfn = PFN_DOWN(handle);
 	/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ff7ed5697d3e..fe31fbfd926d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  */
 static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 
 static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 }
@@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  * whatever the device wrote there.
  */
 static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
@@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
 EXPORT_SYMBOL(arm_dma_ops);
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs);
+				  dma_addr_t handle, unsigned long attrs);
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs);
+		 unsigned long attrs);
 
 struct dma_map_ops arm_coherent_dma_ops = {
 	.alloc			= arm_coherent_dma_alloc,
@@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
-static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 {
 	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
 			    pgprot_writecombine(prot) :
@@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
 
 static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 			 gfp_t gfp, pgprot_t prot, bool is_coherent,
-			 struct dma_attrs *attrs, const void *caller)
+			 unsigned long attrs, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
 	struct page *page = NULL;
@@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * virtual and bus address for that space.
  */
 void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-		    gfp_t gfp, struct dma_attrs *attrs)
+		    gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 
@@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 }
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
 			   attrs, __builtin_return_address(0));
@@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
 
 static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	int ret = -ENXIO;
 #ifdef CONFIG_MMU
@@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  */
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
 int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 #ifdef CONFIG_MMU
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
@@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  * Free a buffer as defined by the above mapping.
  */
 static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			   dma_addr_t handle, struct dma_attrs *attrs,
+			   dma_addr_t handle, unsigned long attrs,
 			   bool is_coherent)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
@@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 }
 
 void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle, struct dma_attrs *attrs)
+		  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
 }
 
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs)
+				  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
 	int ret;
@@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
  * here.
  */
 int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 static const int iommu_order_array[] = { 9, 8, 4, 0 };
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					  gfp_t gfp, unsigned long attrs)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1342,7 +1341,7 @@ error:
 }
 
 static int __iommu_free_buffer(struct device *dev, struct page **pages,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	int count = size >> PAGE_SHIFT;
 	int i;
@@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
 	return (struct page **)page;
 }
 
-static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
 {
 	struct vm_struct *area;
 
@@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 }
 
 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1532,7 +1531,7 @@ err_buffer:
 
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		    struct dma_attrs *attrs)
+		    unsigned long attrs)
 {
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
@@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * Must not be called with IRQs disabled.
  */
 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+			  dma_addr_t handle, unsigned long attrs)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
@@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 
 static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t dma_addr,
-				 size_t size, struct dma_attrs *attrs)
+				 size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
@@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
  */
 static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
 			  size_t size, dma_addr_t *handle,
-			  enum dma_data_direction dir, struct dma_attrs *attrs,
+			  enum dma_data_direction dir, unsigned long attrs,
 			  bool is_coherent)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
@@ -1676,7 +1675,7 @@ fail:
 }
 
 static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		     enum dma_data_direction dir, struct dma_attrs *attrs,
+		     enum dma_data_direction dir, unsigned long attrs,
 		     bool is_coherent)
 {
 	struct scatterlist *s = sg, *dma = sg, *start = sg;
@@ -1734,7 +1733,7 @@ bad_mapping:
  * obtained via sg_dma_{address,length}.
  */
 int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
  * sg_dma_{address,length}.
  */
 int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
 }
 
 static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
-		bool is_coherent)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs, bool is_coherent)
 {
 	struct scatterlist *s;
 	int i;
@@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir, struct dma_attrs *attrs)
+			enum dma_data_direction dir,
+			unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
 }
@@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
  */
 static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t dma_addr;
@@ -1889,7 +1890,7 @@ fail:
  */
 static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
  * Coherent IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
  * IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
 	if (!iova)
 		return;
 
+	// FIXME: replace get with simple check
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(page, offset, size, dir);
 
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index c5f9a9e3d1f3..fc67ed236a10 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	if (is_device_dma_coherent(hwdev))
 		return;
@@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
 
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		unsigned long attrs)
 
 {
 	if (is_device_dma_coherent(hwdev))
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec83719f..a7686028dfeb 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -29,7 +29,7 @@
 
 #include <asm/cacheflush.h>
 
-static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
+static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
 				 bool coherent)
 {
 	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
@@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	if (dev == NULL) {
 		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
@@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
 
 static void __dma_free_coherent(struct device *dev, size_t size,
 				void *vaddr, dma_addr_t dma_handle,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool freed;
 	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
@@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
 
 static void *__dma_alloc(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t flags,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct page *page;
 	void *ptr, *coherent_ptr;
@@ -185,7 +185,7 @@ no_mem:
 
 static void __dma_free(struct device *dev, size_t size,
 		       void *vaddr, dma_addr_t dma_handle,
-		       struct dma_attrs *attrs)
+		       unsigned long attrs)
 {
 	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
 
@@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 				     unsigned long offset, size_t size,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	dma_addr_t dev_addr;
 
@@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 
 static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 				 size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	if (!is_device_dma_coherent(dev))
 		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
@@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 
 static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				  int nelems, enum dma_data_direction dir,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i, ret;
@@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __swiotlb_unmap_sg_attrs(struct device *dev,
 				     struct scatterlist *sgl, int nelems,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
 static int __swiotlb_mmap(struct device *dev,
 			  struct vm_area_struct *vma,
 			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	int ret = -ENXIO;
 	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
@@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
 
 static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t handle, size_t size,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
 
@@ -425,21 +425,21 @@ out:
 
 static void *__dummy_alloc(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	return NULL;
 }
 
 static void __dummy_free(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 }
 
 static int __dummy_mmap(struct device *dev,
 			struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	return -ENXIO;
 }
@@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
 static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	return DMA_ERROR_CODE;
 }
 
 static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 }
 
 static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 			  int nelems, enum dma_data_direction dir,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	return 0;
 }
@@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 static void __dummy_unmap_sg(struct device *dev,
 			     struct scatterlist *sgl, int nelems,
 			     enum dma_data_direction dir,
-			     struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 }
 
@@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
 
 static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 				 dma_addr_t *handle, gfp_t gfp,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
@@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 }
 
 static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			       dma_addr_t handle, struct dma_attrs *attrs)
+			       dma_addr_t handle,
+			       unsigned long attrs)
 {
 	size_t iosize = size;
 
@@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 	 * Hence how dodgy the below logic looks...
 	 */
 	if (__in_atomic_pool(cpu_addr, size)) {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_from_pool(cpu_addr, size);
 	} else if (is_vmalloc_addr(cpu_addr)){
 		struct vm_struct *area = find_vm_area(cpu_addr);
@@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 		iommu_dma_free(dev, area->pages, iosize, &handle);
 		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
 	} else {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_pages(virt_to_page(cpu_addr), get_order(size));
 	}
 }
 
 static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			      struct dma_attrs *attrs)
+			      unsigned long attrs)
 {
 	struct vm_struct *area;
 	int ret;
@@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 
 static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 			       void *cpu_addr, dma_addr_t dma_addr,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct vm_struct *area = find_vm_area(cpu_addr);
@@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
 static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int prot = dma_direction_to_prot(dir, coherent);
@@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 
 static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
@@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
 
 static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				int nelems, enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 
@@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __iommu_unmap_sg_attrs(struct device *dev,
 				   struct scatterlist *sgl, int nelems,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 67dcd6831291..dd091175fc2d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
 
 	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 493552368295..f65e6b7ef93b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-attrs.h>
 #include <linux/of.h>
 
 #include <drm/drmP.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cdf9f1af4347..f2ae72ba7d5a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -24,7 +24,7 @@
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
 	struct drm_device *dev = exynos_gem->base.dev;
-	enum dma_attr attr;
+	unsigned long attr;
 	unsigned int nr_pages;
 	struct sg_table sgt;
 	int ret = -ENOMEM;
@@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 		return 0;
 	}
 
-	init_dma_attrs(&exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs = 0;
 
 	/*
 	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
@@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	 * as possible.
 	 */
 	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
-		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
+		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
 
 	/*
 	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
@@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	else
 		attr = DMA_ATTR_NON_CONSISTENT;
 
-	dma_set_attr(attr, &exynos_gem->dma_attrs);
-	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs |= attr;
+	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
 
 	nr_pages = exynos_gem->size >> PAGE_SHIFT;
 
@@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
 					     &exynos_gem->dma_addr, GFP_KERNEL,
-					     &exynos_gem->dma_attrs);
+					     exynos_gem->dma_attrs);
 	if (!exynos_gem->cookie) {
 		DRM_ERROR("failed to allocate buffer.\n");
 		goto err_free;
@@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
 				    exynos_gem->dma_addr, exynos_gem->size,
-				    &exynos_gem->dma_attrs);
+				    exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to get sgtable.\n");
 		goto err_dma_free;
@@ -99,7 +99,7 @@ err_sgt_free:
 	sg_free_table(&sgt);
 err_dma_free:
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
-		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
+		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
 err_free:
 	drm_free_large(exynos_gem->pages);
 
@@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
 
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
 			(dma_addr_t)exynos_gem->dma_addr,
-			&exynos_gem->dma_attrs);
+			exynos_gem->dma_attrs);
 
 	drm_free_large(exynos_gem->pages);
 }
@@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
 
 	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 78100742281d..df7c543d6558 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -50,7 +50,7 @@ struct exynos_drm_gem {
 	void			*cookie;
 	void __iomem		*kvaddr;
 	dma_addr_t		dma_addr;
-	struct dma_attrs	dma_attrs;
+	unsigned long		dma_attrs;
 	struct page		**pages;
 	struct sg_table		*sgt;
 };
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ea5a9ebf0f78..6c1bda504fb1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
  *	   or NULL on failure.
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t))
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
@@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
 }
 
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
 }
@@ -560,7 +560,7 @@ out_restore_sg:
 }
 
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	/*
 	 * The scatterlist segments are mapped into a single
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 7399782c0998..87e6035c9e81 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -294,7 +294,7 @@ error:
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr, struct dma_attrs *attrs)
+			  dma_addr_t dev_addr, unsigned long attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
@@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
 dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				unsigned long offset, size_t size,
 				enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = xen_phys_to_bus(phys);
@@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
  */
 static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 			     size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
 
@@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			    size_t size, enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
 }
@@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
 int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
 void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
deleted file mode 100644
index 5246239a4953..000000000000
--- a/include/linux/dma-attrs.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _DMA_ATTR_H
-#define _DMA_ATTR_H
-
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
-#include <linux/bug.h>
-
-/**
- * an enum dma_attr represents an attribute associated with a DMA
- * mapping. The semantics of each attribute should be defined in
- * Documentation/DMA-attributes.txt.
- */
-enum dma_attr {
-	DMA_ATTR_WRITE_BARRIER,
-	DMA_ATTR_WEAK_ORDERING,
-	DMA_ATTR_WRITE_COMBINE,
-	DMA_ATTR_NON_CONSISTENT,
-	DMA_ATTR_NO_KERNEL_MAPPING,
-	DMA_ATTR_SKIP_CPU_SYNC,
-	DMA_ATTR_FORCE_CONTIGUOUS,
-	DMA_ATTR_ALLOC_SINGLE_PAGES,
-	DMA_ATTR_MAX,
-};
-
-#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
-
-/**
- * struct dma_attrs - an opaque container for DMA attributes
- * @flags - bitmask representing a collection of enum dma_attr
- */
-struct dma_attrs {
-	unsigned long flags[__DMA_ATTRS_LONGS];
-};
-
-#define DEFINE_DMA_ATTRS(x) 					\
-	struct dma_attrs x = {					\
-		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
-	}
-
-static inline void init_dma_attrs(struct dma_attrs *attrs)
-{
-	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
-}
-
-/**
- * dma_set_attr - set a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	__set_bit(attr, attrs->flags);
-}
-
-/**
- * dma_get_attr - check for a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return 0;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	return test_bit(attr, attrs->flags);
-}
-
-#endif /* _DMA_ATTR_H */
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 8443bbb5c071..81c5c8d167ad 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
  * the arch code to take care of attributes and cache maintenance
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t));
 void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
 		dma_addr_t *handle);
@@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
  * directly as DMA mapping callbacks for simplicity
  */
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 int iommu_dma_supported(struct device *dev, u64 mask);
 int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 71c1b215ef66..19e581d5f8b4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -5,13 +5,25 @@
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
 #include <linux/kmemcheck.h>
 #include <linux/bug.h>
 
+/**
+ * List of possible attributes associated with a DMA mapping. The semantics
+ * of each attribute should be defined in Documentation/DMA-attributes.txt.
+ */
+#define DMA_ATTR_WRITE_BARRIER		BIT(1)
+#define DMA_ATTR_WEAK_ORDERING		BIT(2)
+#define DMA_ATTR_WRITE_COMBINE		BIT(3)
+#define DMA_ATTR_NON_CONSISTENT		BIT(4)
+#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
+#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
+#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
+#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
+
 /*
  * 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.  A CPU cannot
@@ -21,34 +33,35 @@
 struct dma_map_ops {
 	void* (*alloc)(struct device *dev, size_t size,
 				dma_addr_t *dma_handle, gfp_t gfp,
-				struct dma_attrs *attrs);
+				unsigned long attrs);
 	void (*free)(struct device *dev, size_t size,
 			      void *vaddr, dma_addr_t dma_handle,
-			      struct dma_attrs *attrs);
+			      unsigned long attrs);
 	int (*mmap)(struct device *, struct vm_area_struct *,
-			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
+			  void *, dma_addr_t, size_t,
+			  unsigned long attrs);
 
 	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
-			   dma_addr_t, size_t, struct dma_attrs *attrs);
+			   dma_addr_t, size_t, unsigned long attrs);
 
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
 			   size_t size, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 	/*
 	 * map_sg returns 0 on error and a value > 0 on success.
 	 * It should never return a value < 0.
 	 */
 	int (*map_sg)(struct device *dev, struct scatterlist *sg,
 		      int nents, enum dma_data_direction dir,
-		      struct dma_attrs *attrs);
+		      unsigned long attrs);
 	void (*unmap_sg)(struct device *dev,
 			 struct scatterlist *sg, int nents,
 			 enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 	void (*sync_single_for_cpu)(struct device *dev,
 				    dma_addr_t dma_handle, size_t size,
 				    enum dma_data_direction dir);
@@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
 	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
 }
 
+/**
+ * dma_get_attr - check for a specific attribute
+ * @attr: attribute to look for
+ * @attrs: attributes to check within
+ */
+static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
+{
+	return !!(attr & attrs);
+}
+
 #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 /*
  * These three functions are only for dma allocator.
@@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 					      size_t size,
 					      enum dma_data_direction dir,
-					      struct dma_attrs *attrs)
+					      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	dma_addr_t addr;
@@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
 					  size_t size,
 					  enum dma_data_direction dir,
-					  struct dma_attrs *attrs)
+					  unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
  */
 static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 				   int nents, enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	int i, ents;
@@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 
 static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 				      int nents, enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
 	BUG_ON(!valid_dma_direction(dir));
-	addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	addr = ops->map_page(dev, page, offset, size, dir, 0);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
 
 	return addr;
@@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
 
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
-		ops->unmap_page(dev, addr, size, dir, NULL);
+		ops->unmap_page(dev, addr, size, dir, 0);
 	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
@@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 
 }
 
-#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
-#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
-#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
-#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
 
 extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
@@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
  */
 static inline int
 dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
-	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
 	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
 
 int
 dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
@@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 
 static inline int
 dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
-		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+		      dma_addr_t dma_addr, size_t size,
+		      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
 }
 
-#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
 
 #ifndef arch_dma_alloc_attrs
 #define arch_dma_alloc_attrs(dev, flag)	(true)
@@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 
 static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
-				       struct dma_attrs *attrs)
+				       unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
@@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 
 static inline void dma_free_attrs(struct device *dev, size_t size,
 				     void *cpu_addr, dma_addr_t dma_handle,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t flag)
 {
-	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
+	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
+	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
 }
 
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_handle, gfp,
+			       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline void dma_free_noncoherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+	dma_free_attrs(dev, size, cpu_addr, dma_handle,
+		       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
 static inline void *dma_alloc_wc(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_addr, gfp,
+			       DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_alloc_writecombine
 #define dma_alloc_writecombine dma_alloc_wc
@@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
 static inline void dma_free_wc(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
+	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_free_writecombine
 #define dma_free_writecombine dma_free_wc
@@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
 			      void *cpu_addr, dma_addr_t dma_addr,
 			      size_t size)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_mmap_writecombine
 #define dma_mmap_writecombine dma_mmap_wc
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 017fced60242..5f81f8a187f2 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -6,7 +6,6 @@
 #include <linux/types.h>
 
 struct device;
-struct dma_attrs;
 struct page;
 struct scatterlist;
 
@@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 
 extern int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 
 extern int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs);
+		     enum dma_data_direction dir,
+		     unsigned long attrs);
 
 extern void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 		       int nelems, enum dma_data_direction dir,
-		       struct dma_attrs *attrs);
+		       unsigned long attrs);
 
 extern void
 swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 8b2eb93ae8ba..7c35e279d1e3 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t flags,
-			    struct dma_attrs *attrs);
+			    unsigned long attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
 			  void *vaddr, dma_addr_t dma_handle,
-			  struct dma_attrs *attrs);
+			  unsigned long attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
 				       enum dma_data_direction dir,
-				       struct dma_attrs *attrs);
+				       unsigned long attrs);
 
 extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 				   size_t size, enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 
 extern void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 
 extern void
 xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/lib/dma-noop.c b/lib/dma-noop.c
index 72145646857e..3d766e78fbe2 100644
--- a/lib/dma-noop.c
+++ b/lib/dma-noop.c
@@ -10,7 +10,7 @@
 
 static void *dma_noop_alloc(struct device *dev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t gfp,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	void *ret;
 
@@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 
 static void dma_noop_free(struct device *dev, size_t size,
 			  void *cpu_addr, dma_addr_t dma_addr,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
@@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
 static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
 				      unsigned long offset, size_t size,
 				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	return page_to_phys(page) + offset;
 }
 
 static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
+			     enum dma_data_direction dir,
+			     unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 76f29ecba8f4..22e13a0e19d7 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
 dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 			    unsigned long offset, size_t size,
 			    enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = phys_to_dma(dev, phys);
@@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			size_t size, enum dma_data_direction dir,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	unmap_single(hwdev, dev_addr, size, dir);
 }
@@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  */
 int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs)
+		     enum dma_data_direction dir, unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -914,7 +914,7 @@ int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 	       enum dma_data_direction dir)
 {
-	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_map_sg);
 
@@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
  */
 void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
-		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
+		       int nelems, enum dma_data_direction dir,
+		       unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -941,7 +942,7 @@ void
 swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 		 enum dma_data_direction dir)
 {
-	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_unmap_sg);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-30 11:54   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

The dma-mapping core and the implementations do not change the
DMA attributes passed by pointer.  Thus the pointer can point to const
data.  However the attributes do not have to be a bitfield. Instead
unsigned long will do fine:

1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.

Please have in mind that this is RFC, not finished yet.  Only ARM and
ARM64 are fixed (and not everywhere).
However other API users also have to be converted which is quite
intrusive.  I would rather avoid it until the overall approach is
accepted.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 45ef3f279c3b..0b55cb7c5aaa 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
 struct dma_attrs*.
 
 struct dma_attrs encapsulates a set of "DMA attributes". For the
-definition of struct dma_attrs see linux/dma-attrs.h.
+definition of struct dma_attrs see linux/dma-mapping.h.
 
 The interpretation of DMA attributes is architecture-specific, and
 each attribute should be documented in Documentation/DMA-attributes.txt.
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index e8cf9cf873b3..2d455a5cf671 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -2,7 +2,7 @@
 			==============
 
 This document describes the semantics of the DMA attributes that are
-defined in linux/dma-attrs.h.
+defined in linux/dma-mapping.h.
 
 DMA_ATTR_WRITE_BARRIER
 ----------------------
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a83570f10124..d009f7911ffc 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,7 +5,6 @@
 
 #include <linux/mm_types.h>
 #include <linux/scatterlist.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 
 #include <asm/memory.h>
@@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
  * to be the device-viewed address.
  */
 extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-			   gfp_t gfp, struct dma_attrs *attrs);
+			   gfp_t gfp, unsigned long attrs);
 
 /**
  * arm_dma_free - free memory allocated by arm_dma_alloc
@@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * during and after this call executing are illegal.
  */
 extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			 dma_addr_t handle, struct dma_attrs *attrs);
+			 dma_addr_t handle, unsigned long attrs);
 
 /**
  * arm_dma_mmap - map a coherent DMA allocation into user space
@@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
  */
 extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs);
+			unsigned long attrs);
 
 /*
  * This can be called during early boot to increase the size of the atomic
@@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
  * The scatter list versions of the above methods.
  */
 extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 9408a994cc91..95ce6ac3a971 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -2,15 +2,14 @@
 #define _ASM_ARM_XEN_PAGE_COHERENT_H
 
 #include <asm/page.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-mapping.h>
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs);
+	     enum dma_data_direction dir, unsigned long attrs);
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
@@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
 static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flags,
-		struct dma_attrs *attrs)
+		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
 {
 	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
 }
 
 static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-		void *cpu_addr, dma_addr_t dma_handle,
-		struct dma_attrs *attrs)
+		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
 {
 	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page_pfn = page_to_xen_pfn(page);
 	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
@@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 }
 
 static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long pfn = PFN_DOWN(handle);
 	/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ff7ed5697d3e..fe31fbfd926d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  */
 static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 
 static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 }
@@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  * whatever the device wrote there.
  */
 static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
@@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
 EXPORT_SYMBOL(arm_dma_ops);
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs);
+				  dma_addr_t handle, unsigned long attrs);
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs);
+		 unsigned long attrs);
 
 struct dma_map_ops arm_coherent_dma_ops = {
 	.alloc			= arm_coherent_dma_alloc,
@@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
-static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 {
 	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
 			    pgprot_writecombine(prot) :
@@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
 
 static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 			 gfp_t gfp, pgprot_t prot, bool is_coherent,
-			 struct dma_attrs *attrs, const void *caller)
+			 unsigned long attrs, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
 	struct page *page = NULL;
@@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * virtual and bus address for that space.
  */
 void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-		    gfp_t gfp, struct dma_attrs *attrs)
+		    gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 
@@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 }
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
 			   attrs, __builtin_return_address(0));
@@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
 
 static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	int ret = -ENXIO;
 #ifdef CONFIG_MMU
@@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  */
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
 int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 #ifdef CONFIG_MMU
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
@@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  * Free a buffer as defined by the above mapping.
  */
 static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			   dma_addr_t handle, struct dma_attrs *attrs,
+			   dma_addr_t handle, unsigned long attrs,
 			   bool is_coherent)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
@@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 }
 
 void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle, struct dma_attrs *attrs)
+		  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
 }
 
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs)
+				  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
 	int ret;
@@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
  * here.
  */
 int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 static const int iommu_order_array[] = { 9, 8, 4, 0 };
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					  gfp_t gfp, unsigned long attrs)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1342,7 +1341,7 @@ error:
 }
 
 static int __iommu_free_buffer(struct device *dev, struct page **pages,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	int count = size >> PAGE_SHIFT;
 	int i;
@@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
 	return (struct page **)page;
 }
 
-static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
 {
 	struct vm_struct *area;
 
@@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 }
 
 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1532,7 +1531,7 @@ err_buffer:
 
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		    struct dma_attrs *attrs)
+		    unsigned long attrs)
 {
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
@@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * Must not be called with IRQs disabled.
  */
 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+			  dma_addr_t handle, unsigned long attrs)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
@@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 
 static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t dma_addr,
-				 size_t size, struct dma_attrs *attrs)
+				 size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
@@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
  */
 static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
 			  size_t size, dma_addr_t *handle,
-			  enum dma_data_direction dir, struct dma_attrs *attrs,
+			  enum dma_data_direction dir, unsigned long attrs,
 			  bool is_coherent)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
@@ -1676,7 +1675,7 @@ fail:
 }
 
 static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		     enum dma_data_direction dir, struct dma_attrs *attrs,
+		     enum dma_data_direction dir, unsigned long attrs,
 		     bool is_coherent)
 {
 	struct scatterlist *s = sg, *dma = sg, *start = sg;
@@ -1734,7 +1733,7 @@ bad_mapping:
  * obtained via sg_dma_{address,length}.
  */
 int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
  * sg_dma_{address,length}.
  */
 int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
 }
 
 static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
-		bool is_coherent)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs, bool is_coherent)
 {
 	struct scatterlist *s;
 	int i;
@@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir, struct dma_attrs *attrs)
+			enum dma_data_direction dir,
+			unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
 }
@@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
  */
 static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t dma_addr;
@@ -1889,7 +1890,7 @@ fail:
  */
 static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
  * Coherent IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
  * IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
 	if (!iova)
 		return;
 
+	// FIXME: replace get with simple check
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(page, offset, size, dir);
 
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index c5f9a9e3d1f3..fc67ed236a10 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	if (is_device_dma_coherent(hwdev))
 		return;
@@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
 
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		unsigned long attrs)
 
 {
 	if (is_device_dma_coherent(hwdev))
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec83719f..a7686028dfeb 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -29,7 +29,7 @@
 
 #include <asm/cacheflush.h>
 
-static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
+static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
 				 bool coherent)
 {
 	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
@@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	if (dev == NULL) {
 		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
@@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
 
 static void __dma_free_coherent(struct device *dev, size_t size,
 				void *vaddr, dma_addr_t dma_handle,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool freed;
 	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
@@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
 
 static void *__dma_alloc(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t flags,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct page *page;
 	void *ptr, *coherent_ptr;
@@ -185,7 +185,7 @@ no_mem:
 
 static void __dma_free(struct device *dev, size_t size,
 		       void *vaddr, dma_addr_t dma_handle,
-		       struct dma_attrs *attrs)
+		       unsigned long attrs)
 {
 	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
 
@@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 				     unsigned long offset, size_t size,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	dma_addr_t dev_addr;
 
@@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 
 static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 				 size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	if (!is_device_dma_coherent(dev))
 		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
@@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 
 static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				  int nelems, enum dma_data_direction dir,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i, ret;
@@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __swiotlb_unmap_sg_attrs(struct device *dev,
 				     struct scatterlist *sgl, int nelems,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
 static int __swiotlb_mmap(struct device *dev,
 			  struct vm_area_struct *vma,
 			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	int ret = -ENXIO;
 	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
@@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
 
 static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t handle, size_t size,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
 
@@ -425,21 +425,21 @@ out:
 
 static void *__dummy_alloc(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	return NULL;
 }
 
 static void __dummy_free(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 }
 
 static int __dummy_mmap(struct device *dev,
 			struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	return -ENXIO;
 }
@@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
 static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	return DMA_ERROR_CODE;
 }
 
 static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 }
 
 static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 			  int nelems, enum dma_data_direction dir,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	return 0;
 }
@@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 static void __dummy_unmap_sg(struct device *dev,
 			     struct scatterlist *sgl, int nelems,
 			     enum dma_data_direction dir,
-			     struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 }
 
@@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
 
 static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 				 dma_addr_t *handle, gfp_t gfp,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
@@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 }
 
 static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			       dma_addr_t handle, struct dma_attrs *attrs)
+			       dma_addr_t handle,
+			       unsigned long attrs)
 {
 	size_t iosize = size;
 
@@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 	 * Hence how dodgy the below logic looks...
 	 */
 	if (__in_atomic_pool(cpu_addr, size)) {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_from_pool(cpu_addr, size);
 	} else if (is_vmalloc_addr(cpu_addr)){
 		struct vm_struct *area = find_vm_area(cpu_addr);
@@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 		iommu_dma_free(dev, area->pages, iosize, &handle);
 		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
 	} else {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_pages(virt_to_page(cpu_addr), get_order(size));
 	}
 }
 
 static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			      struct dma_attrs *attrs)
+			      unsigned long attrs)
 {
 	struct vm_struct *area;
 	int ret;
@@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 
 static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 			       void *cpu_addr, dma_addr_t dma_addr,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct vm_struct *area = find_vm_area(cpu_addr);
@@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
 static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int prot = dma_direction_to_prot(dir, coherent);
@@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 
 static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
@@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
 
 static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				int nelems, enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 
@@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __iommu_unmap_sg_attrs(struct device *dev,
 				   struct scatterlist *sgl, int nelems,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 67dcd6831291..dd091175fc2d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
 
 	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 493552368295..f65e6b7ef93b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-attrs.h>
 #include <linux/of.h>
 
 #include <drm/drmP.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cdf9f1af4347..f2ae72ba7d5a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -24,7 +24,7 @@
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
 	struct drm_device *dev = exynos_gem->base.dev;
-	enum dma_attr attr;
+	unsigned long attr;
 	unsigned int nr_pages;
 	struct sg_table sgt;
 	int ret = -ENOMEM;
@@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 		return 0;
 	}
 
-	init_dma_attrs(&exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs = 0;
 
 	/*
 	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
@@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	 * as possible.
 	 */
 	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
-		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
+		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
 
 	/*
 	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
@@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	else
 		attr = DMA_ATTR_NON_CONSISTENT;
 
-	dma_set_attr(attr, &exynos_gem->dma_attrs);
-	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs |= attr;
+	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
 
 	nr_pages = exynos_gem->size >> PAGE_SHIFT;
 
@@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
 					     &exynos_gem->dma_addr, GFP_KERNEL,
-					     &exynos_gem->dma_attrs);
+					     exynos_gem->dma_attrs);
 	if (!exynos_gem->cookie) {
 		DRM_ERROR("failed to allocate buffer.\n");
 		goto err_free;
@@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
 				    exynos_gem->dma_addr, exynos_gem->size,
-				    &exynos_gem->dma_attrs);
+				    exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to get sgtable.\n");
 		goto err_dma_free;
@@ -99,7 +99,7 @@ err_sgt_free:
 	sg_free_table(&sgt);
 err_dma_free:
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
-		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
+		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
 err_free:
 	drm_free_large(exynos_gem->pages);
 
@@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
 
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
 			(dma_addr_t)exynos_gem->dma_addr,
-			&exynos_gem->dma_attrs);
+			exynos_gem->dma_attrs);
 
 	drm_free_large(exynos_gem->pages);
 }
@@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
 
 	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 78100742281d..df7c543d6558 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -50,7 +50,7 @@ struct exynos_drm_gem {
 	void			*cookie;
 	void __iomem		*kvaddr;
 	dma_addr_t		dma_addr;
-	struct dma_attrs	dma_attrs;
+	unsigned long		dma_attrs;
 	struct page		**pages;
 	struct sg_table		*sgt;
 };
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ea5a9ebf0f78..6c1bda504fb1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
  *	   or NULL on failure.
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t))
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
@@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
 }
 
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
 }
@@ -560,7 +560,7 @@ out_restore_sg:
 }
 
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	/*
 	 * The scatterlist segments are mapped into a single
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 7399782c0998..87e6035c9e81 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -294,7 +294,7 @@ error:
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr, struct dma_attrs *attrs)
+			  dma_addr_t dev_addr, unsigned long attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
@@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
 dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				unsigned long offset, size_t size,
 				enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = xen_phys_to_bus(phys);
@@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
  */
 static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 			     size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
 
@@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			    size_t size, enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
 }
@@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
 int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
 void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
deleted file mode 100644
index 5246239a4953..000000000000
--- a/include/linux/dma-attrs.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _DMA_ATTR_H
-#define _DMA_ATTR_H
-
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
-#include <linux/bug.h>
-
-/**
- * an enum dma_attr represents an attribute associated with a DMA
- * mapping. The semantics of each attribute should be defined in
- * Documentation/DMA-attributes.txt.
- */
-enum dma_attr {
-	DMA_ATTR_WRITE_BARRIER,
-	DMA_ATTR_WEAK_ORDERING,
-	DMA_ATTR_WRITE_COMBINE,
-	DMA_ATTR_NON_CONSISTENT,
-	DMA_ATTR_NO_KERNEL_MAPPING,
-	DMA_ATTR_SKIP_CPU_SYNC,
-	DMA_ATTR_FORCE_CONTIGUOUS,
-	DMA_ATTR_ALLOC_SINGLE_PAGES,
-	DMA_ATTR_MAX,
-};
-
-#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
-
-/**
- * struct dma_attrs - an opaque container for DMA attributes
- * @flags - bitmask representing a collection of enum dma_attr
- */
-struct dma_attrs {
-	unsigned long flags[__DMA_ATTRS_LONGS];
-};
-
-#define DEFINE_DMA_ATTRS(x) 					\
-	struct dma_attrs x = {					\
-		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
-	}
-
-static inline void init_dma_attrs(struct dma_attrs *attrs)
-{
-	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
-}
-
-/**
- * dma_set_attr - set a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	__set_bit(attr, attrs->flags);
-}
-
-/**
- * dma_get_attr - check for a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return 0;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	return test_bit(attr, attrs->flags);
-}
-
-#endif /* _DMA_ATTR_H */
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 8443bbb5c071..81c5c8d167ad 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
  * the arch code to take care of attributes and cache maintenance
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t));
 void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
 		dma_addr_t *handle);
@@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
  * directly as DMA mapping callbacks for simplicity
  */
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 int iommu_dma_supported(struct device *dev, u64 mask);
 int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 71c1b215ef66..19e581d5f8b4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -5,13 +5,25 @@
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
 #include <linux/kmemcheck.h>
 #include <linux/bug.h>
 
+/**
+ * List of possible attributes associated with a DMA mapping. The semantics
+ * of each attribute should be defined in Documentation/DMA-attributes.txt.
+ */
+#define DMA_ATTR_WRITE_BARRIER		BIT(1)
+#define DMA_ATTR_WEAK_ORDERING		BIT(2)
+#define DMA_ATTR_WRITE_COMBINE		BIT(3)
+#define DMA_ATTR_NON_CONSISTENT		BIT(4)
+#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
+#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
+#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
+#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
+
 /*
  * 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.  A CPU cannot
@@ -21,34 +33,35 @@
 struct dma_map_ops {
 	void* (*alloc)(struct device *dev, size_t size,
 				dma_addr_t *dma_handle, gfp_t gfp,
-				struct dma_attrs *attrs);
+				unsigned long attrs);
 	void (*free)(struct device *dev, size_t size,
 			      void *vaddr, dma_addr_t dma_handle,
-			      struct dma_attrs *attrs);
+			      unsigned long attrs);
 	int (*mmap)(struct device *, struct vm_area_struct *,
-			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
+			  void *, dma_addr_t, size_t,
+			  unsigned long attrs);
 
 	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
-			   dma_addr_t, size_t, struct dma_attrs *attrs);
+			   dma_addr_t, size_t, unsigned long attrs);
 
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
 			   size_t size, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 	/*
 	 * map_sg returns 0 on error and a value > 0 on success.
 	 * It should never return a value < 0.
 	 */
 	int (*map_sg)(struct device *dev, struct scatterlist *sg,
 		      int nents, enum dma_data_direction dir,
-		      struct dma_attrs *attrs);
+		      unsigned long attrs);
 	void (*unmap_sg)(struct device *dev,
 			 struct scatterlist *sg, int nents,
 			 enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 	void (*sync_single_for_cpu)(struct device *dev,
 				    dma_addr_t dma_handle, size_t size,
 				    enum dma_data_direction dir);
@@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
 	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
 }
 
+/**
+ * dma_get_attr - check for a specific attribute
+ * @attr: attribute to look for
+ * @attrs: attributes to check within
+ */
+static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
+{
+	return !!(attr & attrs);
+}
+
 #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 /*
  * These three functions are only for dma allocator.
@@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 					      size_t size,
 					      enum dma_data_direction dir,
-					      struct dma_attrs *attrs)
+					      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	dma_addr_t addr;
@@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
 					  size_t size,
 					  enum dma_data_direction dir,
-					  struct dma_attrs *attrs)
+					  unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
  */
 static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 				   int nents, enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	int i, ents;
@@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 
 static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 				      int nents, enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
 	BUG_ON(!valid_dma_direction(dir));
-	addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	addr = ops->map_page(dev, page, offset, size, dir, 0);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
 
 	return addr;
@@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
 
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
-		ops->unmap_page(dev, addr, size, dir, NULL);
+		ops->unmap_page(dev, addr, size, dir, 0);
 	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
@@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 
 }
 
-#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
-#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
-#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
-#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
 
 extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
@@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
  */
 static inline int
 dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
-	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
 	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
 
 int
 dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
@@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 
 static inline int
 dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
-		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+		      dma_addr_t dma_addr, size_t size,
+		      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
 }
 
-#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
 
 #ifndef arch_dma_alloc_attrs
 #define arch_dma_alloc_attrs(dev, flag)	(true)
@@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 
 static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
-				       struct dma_attrs *attrs)
+				       unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
@@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 
 static inline void dma_free_attrs(struct device *dev, size_t size,
 				     void *cpu_addr, dma_addr_t dma_handle,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t flag)
 {
-	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
+	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
+	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
 }
 
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_handle, gfp,
+			       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline void dma_free_noncoherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+	dma_free_attrs(dev, size, cpu_addr, dma_handle,
+		       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
 static inline void *dma_alloc_wc(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_addr, gfp,
+			       DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_alloc_writecombine
 #define dma_alloc_writecombine dma_alloc_wc
@@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
 static inline void dma_free_wc(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
+	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_free_writecombine
 #define dma_free_writecombine dma_free_wc
@@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
 			      void *cpu_addr, dma_addr_t dma_addr,
 			      size_t size)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_mmap_writecombine
 #define dma_mmap_writecombine dma_mmap_wc
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 017fced60242..5f81f8a187f2 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -6,7 +6,6 @@
 #include <linux/types.h>
 
 struct device;
-struct dma_attrs;
 struct page;
 struct scatterlist;
 
@@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 
 extern int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 
 extern int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs);
+		     enum dma_data_direction dir,
+		     unsigned long attrs);
 
 extern void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 		       int nelems, enum dma_data_direction dir,
-		       struct dma_attrs *attrs);
+		       unsigned long attrs);
 
 extern void
 swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 8b2eb93ae8ba..7c35e279d1e3 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t flags,
-			    struct dma_attrs *attrs);
+			    unsigned long attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
 			  void *vaddr, dma_addr_t dma_handle,
-			  struct dma_attrs *attrs);
+			  unsigned long attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
 				       enum dma_data_direction dir,
-				       struct dma_attrs *attrs);
+				       unsigned long attrs);
 
 extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 				   size_t size, enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 
 extern void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 
 extern void
 xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/lib/dma-noop.c b/lib/dma-noop.c
index 72145646857e..3d766e78fbe2 100644
--- a/lib/dma-noop.c
+++ b/lib/dma-noop.c
@@ -10,7 +10,7 @@
 
 static void *dma_noop_alloc(struct device *dev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t gfp,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	void *ret;
 
@@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 
 static void dma_noop_free(struct device *dev, size_t size,
 			  void *cpu_addr, dma_addr_t dma_addr,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
@@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
 static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
 				      unsigned long offset, size_t size,
 				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	return page_to_phys(page) + offset;
 }
 
 static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
+			     enum dma_data_direction dir,
+			     unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 76f29ecba8f4..22e13a0e19d7 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
 dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 			    unsigned long offset, size_t size,
 			    enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = phys_to_dma(dev, phys);
@@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			size_t size, enum dma_data_direction dir,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	unmap_single(hwdev, dev_addr, size, dir);
 }
@@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  */
 int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs)
+		     enum dma_data_direction dir, unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -914,7 +914,7 @@ int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 	       enum dma_data_direction dir)
 {
-	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_map_sg);
 
@@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
  */
 void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
-		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
+		       int nelems, enum dma_data_direction dir,
+		       unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -941,7 +942,7 @@ void
 swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 		 enum dma_data_direction dir)
 {
-	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_unmap_sg);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-30 11:54 ` Krzysztof Kozlowski
  (?)
@ 2016-05-30 11:54 ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-05-30 11:54 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu
  Cc: hch, Krzysztof Kozlowski, sstabellini, Bartlomiej Zolnierkiewicz

The dma-mapping core and the implementations do not change the
DMA attributes passed by pointer.  Thus the pointer can point to const
data.  However the attributes do not have to be a bitfield. Instead
unsigned long will do fine:

1. This is just simpler.  Both in terms of reading the code and setting
   attributes.  Instead of initializing local attributes on the stack and
   passing pointer to it to dma_set_attr(), just set the bits.

2. It brings safeness and checking for const correctness because the
   attributes are passed by value.

Please have in mind that this is RFC, not finished yet.  Only ARM and
ARM64 are fixed (and not everywhere).
However other API users also have to be converted which is quite
intrusive.  I would rather avoid it until the overall approach is
accepted.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 Documentation/DMA-API.txt                 |   2 +-
 Documentation/DMA-attributes.txt          |   2 +-
 arch/arm/include/asm/dma-mapping.h        |  13 ++--
 arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
 arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
 arch/arm/xen/mm.c                         |   4 +-
 arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
 drivers/iommu/dma-iommu.c                 |   6 +-
 drivers/xen/swiotlb-xen.c                 |  14 ++--
 include/linux/dma-attrs.h                 |  71 --------------------
 include/linux/dma-iommu.h                 |   6 +-
 include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
 include/linux/swiotlb.h                   |  10 +--
 include/xen/swiotlb-xen.h                 |  12 ++--
 lib/dma-noop.c                            |   9 +--
 lib/swiotlb.c                             |  13 ++--
 20 files changed, 195 insertions(+), 252 deletions(-)
 delete mode 100644 include/linux/dma-attrs.h

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 45ef3f279c3b..0b55cb7c5aaa 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
 struct dma_attrs*.
 
 struct dma_attrs encapsulates a set of "DMA attributes". For the
-definition of struct dma_attrs see linux/dma-attrs.h.
+definition of struct dma_attrs see linux/dma-mapping.h.
 
 The interpretation of DMA attributes is architecture-specific, and
 each attribute should be documented in Documentation/DMA-attributes.txt.
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index e8cf9cf873b3..2d455a5cf671 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -2,7 +2,7 @@
 			==============
 
 This document describes the semantics of the DMA attributes that are
-defined in linux/dma-attrs.h.
+defined in linux/dma-mapping.h.
 
 DMA_ATTR_WRITE_BARRIER
 ----------------------
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a83570f10124..d009f7911ffc 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,7 +5,6 @@
 
 #include <linux/mm_types.h>
 #include <linux/scatterlist.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 
 #include <asm/memory.h>
@@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
  * to be the device-viewed address.
  */
 extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-			   gfp_t gfp, struct dma_attrs *attrs);
+			   gfp_t gfp, unsigned long attrs);
 
 /**
  * arm_dma_free - free memory allocated by arm_dma_alloc
@@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * during and after this call executing are illegal.
  */
 extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			 dma_addr_t handle, struct dma_attrs *attrs);
+			 dma_addr_t handle, unsigned long attrs);
 
 /**
  * arm_dma_mmap - map a coherent DMA allocation into user space
@@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
  */
 extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs);
+			unsigned long attrs);
 
 /*
  * This can be called during early boot to increase the size of the atomic
@@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
  * The scatter list versions of the above methods.
  */
 extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
-		enum dma_data_direction, struct dma_attrs *attrs);
+		enum dma_data_direction, unsigned long attrs);
 extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
 		enum dma_data_direction);
 extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 9408a994cc91..95ce6ac3a971 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -2,15 +2,14 @@
 #define _ASM_ARM_XEN_PAGE_COHERENT_H
 
 #include <asm/page.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-mapping.h>
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs);
+	     enum dma_data_direction dir, unsigned long attrs);
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs);
+		unsigned long attrs);
 void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
@@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
 static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flags,
-		struct dma_attrs *attrs)
+		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
 {
 	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
 }
 
 static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-		void *cpu_addr, dma_addr_t dma_handle,
-		struct dma_attrs *attrs)
+		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
 {
 	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page_pfn = page_to_xen_pfn(page);
 	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
@@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 }
 
 static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long pfn = PFN_DOWN(handle);
 	/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ff7ed5697d3e..fe31fbfd926d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  */
 static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 
 static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 }
@@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  * whatever the device wrote there.
  */
 static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
@@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
 EXPORT_SYMBOL(arm_dma_ops);
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs);
+				  dma_addr_t handle, unsigned long attrs);
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs);
+		 unsigned long attrs);
 
 struct dma_map_ops arm_coherent_dma_ops = {
 	.alloc			= arm_coherent_dma_alloc,
@@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
-static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 {
 	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
 			    pgprot_writecombine(prot) :
@@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
 
 static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 			 gfp_t gfp, pgprot_t prot, bool is_coherent,
-			 struct dma_attrs *attrs, const void *caller)
+			 unsigned long attrs, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
 	struct page *page = NULL;
@@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * virtual and bus address for that space.
  */
 void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-		    gfp_t gfp, struct dma_attrs *attrs)
+		    gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 
@@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 }
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
-	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
 			   attrs, __builtin_return_address(0));
@@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
 
 static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	int ret = -ENXIO;
 #ifdef CONFIG_MMU
@@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  */
 static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
 int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 #ifdef CONFIG_MMU
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
@@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  * Free a buffer as defined by the above mapping.
  */
 static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-			   dma_addr_t handle, struct dma_attrs *attrs,
+			   dma_addr_t handle, unsigned long attrs,
 			   bool is_coherent)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
@@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 }
 
 void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle, struct dma_attrs *attrs)
+		  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
 }
 
 static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
-				  dma_addr_t handle, struct dma_attrs *attrs)
+				  dma_addr_t handle, unsigned long attrs)
 {
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
-		 struct dma_attrs *attrs)
+		 unsigned long attrs)
 {
 	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
 	int ret;
@@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
  * here.
  */
 int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
@@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 static const int iommu_order_array[] = { 9, 8, 4, 0 };
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					  gfp_t gfp, unsigned long attrs)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1342,7 +1341,7 @@ error:
 }
 
 static int __iommu_free_buffer(struct device *dev, struct page **pages,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	int count = size >> PAGE_SHIFT;
 	int i;
@@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
 	return (struct page **)page;
 }
 
-static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
 {
 	struct vm_struct *area;
 
@@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 }
 
 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1532,7 +1531,7 @@ err_buffer:
 
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		    struct dma_attrs *attrs)
+		    unsigned long attrs)
 {
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
@@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * Must not be called with IRQs disabled.
  */
 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+			  dma_addr_t handle, unsigned long attrs)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
@@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 
 static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t dma_addr,
-				 size_t size, struct dma_attrs *attrs)
+				 size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
@@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
  */
 static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
 			  size_t size, dma_addr_t *handle,
-			  enum dma_data_direction dir, struct dma_attrs *attrs,
+			  enum dma_data_direction dir, unsigned long attrs,
 			  bool is_coherent)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
@@ -1676,7 +1675,7 @@ fail:
 }
 
 static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		     enum dma_data_direction dir, struct dma_attrs *attrs,
+		     enum dma_data_direction dir, unsigned long attrs,
 		     bool is_coherent)
 {
 	struct scatterlist *s = sg, *dma = sg, *start = sg;
@@ -1734,7 +1733,7 @@ bad_mapping:
  * obtained via sg_dma_{address,length}.
  */
 int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
  * sg_dma_{address,length}.
  */
 int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
 }
 
 static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
-		bool is_coherent)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs, bool is_coherent)
 {
 	struct scatterlist *s;
 	int i;
@@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+		int nents, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
 }
@@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
  * rules concerning calls here are the same as for dma_unmap_single().
  */
 void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir, struct dma_attrs *attrs)
+			enum dma_data_direction dir,
+			unsigned long attrs)
 {
 	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
 }
@@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
  */
 static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t dma_addr;
@@ -1889,7 +1890,7 @@ fail:
  */
 static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
-	     struct dma_attrs *attrs)
+	     unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_cpu_to_dev(page, offset, size, dir);
@@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
  * Coherent IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
  * IOMMU aware version of arm_dma_unmap_page()
  */
 static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
 	dma_addr_t iova = handle & PAGE_MASK;
@@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
 	if (!iova)
 		return;
 
+	// FIXME: replace get with simple check
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__dma_page_dev_to_cpu(page, offset, size, dir);
 
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index c5f9a9e3d1f3..fc67ed236a10 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, struct dma_attrs *attrs)
+	     enum dma_data_direction dir, unsigned long attrs)
 {
 	if (is_device_dma_coherent(hwdev))
 		return;
@@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
 
 void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
-		struct dma_attrs *attrs)
+		unsigned long attrs)
 
 {
 	if (is_device_dma_coherent(hwdev))
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c566ec83719f..a7686028dfeb 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -29,7 +29,7 @@
 
 #include <asm/cacheflush.h>
 
-static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
+static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
 				 bool coherent)
 {
 	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
@@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	if (dev == NULL) {
 		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
@@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
 
 static void __dma_free_coherent(struct device *dev, size_t size,
 				void *vaddr, dma_addr_t dma_handle,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool freed;
 	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
@@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
 
 static void *__dma_alloc(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t flags,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct page *page;
 	void *ptr, *coherent_ptr;
@@ -185,7 +185,7 @@ no_mem:
 
 static void __dma_free(struct device *dev, size_t size,
 		       void *vaddr, dma_addr_t dma_handle,
-		       struct dma_attrs *attrs)
+		       unsigned long attrs)
 {
 	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
 
@@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 				     unsigned long offset, size_t size,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	dma_addr_t dev_addr;
 
@@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
 
 static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 				 size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	if (!is_device_dma_coherent(dev))
 		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
@@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
 
 static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				  int nelems, enum dma_data_direction dir,
-				  struct dma_attrs *attrs)
+				  unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i, ret;
@@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __swiotlb_unmap_sg_attrs(struct device *dev,
 				     struct scatterlist *sgl, int nelems,
 				     enum dma_data_direction dir,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
 static int __swiotlb_mmap(struct device *dev,
 			  struct vm_area_struct *vma,
 			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	int ret = -ENXIO;
 	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
@@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
 
 static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t handle, size_t size,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
 
@@ -425,21 +425,21 @@ out:
 
 static void *__dummy_alloc(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	return NULL;
 }
 
 static void __dummy_free(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 }
 
 static int __dummy_mmap(struct device *dev,
 			struct vm_area_struct *vma,
 			void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	return -ENXIO;
 }
@@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
 static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	return DMA_ERROR_CODE;
 }
 
 static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 }
 
 static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 			  int nelems, enum dma_data_direction dir,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	return 0;
 }
@@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
 static void __dummy_unmap_sg(struct device *dev,
 			     struct scatterlist *sgl, int nelems,
 			     enum dma_data_direction dir,
-			     struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 }
 
@@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
 
 static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 				 dma_addr_t *handle, gfp_t gfp,
-				 struct dma_attrs *attrs)
+				 unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
@@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
 }
 
 static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			       dma_addr_t handle, struct dma_attrs *attrs)
+			       dma_addr_t handle,
+			       unsigned long attrs)
 {
 	size_t iosize = size;
 
@@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 	 * Hence how dodgy the below logic looks...
 	 */
 	if (__in_atomic_pool(cpu_addr, size)) {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_from_pool(cpu_addr, size);
 	} else if (is_vmalloc_addr(cpu_addr)){
 		struct vm_struct *area = find_vm_area(cpu_addr);
@@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 		iommu_dma_free(dev, area->pages, iosize, &handle);
 		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
 	} else {
-		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
 		__free_pages(virt_to_page(cpu_addr), get_order(size));
 	}
 }
 
 static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
-			      struct dma_attrs *attrs)
+			      unsigned long attrs)
 {
 	struct vm_struct *area;
 	int ret;
@@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 
 static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 			       void *cpu_addr, dma_addr_t dma_addr,
-			       size_t size, struct dma_attrs *attrs)
+			       size_t size, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	struct vm_struct *area = find_vm_area(cpu_addr);
@@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
 static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 	int prot = dma_direction_to_prot(dir, coherent);
@@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
 
 static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs)
+			       unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
@@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
 
 static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 				int nelems, enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	bool coherent = is_device_dma_coherent(dev);
 
@@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
 static void __iommu_unmap_sg_attrs(struct device *dev,
 				   struct scatterlist *sgl, int nelems,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
 		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 67dcd6831291..dd091175fc2d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
 
 	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 493552368295..f65e6b7ef93b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-attrs.h>
 #include <linux/of.h>
 
 #include <drm/drmP.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cdf9f1af4347..f2ae72ba7d5a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -24,7 +24,7 @@
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
 	struct drm_device *dev = exynos_gem->base.dev;
-	enum dma_attr attr;
+	unsigned long attr;
 	unsigned int nr_pages;
 	struct sg_table sgt;
 	int ret = -ENOMEM;
@@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 		return 0;
 	}
 
-	init_dma_attrs(&exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs = 0;
 
 	/*
 	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
@@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	 * as possible.
 	 */
 	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
-		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
+		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
 
 	/*
 	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
@@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	else
 		attr = DMA_ATTR_NON_CONSISTENT;
 
-	dma_set_attr(attr, &exynos_gem->dma_attrs);
-	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
+	exynos_gem->dma_attrs |= attr;
+	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
 
 	nr_pages = exynos_gem->size >> PAGE_SHIFT;
 
@@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
 					     &exynos_gem->dma_addr, GFP_KERNEL,
-					     &exynos_gem->dma_attrs);
+					     exynos_gem->dma_attrs);
 	if (!exynos_gem->cookie) {
 		DRM_ERROR("failed to allocate buffer.\n");
 		goto err_free;
@@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 
 	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
 				    exynos_gem->dma_addr, exynos_gem->size,
-				    &exynos_gem->dma_attrs);
+				    exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to get sgtable.\n");
 		goto err_dma_free;
@@ -99,7 +99,7 @@ err_sgt_free:
 	sg_free_table(&sgt);
 err_dma_free:
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
-		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
+		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
 err_free:
 	drm_free_large(exynos_gem->pages);
 
@@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
 
 	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
 			(dma_addr_t)exynos_gem->dma_addr,
-			&exynos_gem->dma_attrs);
+			exynos_gem->dma_attrs);
 
 	drm_free_large(exynos_gem->pages);
 }
@@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
 
 	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
 			     exynos_gem->dma_addr, exynos_gem->size,
-			     &exynos_gem->dma_attrs);
+			     exynos_gem->dma_attrs);
 	if (ret < 0) {
 		DRM_ERROR("failed to mmap.\n");
 		return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 78100742281d..df7c543d6558 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -50,7 +50,7 @@ struct exynos_drm_gem {
 	void			*cookie;
 	void __iomem		*kvaddr;
 	dma_addr_t		dma_addr;
-	struct dma_attrs	dma_attrs;
+	unsigned long		dma_attrs;
 	struct page		**pages;
 	struct sg_table		*sgt;
 };
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ea5a9ebf0f78..6c1bda504fb1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
  *	   or NULL on failure.
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t))
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
@@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
 }
 
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
 }
@@ -560,7 +560,7 @@ out_restore_sg:
 }
 
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs)
+		enum dma_data_direction dir, unsigned long attrs)
 {
 	/*
 	 * The scatterlist segments are mapped into a single
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 7399782c0998..87e6035c9e81 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -294,7 +294,7 @@ error:
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t flags,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr, struct dma_attrs *attrs)
+			  dma_addr_t dev_addr, unsigned long attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
@@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
 dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				unsigned long offset, size_t size,
 				enum dma_data_direction dir,
-				struct dma_attrs *attrs)
+				unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = xen_phys_to_bus(phys);
@@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
  */
 static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 			     size_t size, enum dma_data_direction dir,
-				 struct dma_attrs *attrs)
+			     unsigned long attrs)
 {
 	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
 
@@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			    size_t size, enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
 }
@@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
 int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs)
+			 unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
 void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs)
+			   unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
deleted file mode 100644
index 5246239a4953..000000000000
--- a/include/linux/dma-attrs.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _DMA_ATTR_H
-#define _DMA_ATTR_H
-
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
-#include <linux/bug.h>
-
-/**
- * an enum dma_attr represents an attribute associated with a DMA
- * mapping. The semantics of each attribute should be defined in
- * Documentation/DMA-attributes.txt.
- */
-enum dma_attr {
-	DMA_ATTR_WRITE_BARRIER,
-	DMA_ATTR_WEAK_ORDERING,
-	DMA_ATTR_WRITE_COMBINE,
-	DMA_ATTR_NON_CONSISTENT,
-	DMA_ATTR_NO_KERNEL_MAPPING,
-	DMA_ATTR_SKIP_CPU_SYNC,
-	DMA_ATTR_FORCE_CONTIGUOUS,
-	DMA_ATTR_ALLOC_SINGLE_PAGES,
-	DMA_ATTR_MAX,
-};
-
-#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
-
-/**
- * struct dma_attrs - an opaque container for DMA attributes
- * @flags - bitmask representing a collection of enum dma_attr
- */
-struct dma_attrs {
-	unsigned long flags[__DMA_ATTRS_LONGS];
-};
-
-#define DEFINE_DMA_ATTRS(x) 					\
-	struct dma_attrs x = {					\
-		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
-	}
-
-static inline void init_dma_attrs(struct dma_attrs *attrs)
-{
-	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
-}
-
-/**
- * dma_set_attr - set a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	__set_bit(attr, attrs->flags);
-}
-
-/**
- * dma_get_attr - check for a specific attribute
- * @attr: attribute to set
- * @attrs: struct dma_attrs (may be NULL)
- */
-static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-	if (attrs == NULL)
-		return 0;
-	BUG_ON(attr >= DMA_ATTR_MAX);
-	return test_bit(attr, attrs->flags);
-}
-
-#endif /* _DMA_ATTR_H */
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 8443bbb5c071..81c5c8d167ad 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
  * the arch code to take care of attributes and cache maintenance
  */
 struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
-		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
+		unsigned long attrs, int prot, dma_addr_t *handle,
 		void (*flush_page)(struct device *, const void *, phys_addr_t));
 void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
 		dma_addr_t *handle);
@@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
  * directly as DMA mapping callbacks for simplicity
  */
 void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir, struct dma_attrs *attrs);
+		enum dma_data_direction dir, unsigned long attrs);
 int iommu_dma_supported(struct device *dev, u64 mask);
 int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 71c1b215ef66..19e581d5f8b4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -5,13 +5,25 @@
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/dma-attrs.h>
 #include <linux/dma-debug.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
 #include <linux/kmemcheck.h>
 #include <linux/bug.h>
 
+/**
+ * List of possible attributes associated with a DMA mapping. The semantics
+ * of each attribute should be defined in Documentation/DMA-attributes.txt.
+ */
+#define DMA_ATTR_WRITE_BARRIER		BIT(1)
+#define DMA_ATTR_WEAK_ORDERING		BIT(2)
+#define DMA_ATTR_WRITE_COMBINE		BIT(3)
+#define DMA_ATTR_NON_CONSISTENT		BIT(4)
+#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
+#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
+#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
+#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
+
 /*
  * 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.  A CPU cannot
@@ -21,34 +33,35 @@
 struct dma_map_ops {
 	void* (*alloc)(struct device *dev, size_t size,
 				dma_addr_t *dma_handle, gfp_t gfp,
-				struct dma_attrs *attrs);
+				unsigned long attrs);
 	void (*free)(struct device *dev, size_t size,
 			      void *vaddr, dma_addr_t dma_handle,
-			      struct dma_attrs *attrs);
+			      unsigned long attrs);
 	int (*mmap)(struct device *, struct vm_area_struct *,
-			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
+			  void *, dma_addr_t, size_t,
+			  unsigned long attrs);
 
 	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
-			   dma_addr_t, size_t, struct dma_attrs *attrs);
+			   dma_addr_t, size_t, unsigned long attrs);
 
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
 			   size_t size, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 	/*
 	 * map_sg returns 0 on error and a value > 0 on success.
 	 * It should never return a value < 0.
 	 */
 	int (*map_sg)(struct device *dev, struct scatterlist *sg,
 		      int nents, enum dma_data_direction dir,
-		      struct dma_attrs *attrs);
+		      unsigned long attrs);
 	void (*unmap_sg)(struct device *dev,
 			 struct scatterlist *sg, int nents,
 			 enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 	void (*sync_single_for_cpu)(struct device *dev,
 				    dma_addr_t dma_handle, size_t size,
 				    enum dma_data_direction dir);
@@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
 	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
 }
 
+/**
+ * dma_get_attr - check for a specific attribute
+ * @attr: attribute to look for
+ * @attrs: attributes to check within
+ */
+static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
+{
+	return !!(attr & attrs);
+}
+
 #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 /*
  * These three functions are only for dma allocator.
@@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 					      size_t size,
 					      enum dma_data_direction dir,
-					      struct dma_attrs *attrs)
+					      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	dma_addr_t addr;
@@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
 static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
 					  size_t size,
 					  enum dma_data_direction dir,
-					  struct dma_attrs *attrs)
+					  unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
  */
 static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 				   int nents, enum dma_data_direction dir,
-				   struct dma_attrs *attrs)
+				   unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	int i, ents;
@@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 
 static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 				      int nents, enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
 	BUG_ON(!valid_dma_direction(dir));
-	addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	addr = ops->map_page(dev, page, offset, size, dir, 0);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
 
 	return addr;
@@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
 
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
-		ops->unmap_page(dev, addr, size, dir, NULL);
+		ops->unmap_page(dev, addr, size, dir, 0);
 	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
@@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 
 }
 
-#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
-#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
-#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
-#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
 
 extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
@@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
  */
 static inline int
 dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
-	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
 	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
 
 int
 dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
@@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 
 static inline int
 dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
-		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+		      dma_addr_t dma_addr, size_t size,
+		      unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	BUG_ON(!ops);
@@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
 }
 
-#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
 
 #ifndef arch_dma_alloc_attrs
 #define arch_dma_alloc_attrs(dev, flag)	(true)
@@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
 
 static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
-				       struct dma_attrs *attrs)
+				       unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
@@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 
 static inline void dma_free_attrs(struct device *dev, size_t size,
 				     void *cpu_addr, dma_addr_t dma_handle,
-				     struct dma_attrs *attrs)
+				     unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t flag)
 {
-	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
+	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
+	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
 }
 
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_handle, gfp,
+			       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline void dma_free_noncoherent(struct device *dev, size_t size,
 		void *cpu_addr, dma_addr_t dma_handle)
 {
-	DEFINE_DMA_ATTRS(attrs);
-
-	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+	dma_free_attrs(dev, size, cpu_addr, dma_handle,
+		       DMA_ATTR_NON_CONSISTENT);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
 static inline void *dma_alloc_wc(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t gfp)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
+	return dma_alloc_attrs(dev, size, dma_addr, gfp,
+			       DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_alloc_writecombine
 #define dma_alloc_writecombine dma_alloc_wc
@@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
 static inline void dma_free_wc(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
+	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_free_writecombine
 #define dma_free_writecombine dma_free_wc
@@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
 			      void *cpu_addr, dma_addr_t dma_addr,
 			      size_t size)
 {
-	DEFINE_DMA_ATTRS(attrs);
-	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
-	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
+			      DMA_ATTR_WRITE_COMBINE);
 }
 #ifndef dma_mmap_writecombine
 #define dma_mmap_writecombine dma_mmap_wc
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 017fced60242..5f81f8a187f2 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -6,7 +6,6 @@
 #include <linux/types.h>
 
 struct device;
-struct dma_attrs;
 struct page;
 struct scatterlist;
 
@@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			       size_t size, enum dma_data_direction dir,
-			       struct dma_attrs *attrs);
+			       unsigned long attrs);
 
 extern int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 
 extern int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs);
+		     enum dma_data_direction dir,
+		     unsigned long attrs);
 
 extern void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 		       int nelems, enum dma_data_direction dir,
-		       struct dma_attrs *attrs);
+		       unsigned long attrs);
 
 extern void
 swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 8b2eb93ae8ba..7c35e279d1e3 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t flags,
-			    struct dma_attrs *attrs);
+			    unsigned long attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
 			  void *vaddr, dma_addr_t dma_handle,
-			  struct dma_attrs *attrs);
+			  unsigned long attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
 				       enum dma_data_direction dir,
-				       struct dma_attrs *attrs);
+				       unsigned long attrs);
 
 extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 				   size_t size, enum dma_data_direction dir,
-				   struct dma_attrs *attrs);
+				   unsigned long attrs);
 extern int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			 int nelems, enum dma_data_direction dir,
-			 struct dma_attrs *attrs);
+			 unsigned long attrs);
 
 extern void
 xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 			   int nelems, enum dma_data_direction dir,
-			   struct dma_attrs *attrs);
+			   unsigned long attrs);
 
 extern void
 xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
diff --git a/lib/dma-noop.c b/lib/dma-noop.c
index 72145646857e..3d766e78fbe2 100644
--- a/lib/dma-noop.c
+++ b/lib/dma-noop.c
@@ -10,7 +10,7 @@
 
 static void *dma_noop_alloc(struct device *dev, size_t size,
 			    dma_addr_t *dma_handle, gfp_t gfp,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	void *ret;
 
@@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 
 static void dma_noop_free(struct device *dev, size_t size,
 			  void *cpu_addr, dma_addr_t dma_addr,
-			  struct dma_attrs *attrs)
+			  unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
@@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
 static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
 				      unsigned long offset, size_t size,
 				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
+				      unsigned long attrs)
 {
 	return page_to_phys(page) + offset;
 }
 
 static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
+			     enum dma_data_direction dir,
+			     unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 76f29ecba8f4..22e13a0e19d7 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
 dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 			    unsigned long offset, size_t size,
 			    enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
+			    unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
 	dma_addr_t dev_addr = phys_to_dma(dev, phys);
@@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
 void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			size_t size, enum dma_data_direction dir,
-			struct dma_attrs *attrs)
+			unsigned long attrs)
 {
 	unmap_single(hwdev, dev_addr, size, dir);
 }
@@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  */
 int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		     enum dma_data_direction dir, struct dma_attrs *attrs)
+		     enum dma_data_direction dir, unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -914,7 +914,7 @@ int
 swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 	       enum dma_data_direction dir)
 {
-	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_map_sg);
 
@@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
  */
 void
 swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
-		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
+		       int nelems, enum dma_data_direction dir,
+		       unsigned long attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -941,7 +942,7 @@ void
 swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
 		 enum dma_data_direction dir)
 {
-	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
+	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
 }
 EXPORT_SYMBOL(swiotlb_unmap_sg);
 
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-30 11:54   ` Krzysztof Kozlowski
  (?)
@ 2016-05-31 17:04     ` Christoph Hellwig
  -1 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-05-31 17:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu,
	hch, sstabellini, Bartlomiej Zolnierkiewicz

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.

This looks great!  Please continue doing the full conversion.

> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)

No really for this patch, but I would much prefer to document them next
to the code in the long run.  Also I really think these BIT() macros
are a distraction compared to the (1 << N) notation.

> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}

I'd just kill this helper, much easier to simply open code it in the
caller.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-31 17:04     ` Christoph Hellwig
  0 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-05-31 17:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, hch, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.

This looks great!  Please continue doing the full conversion.

> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)

No really for this patch, but I would much prefer to document them next
to the code in the long run.  Also I really think these BIT() macros
are a distraction compared to the (1 << N) notation.

> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}

I'd just kill this helper, much easier to simply open code it in the
caller.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-31 17:04     ` Christoph Hellwig
  0 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-05-31 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.

This looks great!  Please continue doing the full conversion.

> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)

No really for this patch, but I would much prefer to document them next
to the code in the long run.  Also I really think these BIT() macros
are a distraction compared to the (1 << N) notation.

> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}

I'd just kill this helper, much easier to simply open code it in the
caller.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-30 11:54   ` Krzysztof Kozlowski
  (?)
  (?)
@ 2016-05-31 17:04   ` Christoph Hellwig
  -1 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-05-31 17:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, hch, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.

This looks great!  Please continue doing the full conversion.

> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)

No really for this patch, but I would much prefer to document them next
to the code in the long run.  Also I really think these BIT() macros
are a distraction compared to the (1 << N) notation.

> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}

I'd just kill this helper, much easier to simply open code it in the
caller.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-30 11:54   ` Krzysztof Kozlowski
  (?)
@ 2016-05-31 18:15     ` Konrad Rzeszutek Wilk
  -1 siblings, 0 replies; 24+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-05-31 18:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu,
	hch, sstabellini, Bartlomiej Zolnierkiewicz

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.


.. why not go the next step a do an enum? Perhaps that should be mentioned
as part of the description?

Thanks.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
>  Documentation/DMA-API.txt                 |   2 +-
>  Documentation/DMA-attributes.txt          |   2 +-
>  arch/arm/include/asm/dma-mapping.h        |  13 ++--
>  arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
>  arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
>  arch/arm/xen/mm.c                         |   4 +-
>  arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
>  drivers/iommu/dma-iommu.c                 |   6 +-
>  drivers/xen/swiotlb-xen.c                 |  14 ++--
>  include/linux/dma-attrs.h                 |  71 --------------------
>  include/linux/dma-iommu.h                 |   6 +-
>  include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
>  include/linux/swiotlb.h                   |  10 +--
>  include/xen/swiotlb-xen.h                 |  12 ++--
>  lib/dma-noop.c                            |   9 +--
>  lib/swiotlb.c                             |  13 ++--
>  20 files changed, 195 insertions(+), 252 deletions(-)
>  delete mode 100644 include/linux/dma-attrs.h
> 
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index 45ef3f279c3b..0b55cb7c5aaa 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
>  struct dma_attrs*.
>  
>  struct dma_attrs encapsulates a set of "DMA attributes". For the
> -definition of struct dma_attrs see linux/dma-attrs.h.
> +definition of struct dma_attrs see linux/dma-mapping.h.
>  
>  The interpretation of DMA attributes is architecture-specific, and
>  each attribute should be documented in Documentation/DMA-attributes.txt.
> diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
> index e8cf9cf873b3..2d455a5cf671 100644
> --- a/Documentation/DMA-attributes.txt
> +++ b/Documentation/DMA-attributes.txt
> @@ -2,7 +2,7 @@
>  			==============
>  
>  This document describes the semantics of the DMA attributes that are
> -defined in linux/dma-attrs.h.
> +defined in linux/dma-mapping.h.
>  
>  DMA_ATTR_WRITE_BARRIER
>  ----------------------
> diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> index a83570f10124..d009f7911ffc 100644
> --- a/arch/arm/include/asm/dma-mapping.h
> +++ b/arch/arm/include/asm/dma-mapping.h
> @@ -5,7 +5,6 @@
>  
>  #include <linux/mm_types.h>
>  #include <linux/scatterlist.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  
>  #include <asm/memory.h>
> @@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
>   * to be the device-viewed address.
>   */
>  extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -			   gfp_t gfp, struct dma_attrs *attrs);
> +			   gfp_t gfp, unsigned long attrs);
>  
>  /**
>   * arm_dma_free - free memory allocated by arm_dma_alloc
> @@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * during and after this call executing are illegal.
>   */
>  extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			 dma_addr_t handle, struct dma_attrs *attrs);
> +			 dma_addr_t handle, unsigned long attrs);
>  
>  /**
>   * arm_dma_mmap - map a coherent DMA allocation into user space
> @@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>   */
>  extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs);
> +			unsigned long attrs);
>  
>  /*
>   * This can be called during early boot to increase the size of the atomic
> @@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
>   * The scatter list versions of the above methods.
>   */
>  extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  
>  #endif /* __KERNEL__ */
>  #endif
> diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
> index 9408a994cc91..95ce6ac3a971 100644
> --- a/arch/arm/include/asm/xen/page-coherent.h
> +++ b/arch/arm/include/asm/xen/page-coherent.h
> @@ -2,15 +2,14 @@
>  #define _ASM_ARM_XEN_PAGE_COHERENT_H
>  
>  #include <asm/page.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-mapping.h>
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs);
> +	     enum dma_data_direction dir, unsigned long attrs);
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  void __xen_dma_sync_single_for_cpu(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
> @@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
>  static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t flags,
> -		struct dma_attrs *attrs)
> +		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
>  {
>  	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
>  }
>  
>  static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> -		void *cpu_addr, dma_addr_t dma_handle,
> -		struct dma_attrs *attrs)
> +		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
>  {
>  	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
>  }
>  
>  static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long page_pfn = page_to_xen_pfn(page);
>  	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> @@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  }
>  
>  static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long pfn = PFN_DOWN(handle);
>  	/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ff7ed5697d3e..fe31fbfd926d 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
>   */
>  static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  
>  static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
>  }
> @@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
>   * whatever the device wrote there.
>   */
>  static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
> @@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
>  EXPORT_SYMBOL(arm_dma_ops);
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs);
> +				  dma_addr_t handle, unsigned long attrs);
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs);
> +		 unsigned long attrs);
>  
>  struct dma_map_ops arm_coherent_dma_ops = {
>  	.alloc			= arm_coherent_dma_alloc,
> @@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
>  	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
>  }
>  
> -static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
> +static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
>  {
>  	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
>  			    pgprot_writecombine(prot) :
> @@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
>  
>  static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  			 gfp_t gfp, pgprot_t prot, bool is_coherent,
> -			 struct dma_attrs *attrs, const void *caller)
> +			 unsigned long attrs, const void *caller)
>  {
>  	u64 mask = get_coherent_dma_mask(dev);
>  	struct page *page = NULL;
> @@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * virtual and bus address for that space.
>   */
>  void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -		    gfp_t gfp, struct dma_attrs *attrs)
> +		    gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  
> @@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  }
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
>  			   attrs, __builtin_return_address(0));
> @@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
>  
>  static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  #ifdef CONFIG_MMU
> @@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   */
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
>  }
>  
>  int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  #ifdef CONFIG_MMU
>  	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> @@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   * Free a buffer as defined by the above mapping.
>   */
>  static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			   dma_addr_t handle, struct dma_attrs *attrs,
> +			   dma_addr_t handle, unsigned long attrs,
>  			   bool is_coherent)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
> @@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>  }
>  
>  void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -		  dma_addr_t handle, struct dma_attrs *attrs)
> +		  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
>  }
>  
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs)
> +				  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
>  }
>  
>  int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		 void *cpu_addr, dma_addr_t handle, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
>  	int ret;
> @@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
>   * here.
>   */
>  int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>  static const int iommu_order_array[] = { 9, 8, 4, 0 };
>  
>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> -					  gfp_t gfp, struct dma_attrs *attrs)
> +					  gfp_t gfp, unsigned long attrs)
>  {
>  	struct page **pages;
>  	int count = size >> PAGE_SHIFT;
> @@ -1342,7 +1341,7 @@ error:
>  }
>  
>  static int __iommu_free_buffer(struct device *dev, struct page **pages,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	int count = size >> PAGE_SHIFT;
>  	int i;
> @@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
>  	return (struct page **)page;
>  }
>  
> -static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
> +static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  
> @@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>  }
>  
>  static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1532,7 +1531,7 @@ err_buffer:
>  
>  static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		    struct dma_attrs *attrs)
> +		    unsigned long attrs)
>  {
>  	unsigned long uaddr = vma->vm_start;
>  	unsigned long usize = vma->vm_end - vma->vm_start;
> @@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   * Must not be called with IRQs disabled.
>   */
>  void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			  dma_addr_t handle, struct dma_attrs *attrs)
> +			  dma_addr_t handle, unsigned long attrs)
>  {
>  	struct page **pages;
>  	size = PAGE_ALIGN(size);
> @@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  
>  static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t dma_addr,
> -				 size_t size, struct dma_attrs *attrs)
> +				 size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
> @@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
>   */
>  static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
>  			  size_t size, dma_addr_t *handle,
> -			  enum dma_data_direction dir, struct dma_attrs *attrs,
> +			  enum dma_data_direction dir, unsigned long attrs,
>  			  bool is_coherent)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> @@ -1676,7 +1675,7 @@ fail:
>  }
>  
>  static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs,
> +		     enum dma_data_direction dir, unsigned long attrs,
>  		     bool is_coherent)
>  {
>  	struct scatterlist *s = sg, *dma = sg, *start = sg;
> @@ -1734,7 +1733,7 @@ bad_mapping:
>   * obtained via sg_dma_{address,length}.
>   */
>  int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
>   * sg_dma_{address,length}.
>   */
>  int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
>  }
>  
>  static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
> -		bool is_coherent)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs, bool is_coherent)
>  {
>  	struct scatterlist *s;
>  	int i;
> @@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -			enum dma_data_direction dir, struct dma_attrs *attrs)
> +			enum dma_data_direction dir,
> +			unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
>  }
> @@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>   */
>  static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t dma_addr;
> @@ -1889,7 +1890,7 @@ fail:
>   */
>  static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>   * Coherent IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>   * IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>  	if (!iova)
>  		return;
>  
> +	// FIXME: replace get with simple check
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(page, offset, size, dir);
>  
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index c5f9a9e3d1f3..fc67ed236a10 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (is_device_dma_coherent(hwdev))
>  		return;
> @@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		unsigned long attrs)
>  
>  {
>  	if (is_device_dma_coherent(hwdev))
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec83719f..a7686028dfeb 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -29,7 +29,7 @@
>  
>  #include <asm/cacheflush.h>
>  
> -static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
> +static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
>  				 bool coherent)
>  {
>  	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
> @@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
>  
>  static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  				  dma_addr_t *dma_handle, gfp_t flags,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	if (dev == NULL) {
>  		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
> @@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  
>  static void __dma_free_coherent(struct device *dev, size_t size,
>  				void *vaddr, dma_addr_t dma_handle,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool freed;
>  	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
> @@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
>  
>  static void *__dma_alloc(struct device *dev, size_t size,
>  			 dma_addr_t *dma_handle, gfp_t flags,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct page *page;
>  	void *ptr, *coherent_ptr;
> @@ -185,7 +185,7 @@ no_mem:
>  
>  static void __dma_free(struct device *dev, size_t size,
>  		       void *vaddr, dma_addr_t dma_handle,
> -		       struct dma_attrs *attrs)
> +		       unsigned long attrs)
>  {
>  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
>  
> @@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
>  static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  				     unsigned long offset, size_t size,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	dma_addr_t dev_addr;
>  
> @@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  
>  static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  				 size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	if (!is_device_dma_coherent(dev))
>  		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
> @@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  
>  static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				  int nelems, enum dma_data_direction dir,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i, ret;
> @@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __swiotlb_unmap_sg_attrs(struct device *dev,
>  				     struct scatterlist *sgl, int nelems,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
>  static int __swiotlb_mmap(struct device *dev,
>  			  struct vm_area_struct *vma,
>  			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
> @@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
>  
>  static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t handle, size_t size,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
>  
> @@ -425,21 +425,21 @@ out:
>  
>  static void *__dummy_alloc(struct device *dev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	return NULL;
>  }
>  
>  static void __dummy_free(struct device *dev, size_t size,
>  			 void *vaddr, dma_addr_t dma_handle,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_mmap(struct device *dev,
>  			struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	return -ENXIO;
>  }
> @@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
>  static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	return DMA_ERROR_CODE;
>  }
>  
>  static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  			  int nelems, enum dma_data_direction dir,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	return 0;
>  }
> @@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  static void __dummy_unmap_sg(struct device *dev,
>  			     struct scatterlist *sgl, int nelems,
>  			     enum dma_data_direction dir,
> -			     struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  }
>  
> @@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
>  
>  static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  				 dma_addr_t *handle, gfp_t gfp,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
> @@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  }
>  
>  static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			       dma_addr_t handle, struct dma_attrs *attrs)
> +			       dma_addr_t handle,
> +			       unsigned long attrs)
>  {
>  	size_t iosize = size;
>  
> @@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  	 * Hence how dodgy the below logic looks...
>  	 */
>  	if (__in_atomic_pool(cpu_addr, size)) {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_from_pool(cpu_addr, size);
>  	} else if (is_vmalloc_addr(cpu_addr)){
>  		struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  		iommu_dma_free(dev, area->pages, iosize, &handle);
>  		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>  	} else {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_pages(virt_to_page(cpu_addr), get_order(size));
>  	}
>  }
>  
>  static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			      struct dma_attrs *attrs)
> +			      unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  	int ret;
> @@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  
>  static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  			       void *cpu_addr, dma_addr_t dma_addr,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
>  static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int prot = dma_direction_to_prot(dir, coherent);
> @@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  
>  static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
> @@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
>  
>  static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				int nelems, enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  
> @@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __iommu_unmap_sg_attrs(struct device *dev,
>  				   struct scatterlist *sgl, int nelems,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> index 67dcd6831291..dd091175fc2d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> @@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 493552368295..f65e6b7ef93b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -17,7 +17,6 @@
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include <linux/dma-mapping.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/of.h>
>  
>  #include <drm/drmP.h>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index cdf9f1af4347..f2ae72ba7d5a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -24,7 +24,7 @@
>  static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  {
>  	struct drm_device *dev = exynos_gem->base.dev;
> -	enum dma_attr attr;
> +	unsigned long attr;
>  	unsigned int nr_pages;
>  	struct sg_table sgt;
>  	int ret = -ENOMEM;
> @@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  		return 0;
>  	}
>  
> -	init_dma_attrs(&exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs = 0;
>  
>  	/*
>  	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
> @@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	 * as possible.
>  	 */
>  	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
> -		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
> +		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
>  
>  	/*
>  	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
> @@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	else
>  		attr = DMA_ATTR_NON_CONSISTENT;
>  
> -	dma_set_attr(attr, &exynos_gem->dma_attrs);
> -	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs |= attr;
> +	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
>  
>  	nr_pages = exynos_gem->size >> PAGE_SHIFT;
>  
> @@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
>  					     &exynos_gem->dma_addr, GFP_KERNEL,
> -					     &exynos_gem->dma_attrs);
> +					     exynos_gem->dma_attrs);
>  	if (!exynos_gem->cookie) {
>  		DRM_ERROR("failed to allocate buffer.\n");
>  		goto err_free;
> @@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
>  				    exynos_gem->dma_addr, exynos_gem->size,
> -				    &exynos_gem->dma_attrs);
> +				    exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to get sgtable.\n");
>  		goto err_dma_free;
> @@ -99,7 +99,7 @@ err_sgt_free:
>  	sg_free_table(&sgt);
>  err_dma_free:
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
> -		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
> +		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
>  err_free:
>  	drm_free_large(exynos_gem->pages);
>  
> @@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
>  			(dma_addr_t)exynos_gem->dma_addr,
> -			&exynos_gem->dma_attrs);
> +			exynos_gem->dma_attrs);
>  
>  	drm_free_large(exynos_gem->pages);
>  }
> @@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> index 78100742281d..df7c543d6558 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> @@ -50,7 +50,7 @@ struct exynos_drm_gem {
>  	void			*cookie;
>  	void __iomem		*kvaddr;
>  	dma_addr_t		dma_addr;
> -	struct dma_attrs	dma_attrs;
> +	unsigned long		dma_attrs;
>  	struct page		**pages;
>  	struct sg_table		*sgt;
>  };
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index ea5a9ebf0f78..6c1bda504fb1 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>   *	   or NULL on failure.
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t))
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> @@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
>  }
>  
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
>  }
> @@ -560,7 +560,7 @@ out_restore_sg:
>  }
>  
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	/*
>  	 * The scatterlist segments are mapped into a single
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index 7399782c0998..87e6035c9e81 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -294,7 +294,7 @@ error:
>  void *
>  xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	void *ret;
>  	int order = get_order(size);
> @@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
>  
>  void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
> -			  dma_addr_t dev_addr, struct dma_attrs *attrs)
> +			  dma_addr_t dev_addr, unsigned long attrs)
>  {
>  	int order = get_order(size);
>  	phys_addr_t phys;
> @@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
>  dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				unsigned long offset, size_t size,
>  				enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = xen_phys_to_bus(phys);
> @@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
>   */
>  static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  			     size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
>  
> @@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			    size_t size, enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
>  }
> @@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
>  int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
>  void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
> deleted file mode 100644
> index 5246239a4953..000000000000
> --- a/include/linux/dma-attrs.h
> +++ /dev/null
> @@ -1,71 +0,0 @@
> -#ifndef _DMA_ATTR_H
> -#define _DMA_ATTR_H
> -
> -#include <linux/bitmap.h>
> -#include <linux/bitops.h>
> -#include <linux/bug.h>
> -
> -/**
> - * an enum dma_attr represents an attribute associated with a DMA
> - * mapping. The semantics of each attribute should be defined in
> - * Documentation/DMA-attributes.txt.
> - */
> -enum dma_attr {
> -	DMA_ATTR_WRITE_BARRIER,
> -	DMA_ATTR_WEAK_ORDERING,
> -	DMA_ATTR_WRITE_COMBINE,
> -	DMA_ATTR_NON_CONSISTENT,
> -	DMA_ATTR_NO_KERNEL_MAPPING,
> -	DMA_ATTR_SKIP_CPU_SYNC,
> -	DMA_ATTR_FORCE_CONTIGUOUS,
> -	DMA_ATTR_ALLOC_SINGLE_PAGES,
> -	DMA_ATTR_MAX,
> -};
> -
> -#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
> -
> -/**
> - * struct dma_attrs - an opaque container for DMA attributes
> - * @flags - bitmask representing a collection of enum dma_attr
> - */
> -struct dma_attrs {
> -	unsigned long flags[__DMA_ATTRS_LONGS];
> -};
> -
> -#define DEFINE_DMA_ATTRS(x) 					\
> -	struct dma_attrs x = {					\
> -		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
> -	}
> -
> -static inline void init_dma_attrs(struct dma_attrs *attrs)
> -{
> -	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
> -}
> -
> -/**
> - * dma_set_attr - set a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	__set_bit(attr, attrs->flags);
> -}
> -
> -/**
> - * dma_get_attr - check for a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return 0;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	return test_bit(attr, attrs->flags);
> -}
> -
> -#endif /* _DMA_ATTR_H */
> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> index 8443bbb5c071..81c5c8d167ad 100644
> --- a/include/linux/dma-iommu.h
> +++ b/include/linux/dma-iommu.h
> @@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
>   * the arch code to take care of attributes and cache maintenance
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t));
>  void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>  		dma_addr_t *handle);
> @@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>   * directly as DMA mapping callbacks for simplicity
>   */
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  int iommu_dma_supported(struct device *dev, u64 mask);
>  int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>  
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 71c1b215ef66..19e581d5f8b4 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -5,13 +5,25 @@
>  #include <linux/string.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  #include <linux/dma-direction.h>
>  #include <linux/scatterlist.h>
>  #include <linux/kmemcheck.h>
>  #include <linux/bug.h>
>  
> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> +
>  /*
>   * 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.  A CPU cannot
> @@ -21,34 +33,35 @@
>  struct dma_map_ops {
>  	void* (*alloc)(struct device *dev, size_t size,
>  				dma_addr_t *dma_handle, gfp_t gfp,
> -				struct dma_attrs *attrs);
> +				unsigned long attrs);
>  	void (*free)(struct device *dev, size_t size,
>  			      void *vaddr, dma_addr_t dma_handle,
> -			      struct dma_attrs *attrs);
> +			      unsigned long attrs);
>  	int (*mmap)(struct device *, struct vm_area_struct *,
> -			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
> +			  void *, dma_addr_t, size_t,
> +			  unsigned long attrs);
>  
>  	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
> -			   dma_addr_t, size_t, struct dma_attrs *attrs);
> +			   dma_addr_t, size_t, unsigned long attrs);
>  
>  	dma_addr_t (*map_page)(struct device *dev, struct page *page,
>  			       unsigned long offset, size_t size,
>  			       enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
>  			   size_t size, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  	/*
>  	 * map_sg returns 0 on error and a value > 0 on success.
>  	 * It should never return a value < 0.
>  	 */
>  	int (*map_sg)(struct device *dev, struct scatterlist *sg,
>  		      int nents, enum dma_data_direction dir,
> -		      struct dma_attrs *attrs);
> +		      unsigned long attrs);
>  	void (*unmap_sg)(struct device *dev,
>  			 struct scatterlist *sg, int nents,
>  			 enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  	void (*sync_single_for_cpu)(struct device *dev,
>  				    dma_addr_t dma_handle, size_t size,
>  				    enum dma_data_direction dir);
> @@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
>  	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
>  }
>  
> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}
> +
>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>  /*
>   * These three functions are only for dma allocator.
> @@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
>  static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  					      size_t size,
>  					      enum dma_data_direction dir,
> -					      struct dma_attrs *attrs)
> +					      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	dma_addr_t addr;
> @@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>  					  size_t size,
>  					  enum dma_data_direction dir,
> -					  struct dma_attrs *attrs)
> +					  unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>   */
>  static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				   int nents, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	int i, ents;
> @@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  
>  static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				      int nents, enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
>  
>  	kmemcheck_mark_initialized(page_address(page) + offset, size);
>  	BUG_ON(!valid_dma_direction(dir));
> -	addr = ops->map_page(dev, page, offset, size, dir, NULL);
> +	addr = ops->map_page(dev, page, offset, size, dir, 0);
>  	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
>  
>  	return addr;
> @@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
>  
>  	BUG_ON(!valid_dma_direction(dir));
>  	if (ops->unmap_page)
> -		ops->unmap_page(dev, addr, size, dir, NULL);
> +		ops->unmap_page(dev, addr, size, dir, 0);
>  	debug_dma_unmap_page(dev, addr, size, dir, false);
>  }
>  
> @@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>  
>  }
>  
> -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
> -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
> -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
> -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
> +#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
> +#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
> +#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
> +#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
>  
>  extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
>  			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
> @@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
>   */
>  static inline int
>  dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
> -	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
>  	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
> +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
>  
>  int
>  dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> @@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
>  
>  static inline int
>  dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
> -		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +		      dma_addr_t dma_addr, size_t size,
> +		      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
> +#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
>  
>  #ifndef arch_dma_alloc_attrs
>  #define arch_dma_alloc_attrs(dev, flag)	(true)
> @@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  
>  static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  				       dma_addr_t *dma_handle, gfp_t flag,
> -				       struct dma_attrs *attrs)
> +				       unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	void *cpu_addr;
> @@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  
>  static inline void dma_free_attrs(struct device *dev, size_t size,
>  				     void *cpu_addr, dma_addr_t dma_handle,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
>  static inline void *dma_alloc_coherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t flag)
>  {
> -	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
> +	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
>  }
>  
>  static inline void dma_free_coherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
>  }
>  
>  static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_handle, gfp,
> +			       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline void dma_free_noncoherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
> +	dma_free_attrs(dev, size, cpu_addr, dma_handle,
> +		       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> @@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
>  static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  				 dma_addr_t *dma_addr, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_addr, gfp,
> +			       DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_alloc_writecombine
>  #define dma_alloc_writecombine dma_alloc_wc
> @@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  static inline void dma_free_wc(struct device *dev, size_t size,
>  			       void *cpu_addr, dma_addr_t dma_addr)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_free_writecombine
>  #define dma_free_writecombine dma_free_wc
> @@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
>  			      void *cpu_addr, dma_addr_t dma_addr,
>  			      size_t size)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
> +	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_mmap_writecombine
>  #define dma_mmap_writecombine dma_mmap_wc
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 017fced60242..5f81f8a187f2 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -6,7 +6,6 @@
>  #include <linux/types.h>
>  
>  struct device;
> -struct dma_attrs;
>  struct page;
>  struct scatterlist;
>  
> @@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
>  extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  
>  extern int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
> @@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
>  
>  extern int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs);
> +		     enum dma_data_direction dir,
> +		     unsigned long attrs);
>  
>  extern void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  		       int nelems, enum dma_data_direction dir,
> -		       struct dma_attrs *attrs);
> +		       unsigned long attrs);
>  
>  extern void
>  swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
> index 8b2eb93ae8ba..7c35e279d1e3 100644
> --- a/include/xen/swiotlb-xen.h
> +++ b/include/xen/swiotlb-xen.h
> @@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
>  extern void
>  *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t flags,
> -			    struct dma_attrs *attrs);
> +			    unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
>  			  void *vaddr, dma_addr_t dma_handle,
> -			  struct dma_attrs *attrs);
> +			  unsigned long attrs);
>  
>  extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				       unsigned long offset, size_t size,
>  				       enum dma_data_direction dir,
> -				       struct dma_attrs *attrs);
> +				       unsigned long attrs);
>  
>  extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  				   size_t size, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/lib/dma-noop.c b/lib/dma-noop.c
> index 72145646857e..3d766e78fbe2 100644
> --- a/lib/dma-noop.c
> +++ b/lib/dma-noop.c
> @@ -10,7 +10,7 @@
>  
>  static void *dma_noop_alloc(struct device *dev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t gfp,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	void *ret;
>  
> @@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
>  
>  static void dma_noop_free(struct device *dev, size_t size,
>  			  void *cpu_addr, dma_addr_t dma_addr,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	free_pages((unsigned long)cpu_addr, get_order(size));
>  }
> @@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
>  static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
>  				      unsigned long offset, size_t size,
>  				      enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	return page_to_phys(page) + offset;
>  }
>  
>  static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
> -			     enum dma_data_direction dir, struct dma_attrs *attrs)
> +			     enum dma_data_direction dir,
> +			     unsigned long attrs)
>  {
>  	int i;
>  	struct scatterlist *sg;
> diff --git a/lib/swiotlb.c b/lib/swiotlb.c
> index 76f29ecba8f4..22e13a0e19d7 100644
> --- a/lib/swiotlb.c
> +++ b/lib/swiotlb.c
> @@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
>  dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  			    unsigned long offset, size_t size,
>  			    enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = phys_to_dma(dev, phys);
> @@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			size_t size, enum dma_data_direction dir,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	unmap_single(hwdev, dev_addr, size, dir);
>  }
> @@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
>   */
>  int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs)
> +		     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -914,7 +914,7 @@ int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  	       enum dma_data_direction dir)
>  {
> -	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_map_sg);
>  
> @@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
>   */
>  void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
> -		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		       int nelems, enum dma_data_direction dir,
> +		       unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -941,7 +942,7 @@ void
>  swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  		 enum dma_data_direction dir)
>  {
> -	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_unmap_sg);
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-31 18:15     ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 24+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-05-31 18:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Bartlomiej Zolnierkiewicz, Will Deacon, Russell King, dri-devel,
	linux-kernel, hch, iommu, linux-samsung-soc, sstabellini,
	Andy Lutomirski, xen-devel, Andrew Morton, Mel Gorman,
	linux-arm-kernel, Marek Szyprowski

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.


.. why not go the next step a do an enum? Perhaps that should be mentioned
as part of the description?

Thanks.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
>  Documentation/DMA-API.txt                 |   2 +-
>  Documentation/DMA-attributes.txt          |   2 +-
>  arch/arm/include/asm/dma-mapping.h        |  13 ++--
>  arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
>  arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
>  arch/arm/xen/mm.c                         |   4 +-
>  arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
>  drivers/iommu/dma-iommu.c                 |   6 +-
>  drivers/xen/swiotlb-xen.c                 |  14 ++--
>  include/linux/dma-attrs.h                 |  71 --------------------
>  include/linux/dma-iommu.h                 |   6 +-
>  include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
>  include/linux/swiotlb.h                   |  10 +--
>  include/xen/swiotlb-xen.h                 |  12 ++--
>  lib/dma-noop.c                            |   9 +--
>  lib/swiotlb.c                             |  13 ++--
>  20 files changed, 195 insertions(+), 252 deletions(-)
>  delete mode 100644 include/linux/dma-attrs.h
> 
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index 45ef3f279c3b..0b55cb7c5aaa 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
>  struct dma_attrs*.
>  
>  struct dma_attrs encapsulates a set of "DMA attributes". For the
> -definition of struct dma_attrs see linux/dma-attrs.h.
> +definition of struct dma_attrs see linux/dma-mapping.h.
>  
>  The interpretation of DMA attributes is architecture-specific, and
>  each attribute should be documented in Documentation/DMA-attributes.txt.
> diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
> index e8cf9cf873b3..2d455a5cf671 100644
> --- a/Documentation/DMA-attributes.txt
> +++ b/Documentation/DMA-attributes.txt
> @@ -2,7 +2,7 @@
>  			==============
>  
>  This document describes the semantics of the DMA attributes that are
> -defined in linux/dma-attrs.h.
> +defined in linux/dma-mapping.h.
>  
>  DMA_ATTR_WRITE_BARRIER
>  ----------------------
> diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> index a83570f10124..d009f7911ffc 100644
> --- a/arch/arm/include/asm/dma-mapping.h
> +++ b/arch/arm/include/asm/dma-mapping.h
> @@ -5,7 +5,6 @@
>  
>  #include <linux/mm_types.h>
>  #include <linux/scatterlist.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  
>  #include <asm/memory.h>
> @@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
>   * to be the device-viewed address.
>   */
>  extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -			   gfp_t gfp, struct dma_attrs *attrs);
> +			   gfp_t gfp, unsigned long attrs);
>  
>  /**
>   * arm_dma_free - free memory allocated by arm_dma_alloc
> @@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * during and after this call executing are illegal.
>   */
>  extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			 dma_addr_t handle, struct dma_attrs *attrs);
> +			 dma_addr_t handle, unsigned long attrs);
>  
>  /**
>   * arm_dma_mmap - map a coherent DMA allocation into user space
> @@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>   */
>  extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs);
> +			unsigned long attrs);
>  
>  /*
>   * This can be called during early boot to increase the size of the atomic
> @@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
>   * The scatter list versions of the above methods.
>   */
>  extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  
>  #endif /* __KERNEL__ */
>  #endif
> diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
> index 9408a994cc91..95ce6ac3a971 100644
> --- a/arch/arm/include/asm/xen/page-coherent.h
> +++ b/arch/arm/include/asm/xen/page-coherent.h
> @@ -2,15 +2,14 @@
>  #define _ASM_ARM_XEN_PAGE_COHERENT_H
>  
>  #include <asm/page.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-mapping.h>
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs);
> +	     enum dma_data_direction dir, unsigned long attrs);
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  void __xen_dma_sync_single_for_cpu(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
> @@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
>  static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t flags,
> -		struct dma_attrs *attrs)
> +		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
>  {
>  	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
>  }
>  
>  static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> -		void *cpu_addr, dma_addr_t dma_handle,
> -		struct dma_attrs *attrs)
> +		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
>  {
>  	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
>  }
>  
>  static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long page_pfn = page_to_xen_pfn(page);
>  	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> @@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  }
>  
>  static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long pfn = PFN_DOWN(handle);
>  	/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ff7ed5697d3e..fe31fbfd926d 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
>   */
>  static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  
>  static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
>  }
> @@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
>   * whatever the device wrote there.
>   */
>  static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
> @@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
>  EXPORT_SYMBOL(arm_dma_ops);
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs);
> +				  dma_addr_t handle, unsigned long attrs);
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs);
> +		 unsigned long attrs);
>  
>  struct dma_map_ops arm_coherent_dma_ops = {
>  	.alloc			= arm_coherent_dma_alloc,
> @@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
>  	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
>  }
>  
> -static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
> +static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
>  {
>  	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
>  			    pgprot_writecombine(prot) :
> @@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
>  
>  static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  			 gfp_t gfp, pgprot_t prot, bool is_coherent,
> -			 struct dma_attrs *attrs, const void *caller)
> +			 unsigned long attrs, const void *caller)
>  {
>  	u64 mask = get_coherent_dma_mask(dev);
>  	struct page *page = NULL;
> @@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * virtual and bus address for that space.
>   */
>  void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -		    gfp_t gfp, struct dma_attrs *attrs)
> +		    gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  
> @@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  }
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
>  			   attrs, __builtin_return_address(0));
> @@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
>  
>  static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  #ifdef CONFIG_MMU
> @@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   */
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
>  }
>  
>  int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  #ifdef CONFIG_MMU
>  	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> @@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   * Free a buffer as defined by the above mapping.
>   */
>  static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			   dma_addr_t handle, struct dma_attrs *attrs,
> +			   dma_addr_t handle, unsigned long attrs,
>  			   bool is_coherent)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
> @@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>  }
>  
>  void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -		  dma_addr_t handle, struct dma_attrs *attrs)
> +		  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
>  }
>  
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs)
> +				  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
>  }
>  
>  int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		 void *cpu_addr, dma_addr_t handle, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
>  	int ret;
> @@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
>   * here.
>   */
>  int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>  static const int iommu_order_array[] = { 9, 8, 4, 0 };
>  
>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> -					  gfp_t gfp, struct dma_attrs *attrs)
> +					  gfp_t gfp, unsigned long attrs)
>  {
>  	struct page **pages;
>  	int count = size >> PAGE_SHIFT;
> @@ -1342,7 +1341,7 @@ error:
>  }
>  
>  static int __iommu_free_buffer(struct device *dev, struct page **pages,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	int count = size >> PAGE_SHIFT;
>  	int i;
> @@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
>  	return (struct page **)page;
>  }
>  
> -static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
> +static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  
> @@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>  }
>  
>  static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1532,7 +1531,7 @@ err_buffer:
>  
>  static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		    struct dma_attrs *attrs)
> +		    unsigned long attrs)
>  {
>  	unsigned long uaddr = vma->vm_start;
>  	unsigned long usize = vma->vm_end - vma->vm_start;
> @@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   * Must not be called with IRQs disabled.
>   */
>  void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			  dma_addr_t handle, struct dma_attrs *attrs)
> +			  dma_addr_t handle, unsigned long attrs)
>  {
>  	struct page **pages;
>  	size = PAGE_ALIGN(size);
> @@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  
>  static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t dma_addr,
> -				 size_t size, struct dma_attrs *attrs)
> +				 size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
> @@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
>   */
>  static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
>  			  size_t size, dma_addr_t *handle,
> -			  enum dma_data_direction dir, struct dma_attrs *attrs,
> +			  enum dma_data_direction dir, unsigned long attrs,
>  			  bool is_coherent)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> @@ -1676,7 +1675,7 @@ fail:
>  }
>  
>  static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs,
> +		     enum dma_data_direction dir, unsigned long attrs,
>  		     bool is_coherent)
>  {
>  	struct scatterlist *s = sg, *dma = sg, *start = sg;
> @@ -1734,7 +1733,7 @@ bad_mapping:
>   * obtained via sg_dma_{address,length}.
>   */
>  int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
>   * sg_dma_{address,length}.
>   */
>  int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
>  }
>  
>  static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
> -		bool is_coherent)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs, bool is_coherent)
>  {
>  	struct scatterlist *s;
>  	int i;
> @@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -			enum dma_data_direction dir, struct dma_attrs *attrs)
> +			enum dma_data_direction dir,
> +			unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
>  }
> @@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>   */
>  static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t dma_addr;
> @@ -1889,7 +1890,7 @@ fail:
>   */
>  static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>   * Coherent IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>   * IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>  	if (!iova)
>  		return;
>  
> +	// FIXME: replace get with simple check
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(page, offset, size, dir);
>  
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index c5f9a9e3d1f3..fc67ed236a10 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (is_device_dma_coherent(hwdev))
>  		return;
> @@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		unsigned long attrs)
>  
>  {
>  	if (is_device_dma_coherent(hwdev))
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec83719f..a7686028dfeb 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -29,7 +29,7 @@
>  
>  #include <asm/cacheflush.h>
>  
> -static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
> +static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
>  				 bool coherent)
>  {
>  	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
> @@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
>  
>  static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  				  dma_addr_t *dma_handle, gfp_t flags,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	if (dev == NULL) {
>  		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
> @@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  
>  static void __dma_free_coherent(struct device *dev, size_t size,
>  				void *vaddr, dma_addr_t dma_handle,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool freed;
>  	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
> @@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
>  
>  static void *__dma_alloc(struct device *dev, size_t size,
>  			 dma_addr_t *dma_handle, gfp_t flags,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct page *page;
>  	void *ptr, *coherent_ptr;
> @@ -185,7 +185,7 @@ no_mem:
>  
>  static void __dma_free(struct device *dev, size_t size,
>  		       void *vaddr, dma_addr_t dma_handle,
> -		       struct dma_attrs *attrs)
> +		       unsigned long attrs)
>  {
>  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
>  
> @@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
>  static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  				     unsigned long offset, size_t size,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	dma_addr_t dev_addr;
>  
> @@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  
>  static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  				 size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	if (!is_device_dma_coherent(dev))
>  		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
> @@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  
>  static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				  int nelems, enum dma_data_direction dir,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i, ret;
> @@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __swiotlb_unmap_sg_attrs(struct device *dev,
>  				     struct scatterlist *sgl, int nelems,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
>  static int __swiotlb_mmap(struct device *dev,
>  			  struct vm_area_struct *vma,
>  			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
> @@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
>  
>  static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t handle, size_t size,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
>  
> @@ -425,21 +425,21 @@ out:
>  
>  static void *__dummy_alloc(struct device *dev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	return NULL;
>  }
>  
>  static void __dummy_free(struct device *dev, size_t size,
>  			 void *vaddr, dma_addr_t dma_handle,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_mmap(struct device *dev,
>  			struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	return -ENXIO;
>  }
> @@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
>  static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	return DMA_ERROR_CODE;
>  }
>  
>  static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  			  int nelems, enum dma_data_direction dir,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	return 0;
>  }
> @@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  static void __dummy_unmap_sg(struct device *dev,
>  			     struct scatterlist *sgl, int nelems,
>  			     enum dma_data_direction dir,
> -			     struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  }
>  
> @@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
>  
>  static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  				 dma_addr_t *handle, gfp_t gfp,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
> @@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  }
>  
>  static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			       dma_addr_t handle, struct dma_attrs *attrs)
> +			       dma_addr_t handle,
> +			       unsigned long attrs)
>  {
>  	size_t iosize = size;
>  
> @@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  	 * Hence how dodgy the below logic looks...
>  	 */
>  	if (__in_atomic_pool(cpu_addr, size)) {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_from_pool(cpu_addr, size);
>  	} else if (is_vmalloc_addr(cpu_addr)){
>  		struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  		iommu_dma_free(dev, area->pages, iosize, &handle);
>  		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>  	} else {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_pages(virt_to_page(cpu_addr), get_order(size));
>  	}
>  }
>  
>  static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			      struct dma_attrs *attrs)
> +			      unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  	int ret;
> @@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  
>  static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  			       void *cpu_addr, dma_addr_t dma_addr,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
>  static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int prot = dma_direction_to_prot(dir, coherent);
> @@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  
>  static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
> @@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
>  
>  static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				int nelems, enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  
> @@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __iommu_unmap_sg_attrs(struct device *dev,
>  				   struct scatterlist *sgl, int nelems,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> index 67dcd6831291..dd091175fc2d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> @@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 493552368295..f65e6b7ef93b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -17,7 +17,6 @@
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include <linux/dma-mapping.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/of.h>
>  
>  #include <drm/drmP.h>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index cdf9f1af4347..f2ae72ba7d5a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -24,7 +24,7 @@
>  static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  {
>  	struct drm_device *dev = exynos_gem->base.dev;
> -	enum dma_attr attr;
> +	unsigned long attr;
>  	unsigned int nr_pages;
>  	struct sg_table sgt;
>  	int ret = -ENOMEM;
> @@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  		return 0;
>  	}
>  
> -	init_dma_attrs(&exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs = 0;
>  
>  	/*
>  	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
> @@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	 * as possible.
>  	 */
>  	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
> -		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
> +		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
>  
>  	/*
>  	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
> @@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	else
>  		attr = DMA_ATTR_NON_CONSISTENT;
>  
> -	dma_set_attr(attr, &exynos_gem->dma_attrs);
> -	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs |= attr;
> +	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
>  
>  	nr_pages = exynos_gem->size >> PAGE_SHIFT;
>  
> @@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
>  					     &exynos_gem->dma_addr, GFP_KERNEL,
> -					     &exynos_gem->dma_attrs);
> +					     exynos_gem->dma_attrs);
>  	if (!exynos_gem->cookie) {
>  		DRM_ERROR("failed to allocate buffer.\n");
>  		goto err_free;
> @@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
>  				    exynos_gem->dma_addr, exynos_gem->size,
> -				    &exynos_gem->dma_attrs);
> +				    exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to get sgtable.\n");
>  		goto err_dma_free;
> @@ -99,7 +99,7 @@ err_sgt_free:
>  	sg_free_table(&sgt);
>  err_dma_free:
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
> -		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
> +		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
>  err_free:
>  	drm_free_large(exynos_gem->pages);
>  
> @@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
>  			(dma_addr_t)exynos_gem->dma_addr,
> -			&exynos_gem->dma_attrs);
> +			exynos_gem->dma_attrs);
>  
>  	drm_free_large(exynos_gem->pages);
>  }
> @@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> index 78100742281d..df7c543d6558 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> @@ -50,7 +50,7 @@ struct exynos_drm_gem {
>  	void			*cookie;
>  	void __iomem		*kvaddr;
>  	dma_addr_t		dma_addr;
> -	struct dma_attrs	dma_attrs;
> +	unsigned long		dma_attrs;
>  	struct page		**pages;
>  	struct sg_table		*sgt;
>  };
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index ea5a9ebf0f78..6c1bda504fb1 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>   *	   or NULL on failure.
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t))
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> @@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
>  }
>  
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
>  }
> @@ -560,7 +560,7 @@ out_restore_sg:
>  }
>  
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	/*
>  	 * The scatterlist segments are mapped into a single
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index 7399782c0998..87e6035c9e81 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -294,7 +294,7 @@ error:
>  void *
>  xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	void *ret;
>  	int order = get_order(size);
> @@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
>  
>  void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
> -			  dma_addr_t dev_addr, struct dma_attrs *attrs)
> +			  dma_addr_t dev_addr, unsigned long attrs)
>  {
>  	int order = get_order(size);
>  	phys_addr_t phys;
> @@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
>  dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				unsigned long offset, size_t size,
>  				enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = xen_phys_to_bus(phys);
> @@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
>   */
>  static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  			     size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
>  
> @@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			    size_t size, enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
>  }
> @@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
>  int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
>  void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
> deleted file mode 100644
> index 5246239a4953..000000000000
> --- a/include/linux/dma-attrs.h
> +++ /dev/null
> @@ -1,71 +0,0 @@
> -#ifndef _DMA_ATTR_H
> -#define _DMA_ATTR_H
> -
> -#include <linux/bitmap.h>
> -#include <linux/bitops.h>
> -#include <linux/bug.h>
> -
> -/**
> - * an enum dma_attr represents an attribute associated with a DMA
> - * mapping. The semantics of each attribute should be defined in
> - * Documentation/DMA-attributes.txt.
> - */
> -enum dma_attr {
> -	DMA_ATTR_WRITE_BARRIER,
> -	DMA_ATTR_WEAK_ORDERING,
> -	DMA_ATTR_WRITE_COMBINE,
> -	DMA_ATTR_NON_CONSISTENT,
> -	DMA_ATTR_NO_KERNEL_MAPPING,
> -	DMA_ATTR_SKIP_CPU_SYNC,
> -	DMA_ATTR_FORCE_CONTIGUOUS,
> -	DMA_ATTR_ALLOC_SINGLE_PAGES,
> -	DMA_ATTR_MAX,
> -};
> -
> -#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
> -
> -/**
> - * struct dma_attrs - an opaque container for DMA attributes
> - * @flags - bitmask representing a collection of enum dma_attr
> - */
> -struct dma_attrs {
> -	unsigned long flags[__DMA_ATTRS_LONGS];
> -};
> -
> -#define DEFINE_DMA_ATTRS(x) 					\
> -	struct dma_attrs x = {					\
> -		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
> -	}
> -
> -static inline void init_dma_attrs(struct dma_attrs *attrs)
> -{
> -	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
> -}
> -
> -/**
> - * dma_set_attr - set a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	__set_bit(attr, attrs->flags);
> -}
> -
> -/**
> - * dma_get_attr - check for a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return 0;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	return test_bit(attr, attrs->flags);
> -}
> -
> -#endif /* _DMA_ATTR_H */
> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> index 8443bbb5c071..81c5c8d167ad 100644
> --- a/include/linux/dma-iommu.h
> +++ b/include/linux/dma-iommu.h
> @@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
>   * the arch code to take care of attributes and cache maintenance
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t));
>  void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>  		dma_addr_t *handle);
> @@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>   * directly as DMA mapping callbacks for simplicity
>   */
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  int iommu_dma_supported(struct device *dev, u64 mask);
>  int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>  
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 71c1b215ef66..19e581d5f8b4 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -5,13 +5,25 @@
>  #include <linux/string.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  #include <linux/dma-direction.h>
>  #include <linux/scatterlist.h>
>  #include <linux/kmemcheck.h>
>  #include <linux/bug.h>
>  
> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> +
>  /*
>   * 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.  A CPU cannot
> @@ -21,34 +33,35 @@
>  struct dma_map_ops {
>  	void* (*alloc)(struct device *dev, size_t size,
>  				dma_addr_t *dma_handle, gfp_t gfp,
> -				struct dma_attrs *attrs);
> +				unsigned long attrs);
>  	void (*free)(struct device *dev, size_t size,
>  			      void *vaddr, dma_addr_t dma_handle,
> -			      struct dma_attrs *attrs);
> +			      unsigned long attrs);
>  	int (*mmap)(struct device *, struct vm_area_struct *,
> -			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
> +			  void *, dma_addr_t, size_t,
> +			  unsigned long attrs);
>  
>  	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
> -			   dma_addr_t, size_t, struct dma_attrs *attrs);
> +			   dma_addr_t, size_t, unsigned long attrs);
>  
>  	dma_addr_t (*map_page)(struct device *dev, struct page *page,
>  			       unsigned long offset, size_t size,
>  			       enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
>  			   size_t size, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  	/*
>  	 * map_sg returns 0 on error and a value > 0 on success.
>  	 * It should never return a value < 0.
>  	 */
>  	int (*map_sg)(struct device *dev, struct scatterlist *sg,
>  		      int nents, enum dma_data_direction dir,
> -		      struct dma_attrs *attrs);
> +		      unsigned long attrs);
>  	void (*unmap_sg)(struct device *dev,
>  			 struct scatterlist *sg, int nents,
>  			 enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  	void (*sync_single_for_cpu)(struct device *dev,
>  				    dma_addr_t dma_handle, size_t size,
>  				    enum dma_data_direction dir);
> @@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
>  	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
>  }
>  
> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}
> +
>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>  /*
>   * These three functions are only for dma allocator.
> @@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
>  static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  					      size_t size,
>  					      enum dma_data_direction dir,
> -					      struct dma_attrs *attrs)
> +					      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	dma_addr_t addr;
> @@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>  					  size_t size,
>  					  enum dma_data_direction dir,
> -					  struct dma_attrs *attrs)
> +					  unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>   */
>  static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				   int nents, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	int i, ents;
> @@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  
>  static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				      int nents, enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
>  
>  	kmemcheck_mark_initialized(page_address(page) + offset, size);
>  	BUG_ON(!valid_dma_direction(dir));
> -	addr = ops->map_page(dev, page, offset, size, dir, NULL);
> +	addr = ops->map_page(dev, page, offset, size, dir, 0);
>  	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
>  
>  	return addr;
> @@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
>  
>  	BUG_ON(!valid_dma_direction(dir));
>  	if (ops->unmap_page)
> -		ops->unmap_page(dev, addr, size, dir, NULL);
> +		ops->unmap_page(dev, addr, size, dir, 0);
>  	debug_dma_unmap_page(dev, addr, size, dir, false);
>  }
>  
> @@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>  
>  }
>  
> -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
> -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
> -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
> -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
> +#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
> +#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
> +#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
> +#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
>  
>  extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
>  			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
> @@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
>   */
>  static inline int
>  dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
> -	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
>  	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
> +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
>  
>  int
>  dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> @@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
>  
>  static inline int
>  dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
> -		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +		      dma_addr_t dma_addr, size_t size,
> +		      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
> +#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
>  
>  #ifndef arch_dma_alloc_attrs
>  #define arch_dma_alloc_attrs(dev, flag)	(true)
> @@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  
>  static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  				       dma_addr_t *dma_handle, gfp_t flag,
> -				       struct dma_attrs *attrs)
> +				       unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	void *cpu_addr;
> @@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  
>  static inline void dma_free_attrs(struct device *dev, size_t size,
>  				     void *cpu_addr, dma_addr_t dma_handle,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
>  static inline void *dma_alloc_coherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t flag)
>  {
> -	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
> +	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
>  }
>  
>  static inline void dma_free_coherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
>  }
>  
>  static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_handle, gfp,
> +			       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline void dma_free_noncoherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
> +	dma_free_attrs(dev, size, cpu_addr, dma_handle,
> +		       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> @@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
>  static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  				 dma_addr_t *dma_addr, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_addr, gfp,
> +			       DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_alloc_writecombine
>  #define dma_alloc_writecombine dma_alloc_wc
> @@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  static inline void dma_free_wc(struct device *dev, size_t size,
>  			       void *cpu_addr, dma_addr_t dma_addr)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_free_writecombine
>  #define dma_free_writecombine dma_free_wc
> @@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
>  			      void *cpu_addr, dma_addr_t dma_addr,
>  			      size_t size)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
> +	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_mmap_writecombine
>  #define dma_mmap_writecombine dma_mmap_wc
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 017fced60242..5f81f8a187f2 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -6,7 +6,6 @@
>  #include <linux/types.h>
>  
>  struct device;
> -struct dma_attrs;
>  struct page;
>  struct scatterlist;
>  
> @@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
>  extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  
>  extern int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
> @@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
>  
>  extern int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs);
> +		     enum dma_data_direction dir,
> +		     unsigned long attrs);
>  
>  extern void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  		       int nelems, enum dma_data_direction dir,
> -		       struct dma_attrs *attrs);
> +		       unsigned long attrs);
>  
>  extern void
>  swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
> index 8b2eb93ae8ba..7c35e279d1e3 100644
> --- a/include/xen/swiotlb-xen.h
> +++ b/include/xen/swiotlb-xen.h
> @@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
>  extern void
>  *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t flags,
> -			    struct dma_attrs *attrs);
> +			    unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
>  			  void *vaddr, dma_addr_t dma_handle,
> -			  struct dma_attrs *attrs);
> +			  unsigned long attrs);
>  
>  extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				       unsigned long offset, size_t size,
>  				       enum dma_data_direction dir,
> -				       struct dma_attrs *attrs);
> +				       unsigned long attrs);
>  
>  extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  				   size_t size, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/lib/dma-noop.c b/lib/dma-noop.c
> index 72145646857e..3d766e78fbe2 100644
> --- a/lib/dma-noop.c
> +++ b/lib/dma-noop.c
> @@ -10,7 +10,7 @@
>  
>  static void *dma_noop_alloc(struct device *dev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t gfp,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	void *ret;
>  
> @@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
>  
>  static void dma_noop_free(struct device *dev, size_t size,
>  			  void *cpu_addr, dma_addr_t dma_addr,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	free_pages((unsigned long)cpu_addr, get_order(size));
>  }
> @@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
>  static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
>  				      unsigned long offset, size_t size,
>  				      enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	return page_to_phys(page) + offset;
>  }
>  
>  static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
> -			     enum dma_data_direction dir, struct dma_attrs *attrs)
> +			     enum dma_data_direction dir,
> +			     unsigned long attrs)
>  {
>  	int i;
>  	struct scatterlist *sg;
> diff --git a/lib/swiotlb.c b/lib/swiotlb.c
> index 76f29ecba8f4..22e13a0e19d7 100644
> --- a/lib/swiotlb.c
> +++ b/lib/swiotlb.c
> @@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
>  dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  			    unsigned long offset, size_t size,
>  			    enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = phys_to_dma(dev, phys);
> @@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			size_t size, enum dma_data_direction dir,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	unmap_single(hwdev, dev_addr, size, dir);
>  }
> @@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
>   */
>  int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs)
> +		     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -914,7 +914,7 @@ int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  	       enum dma_data_direction dir)
>  {
> -	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_map_sg);
>  
> @@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
>   */
>  void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
> -		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		       int nelems, enum dma_data_direction dir,
> +		       unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -941,7 +942,7 @@ void
>  swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  		 enum dma_data_direction dir)
>  {
> -	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_unmap_sg);
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-05-31 18:15     ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 24+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-05-31 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.


.. why not go the next step a do an enum? Perhaps that should be mentioned
as part of the description?

Thanks.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
>  Documentation/DMA-API.txt                 |   2 +-
>  Documentation/DMA-attributes.txt          |   2 +-
>  arch/arm/include/asm/dma-mapping.h        |  13 ++--
>  arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
>  arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
>  arch/arm/xen/mm.c                         |   4 +-
>  arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
>  drivers/iommu/dma-iommu.c                 |   6 +-
>  drivers/xen/swiotlb-xen.c                 |  14 ++--
>  include/linux/dma-attrs.h                 |  71 --------------------
>  include/linux/dma-iommu.h                 |   6 +-
>  include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
>  include/linux/swiotlb.h                   |  10 +--
>  include/xen/swiotlb-xen.h                 |  12 ++--
>  lib/dma-noop.c                            |   9 +--
>  lib/swiotlb.c                             |  13 ++--
>  20 files changed, 195 insertions(+), 252 deletions(-)
>  delete mode 100644 include/linux/dma-attrs.h
> 
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index 45ef3f279c3b..0b55cb7c5aaa 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
>  struct dma_attrs*.
>  
>  struct dma_attrs encapsulates a set of "DMA attributes". For the
> -definition of struct dma_attrs see linux/dma-attrs.h.
> +definition of struct dma_attrs see linux/dma-mapping.h.
>  
>  The interpretation of DMA attributes is architecture-specific, and
>  each attribute should be documented in Documentation/DMA-attributes.txt.
> diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
> index e8cf9cf873b3..2d455a5cf671 100644
> --- a/Documentation/DMA-attributes.txt
> +++ b/Documentation/DMA-attributes.txt
> @@ -2,7 +2,7 @@
>  			==============
>  
>  This document describes the semantics of the DMA attributes that are
> -defined in linux/dma-attrs.h.
> +defined in linux/dma-mapping.h.
>  
>  DMA_ATTR_WRITE_BARRIER
>  ----------------------
> diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> index a83570f10124..d009f7911ffc 100644
> --- a/arch/arm/include/asm/dma-mapping.h
> +++ b/arch/arm/include/asm/dma-mapping.h
> @@ -5,7 +5,6 @@
>  
>  #include <linux/mm_types.h>
>  #include <linux/scatterlist.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  
>  #include <asm/memory.h>
> @@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
>   * to be the device-viewed address.
>   */
>  extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -			   gfp_t gfp, struct dma_attrs *attrs);
> +			   gfp_t gfp, unsigned long attrs);
>  
>  /**
>   * arm_dma_free - free memory allocated by arm_dma_alloc
> @@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * during and after this call executing are illegal.
>   */
>  extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			 dma_addr_t handle, struct dma_attrs *attrs);
> +			 dma_addr_t handle, unsigned long attrs);
>  
>  /**
>   * arm_dma_mmap - map a coherent DMA allocation into user space
> @@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>   */
>  extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs);
> +			unsigned long attrs);
>  
>  /*
>   * This can be called during early boot to increase the size of the atomic
> @@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
>   * The scatter list versions of the above methods.
>   */
>  extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  
>  #endif /* __KERNEL__ */
>  #endif
> diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
> index 9408a994cc91..95ce6ac3a971 100644
> --- a/arch/arm/include/asm/xen/page-coherent.h
> +++ b/arch/arm/include/asm/xen/page-coherent.h
> @@ -2,15 +2,14 @@
>  #define _ASM_ARM_XEN_PAGE_COHERENT_H
>  
>  #include <asm/page.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-mapping.h>
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs);
> +	     enum dma_data_direction dir, unsigned long attrs);
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  void __xen_dma_sync_single_for_cpu(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
> @@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
>  static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t flags,
> -		struct dma_attrs *attrs)
> +		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
>  {
>  	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
>  }
>  
>  static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> -		void *cpu_addr, dma_addr_t dma_handle,
> -		struct dma_attrs *attrs)
> +		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
>  {
>  	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
>  }
>  
>  static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long page_pfn = page_to_xen_pfn(page);
>  	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> @@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  }
>  
>  static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long pfn = PFN_DOWN(handle);
>  	/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ff7ed5697d3e..fe31fbfd926d 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
>   */
>  static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  
>  static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
>  }
> @@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
>   * whatever the device wrote there.
>   */
>  static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
> @@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
>  EXPORT_SYMBOL(arm_dma_ops);
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs);
> +				  dma_addr_t handle, unsigned long attrs);
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs);
> +		 unsigned long attrs);
>  
>  struct dma_map_ops arm_coherent_dma_ops = {
>  	.alloc			= arm_coherent_dma_alloc,
> @@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
>  	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
>  }
>  
> -static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
> +static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
>  {
>  	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
>  			    pgprot_writecombine(prot) :
> @@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
>  
>  static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  			 gfp_t gfp, pgprot_t prot, bool is_coherent,
> -			 struct dma_attrs *attrs, const void *caller)
> +			 unsigned long attrs, const void *caller)
>  {
>  	u64 mask = get_coherent_dma_mask(dev);
>  	struct page *page = NULL;
> @@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * virtual and bus address for that space.
>   */
>  void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -		    gfp_t gfp, struct dma_attrs *attrs)
> +		    gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  
> @@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  }
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
>  			   attrs, __builtin_return_address(0));
> @@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
>  
>  static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  #ifdef CONFIG_MMU
> @@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   */
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
>  }
>  
>  int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  #ifdef CONFIG_MMU
>  	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> @@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   * Free a buffer as defined by the above mapping.
>   */
>  static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			   dma_addr_t handle, struct dma_attrs *attrs,
> +			   dma_addr_t handle, unsigned long attrs,
>  			   bool is_coherent)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
> @@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>  }
>  
>  void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -		  dma_addr_t handle, struct dma_attrs *attrs)
> +		  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
>  }
>  
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs)
> +				  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
>  }
>  
>  int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		 void *cpu_addr, dma_addr_t handle, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
>  	int ret;
> @@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
>   * here.
>   */
>  int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>  static const int iommu_order_array[] = { 9, 8, 4, 0 };
>  
>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> -					  gfp_t gfp, struct dma_attrs *attrs)
> +					  gfp_t gfp, unsigned long attrs)
>  {
>  	struct page **pages;
>  	int count = size >> PAGE_SHIFT;
> @@ -1342,7 +1341,7 @@ error:
>  }
>  
>  static int __iommu_free_buffer(struct device *dev, struct page **pages,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	int count = size >> PAGE_SHIFT;
>  	int i;
> @@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
>  	return (struct page **)page;
>  }
>  
> -static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
> +static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  
> @@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>  }
>  
>  static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1532,7 +1531,7 @@ err_buffer:
>  
>  static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		    struct dma_attrs *attrs)
> +		    unsigned long attrs)
>  {
>  	unsigned long uaddr = vma->vm_start;
>  	unsigned long usize = vma->vm_end - vma->vm_start;
> @@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   * Must not be called with IRQs disabled.
>   */
>  void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			  dma_addr_t handle, struct dma_attrs *attrs)
> +			  dma_addr_t handle, unsigned long attrs)
>  {
>  	struct page **pages;
>  	size = PAGE_ALIGN(size);
> @@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  
>  static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t dma_addr,
> -				 size_t size, struct dma_attrs *attrs)
> +				 size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
> @@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
>   */
>  static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
>  			  size_t size, dma_addr_t *handle,
> -			  enum dma_data_direction dir, struct dma_attrs *attrs,
> +			  enum dma_data_direction dir, unsigned long attrs,
>  			  bool is_coherent)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> @@ -1676,7 +1675,7 @@ fail:
>  }
>  
>  static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs,
> +		     enum dma_data_direction dir, unsigned long attrs,
>  		     bool is_coherent)
>  {
>  	struct scatterlist *s = sg, *dma = sg, *start = sg;
> @@ -1734,7 +1733,7 @@ bad_mapping:
>   * obtained via sg_dma_{address,length}.
>   */
>  int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
>   * sg_dma_{address,length}.
>   */
>  int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
>  }
>  
>  static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
> -		bool is_coherent)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs, bool is_coherent)
>  {
>  	struct scatterlist *s;
>  	int i;
> @@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -			enum dma_data_direction dir, struct dma_attrs *attrs)
> +			enum dma_data_direction dir,
> +			unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
>  }
> @@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>   */
>  static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t dma_addr;
> @@ -1889,7 +1890,7 @@ fail:
>   */
>  static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>   * Coherent IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>   * IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>  	if (!iova)
>  		return;
>  
> +	// FIXME: replace get with simple check
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(page, offset, size, dir);
>  
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index c5f9a9e3d1f3..fc67ed236a10 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (is_device_dma_coherent(hwdev))
>  		return;
> @@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		unsigned long attrs)
>  
>  {
>  	if (is_device_dma_coherent(hwdev))
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec83719f..a7686028dfeb 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -29,7 +29,7 @@
>  
>  #include <asm/cacheflush.h>
>  
> -static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
> +static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
>  				 bool coherent)
>  {
>  	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
> @@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
>  
>  static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  				  dma_addr_t *dma_handle, gfp_t flags,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	if (dev == NULL) {
>  		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
> @@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  
>  static void __dma_free_coherent(struct device *dev, size_t size,
>  				void *vaddr, dma_addr_t dma_handle,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool freed;
>  	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
> @@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
>  
>  static void *__dma_alloc(struct device *dev, size_t size,
>  			 dma_addr_t *dma_handle, gfp_t flags,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct page *page;
>  	void *ptr, *coherent_ptr;
> @@ -185,7 +185,7 @@ no_mem:
>  
>  static void __dma_free(struct device *dev, size_t size,
>  		       void *vaddr, dma_addr_t dma_handle,
> -		       struct dma_attrs *attrs)
> +		       unsigned long attrs)
>  {
>  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
>  
> @@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
>  static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  				     unsigned long offset, size_t size,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	dma_addr_t dev_addr;
>  
> @@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  
>  static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  				 size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	if (!is_device_dma_coherent(dev))
>  		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
> @@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  
>  static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				  int nelems, enum dma_data_direction dir,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i, ret;
> @@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __swiotlb_unmap_sg_attrs(struct device *dev,
>  				     struct scatterlist *sgl, int nelems,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
>  static int __swiotlb_mmap(struct device *dev,
>  			  struct vm_area_struct *vma,
>  			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
> @@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
>  
>  static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t handle, size_t size,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
>  
> @@ -425,21 +425,21 @@ out:
>  
>  static void *__dummy_alloc(struct device *dev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	return NULL;
>  }
>  
>  static void __dummy_free(struct device *dev, size_t size,
>  			 void *vaddr, dma_addr_t dma_handle,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_mmap(struct device *dev,
>  			struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	return -ENXIO;
>  }
> @@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
>  static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	return DMA_ERROR_CODE;
>  }
>  
>  static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  			  int nelems, enum dma_data_direction dir,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	return 0;
>  }
> @@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  static void __dummy_unmap_sg(struct device *dev,
>  			     struct scatterlist *sgl, int nelems,
>  			     enum dma_data_direction dir,
> -			     struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  }
>  
> @@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
>  
>  static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  				 dma_addr_t *handle, gfp_t gfp,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
> @@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  }
>  
>  static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			       dma_addr_t handle, struct dma_attrs *attrs)
> +			       dma_addr_t handle,
> +			       unsigned long attrs)
>  {
>  	size_t iosize = size;
>  
> @@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  	 * Hence how dodgy the below logic looks...
>  	 */
>  	if (__in_atomic_pool(cpu_addr, size)) {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_from_pool(cpu_addr, size);
>  	} else if (is_vmalloc_addr(cpu_addr)){
>  		struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  		iommu_dma_free(dev, area->pages, iosize, &handle);
>  		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>  	} else {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_pages(virt_to_page(cpu_addr), get_order(size));
>  	}
>  }
>  
>  static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			      struct dma_attrs *attrs)
> +			      unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  	int ret;
> @@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  
>  static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  			       void *cpu_addr, dma_addr_t dma_addr,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
>  static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int prot = dma_direction_to_prot(dir, coherent);
> @@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  
>  static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
> @@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
>  
>  static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				int nelems, enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  
> @@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __iommu_unmap_sg_attrs(struct device *dev,
>  				   struct scatterlist *sgl, int nelems,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> index 67dcd6831291..dd091175fc2d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> @@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 493552368295..f65e6b7ef93b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -17,7 +17,6 @@
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include <linux/dma-mapping.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/of.h>
>  
>  #include <drm/drmP.h>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index cdf9f1af4347..f2ae72ba7d5a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -24,7 +24,7 @@
>  static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  {
>  	struct drm_device *dev = exynos_gem->base.dev;
> -	enum dma_attr attr;
> +	unsigned long attr;
>  	unsigned int nr_pages;
>  	struct sg_table sgt;
>  	int ret = -ENOMEM;
> @@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  		return 0;
>  	}
>  
> -	init_dma_attrs(&exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs = 0;
>  
>  	/*
>  	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
> @@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	 * as possible.
>  	 */
>  	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
> -		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
> +		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
>  
>  	/*
>  	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
> @@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	else
>  		attr = DMA_ATTR_NON_CONSISTENT;
>  
> -	dma_set_attr(attr, &exynos_gem->dma_attrs);
> -	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs |= attr;
> +	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
>  
>  	nr_pages = exynos_gem->size >> PAGE_SHIFT;
>  
> @@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
>  					     &exynos_gem->dma_addr, GFP_KERNEL,
> -					     &exynos_gem->dma_attrs);
> +					     exynos_gem->dma_attrs);
>  	if (!exynos_gem->cookie) {
>  		DRM_ERROR("failed to allocate buffer.\n");
>  		goto err_free;
> @@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
>  				    exynos_gem->dma_addr, exynos_gem->size,
> -				    &exynos_gem->dma_attrs);
> +				    exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to get sgtable.\n");
>  		goto err_dma_free;
> @@ -99,7 +99,7 @@ err_sgt_free:
>  	sg_free_table(&sgt);
>  err_dma_free:
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
> -		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
> +		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
>  err_free:
>  	drm_free_large(exynos_gem->pages);
>  
> @@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
>  			(dma_addr_t)exynos_gem->dma_addr,
> -			&exynos_gem->dma_attrs);
> +			exynos_gem->dma_attrs);
>  
>  	drm_free_large(exynos_gem->pages);
>  }
> @@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> index 78100742281d..df7c543d6558 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> @@ -50,7 +50,7 @@ struct exynos_drm_gem {
>  	void			*cookie;
>  	void __iomem		*kvaddr;
>  	dma_addr_t		dma_addr;
> -	struct dma_attrs	dma_attrs;
> +	unsigned long		dma_attrs;
>  	struct page		**pages;
>  	struct sg_table		*sgt;
>  };
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index ea5a9ebf0f78..6c1bda504fb1 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>   *	   or NULL on failure.
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t))
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> @@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
>  }
>  
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
>  }
> @@ -560,7 +560,7 @@ out_restore_sg:
>  }
>  
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	/*
>  	 * The scatterlist segments are mapped into a single
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index 7399782c0998..87e6035c9e81 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -294,7 +294,7 @@ error:
>  void *
>  xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	void *ret;
>  	int order = get_order(size);
> @@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
>  
>  void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
> -			  dma_addr_t dev_addr, struct dma_attrs *attrs)
> +			  dma_addr_t dev_addr, unsigned long attrs)
>  {
>  	int order = get_order(size);
>  	phys_addr_t phys;
> @@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
>  dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				unsigned long offset, size_t size,
>  				enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = xen_phys_to_bus(phys);
> @@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
>   */
>  static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  			     size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
>  
> @@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			    size_t size, enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
>  }
> @@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
>  int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
>  void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
> deleted file mode 100644
> index 5246239a4953..000000000000
> --- a/include/linux/dma-attrs.h
> +++ /dev/null
> @@ -1,71 +0,0 @@
> -#ifndef _DMA_ATTR_H
> -#define _DMA_ATTR_H
> -
> -#include <linux/bitmap.h>
> -#include <linux/bitops.h>
> -#include <linux/bug.h>
> -
> -/**
> - * an enum dma_attr represents an attribute associated with a DMA
> - * mapping. The semantics of each attribute should be defined in
> - * Documentation/DMA-attributes.txt.
> - */
> -enum dma_attr {
> -	DMA_ATTR_WRITE_BARRIER,
> -	DMA_ATTR_WEAK_ORDERING,
> -	DMA_ATTR_WRITE_COMBINE,
> -	DMA_ATTR_NON_CONSISTENT,
> -	DMA_ATTR_NO_KERNEL_MAPPING,
> -	DMA_ATTR_SKIP_CPU_SYNC,
> -	DMA_ATTR_FORCE_CONTIGUOUS,
> -	DMA_ATTR_ALLOC_SINGLE_PAGES,
> -	DMA_ATTR_MAX,
> -};
> -
> -#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
> -
> -/**
> - * struct dma_attrs - an opaque container for DMA attributes
> - * @flags - bitmask representing a collection of enum dma_attr
> - */
> -struct dma_attrs {
> -	unsigned long flags[__DMA_ATTRS_LONGS];
> -};
> -
> -#define DEFINE_DMA_ATTRS(x) 					\
> -	struct dma_attrs x = {					\
> -		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
> -	}
> -
> -static inline void init_dma_attrs(struct dma_attrs *attrs)
> -{
> -	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
> -}
> -
> -/**
> - * dma_set_attr - set a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	__set_bit(attr, attrs->flags);
> -}
> -
> -/**
> - * dma_get_attr - check for a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return 0;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	return test_bit(attr, attrs->flags);
> -}
> -
> -#endif /* _DMA_ATTR_H */
> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> index 8443bbb5c071..81c5c8d167ad 100644
> --- a/include/linux/dma-iommu.h
> +++ b/include/linux/dma-iommu.h
> @@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
>   * the arch code to take care of attributes and cache maintenance
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t));
>  void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>  		dma_addr_t *handle);
> @@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>   * directly as DMA mapping callbacks for simplicity
>   */
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  int iommu_dma_supported(struct device *dev, u64 mask);
>  int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>  
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 71c1b215ef66..19e581d5f8b4 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -5,13 +5,25 @@
>  #include <linux/string.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  #include <linux/dma-direction.h>
>  #include <linux/scatterlist.h>
>  #include <linux/kmemcheck.h>
>  #include <linux/bug.h>
>  
> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> +
>  /*
>   * 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.  A CPU cannot
> @@ -21,34 +33,35 @@
>  struct dma_map_ops {
>  	void* (*alloc)(struct device *dev, size_t size,
>  				dma_addr_t *dma_handle, gfp_t gfp,
> -				struct dma_attrs *attrs);
> +				unsigned long attrs);
>  	void (*free)(struct device *dev, size_t size,
>  			      void *vaddr, dma_addr_t dma_handle,
> -			      struct dma_attrs *attrs);
> +			      unsigned long attrs);
>  	int (*mmap)(struct device *, struct vm_area_struct *,
> -			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
> +			  void *, dma_addr_t, size_t,
> +			  unsigned long attrs);
>  
>  	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
> -			   dma_addr_t, size_t, struct dma_attrs *attrs);
> +			   dma_addr_t, size_t, unsigned long attrs);
>  
>  	dma_addr_t (*map_page)(struct device *dev, struct page *page,
>  			       unsigned long offset, size_t size,
>  			       enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
>  			   size_t size, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  	/*
>  	 * map_sg returns 0 on error and a value > 0 on success.
>  	 * It should never return a value < 0.
>  	 */
>  	int (*map_sg)(struct device *dev, struct scatterlist *sg,
>  		      int nents, enum dma_data_direction dir,
> -		      struct dma_attrs *attrs);
> +		      unsigned long attrs);
>  	void (*unmap_sg)(struct device *dev,
>  			 struct scatterlist *sg, int nents,
>  			 enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  	void (*sync_single_for_cpu)(struct device *dev,
>  				    dma_addr_t dma_handle, size_t size,
>  				    enum dma_data_direction dir);
> @@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
>  	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
>  }
>  
> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}
> +
>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>  /*
>   * These three functions are only for dma allocator.
> @@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
>  static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  					      size_t size,
>  					      enum dma_data_direction dir,
> -					      struct dma_attrs *attrs)
> +					      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	dma_addr_t addr;
> @@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>  					  size_t size,
>  					  enum dma_data_direction dir,
> -					  struct dma_attrs *attrs)
> +					  unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>   */
>  static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				   int nents, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	int i, ents;
> @@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  
>  static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				      int nents, enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
>  
>  	kmemcheck_mark_initialized(page_address(page) + offset, size);
>  	BUG_ON(!valid_dma_direction(dir));
> -	addr = ops->map_page(dev, page, offset, size, dir, NULL);
> +	addr = ops->map_page(dev, page, offset, size, dir, 0);
>  	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
>  
>  	return addr;
> @@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
>  
>  	BUG_ON(!valid_dma_direction(dir));
>  	if (ops->unmap_page)
> -		ops->unmap_page(dev, addr, size, dir, NULL);
> +		ops->unmap_page(dev, addr, size, dir, 0);
>  	debug_dma_unmap_page(dev, addr, size, dir, false);
>  }
>  
> @@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>  
>  }
>  
> -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
> -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
> -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
> -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
> +#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
> +#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
> +#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
> +#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
>  
>  extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
>  			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
> @@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
>   */
>  static inline int
>  dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
> -	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
>  	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
> +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
>  
>  int
>  dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> @@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
>  
>  static inline int
>  dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
> -		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +		      dma_addr_t dma_addr, size_t size,
> +		      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
> +#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
>  
>  #ifndef arch_dma_alloc_attrs
>  #define arch_dma_alloc_attrs(dev, flag)	(true)
> @@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  
>  static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  				       dma_addr_t *dma_handle, gfp_t flag,
> -				       struct dma_attrs *attrs)
> +				       unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	void *cpu_addr;
> @@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  
>  static inline void dma_free_attrs(struct device *dev, size_t size,
>  				     void *cpu_addr, dma_addr_t dma_handle,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
>  static inline void *dma_alloc_coherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t flag)
>  {
> -	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
> +	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
>  }
>  
>  static inline void dma_free_coherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
>  }
>  
>  static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_handle, gfp,
> +			       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline void dma_free_noncoherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
> +	dma_free_attrs(dev, size, cpu_addr, dma_handle,
> +		       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> @@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
>  static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  				 dma_addr_t *dma_addr, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_addr, gfp,
> +			       DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_alloc_writecombine
>  #define dma_alloc_writecombine dma_alloc_wc
> @@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  static inline void dma_free_wc(struct device *dev, size_t size,
>  			       void *cpu_addr, dma_addr_t dma_addr)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_free_writecombine
>  #define dma_free_writecombine dma_free_wc
> @@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
>  			      void *cpu_addr, dma_addr_t dma_addr,
>  			      size_t size)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
> +	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_mmap_writecombine
>  #define dma_mmap_writecombine dma_mmap_wc
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 017fced60242..5f81f8a187f2 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -6,7 +6,6 @@
>  #include <linux/types.h>
>  
>  struct device;
> -struct dma_attrs;
>  struct page;
>  struct scatterlist;
>  
> @@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
>  extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  
>  extern int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
> @@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
>  
>  extern int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs);
> +		     enum dma_data_direction dir,
> +		     unsigned long attrs);
>  
>  extern void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  		       int nelems, enum dma_data_direction dir,
> -		       struct dma_attrs *attrs);
> +		       unsigned long attrs);
>  
>  extern void
>  swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
> index 8b2eb93ae8ba..7c35e279d1e3 100644
> --- a/include/xen/swiotlb-xen.h
> +++ b/include/xen/swiotlb-xen.h
> @@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
>  extern void
>  *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t flags,
> -			    struct dma_attrs *attrs);
> +			    unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
>  			  void *vaddr, dma_addr_t dma_handle,
> -			  struct dma_attrs *attrs);
> +			  unsigned long attrs);
>  
>  extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				       unsigned long offset, size_t size,
>  				       enum dma_data_direction dir,
> -				       struct dma_attrs *attrs);
> +				       unsigned long attrs);
>  
>  extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  				   size_t size, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/lib/dma-noop.c b/lib/dma-noop.c
> index 72145646857e..3d766e78fbe2 100644
> --- a/lib/dma-noop.c
> +++ b/lib/dma-noop.c
> @@ -10,7 +10,7 @@
>  
>  static void *dma_noop_alloc(struct device *dev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t gfp,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	void *ret;
>  
> @@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
>  
>  static void dma_noop_free(struct device *dev, size_t size,
>  			  void *cpu_addr, dma_addr_t dma_addr,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	free_pages((unsigned long)cpu_addr, get_order(size));
>  }
> @@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
>  static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
>  				      unsigned long offset, size_t size,
>  				      enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	return page_to_phys(page) + offset;
>  }
>  
>  static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
> -			     enum dma_data_direction dir, struct dma_attrs *attrs)
> +			     enum dma_data_direction dir,
> +			     unsigned long attrs)
>  {
>  	int i;
>  	struct scatterlist *sg;
> diff --git a/lib/swiotlb.c b/lib/swiotlb.c
> index 76f29ecba8f4..22e13a0e19d7 100644
> --- a/lib/swiotlb.c
> +++ b/lib/swiotlb.c
> @@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
>  dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  			    unsigned long offset, size_t size,
>  			    enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = phys_to_dma(dev, phys);
> @@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			size_t size, enum dma_data_direction dir,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	unmap_single(hwdev, dev_addr, size, dir);
>  }
> @@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
>   */
>  int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs)
> +		     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -914,7 +914,7 @@ int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  	       enum dma_data_direction dir)
>  {
> -	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_map_sg);
>  
> @@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
>   */
>  void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
> -		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		       int nelems, enum dma_data_direction dir,
> +		       unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -941,7 +942,7 @@ void
>  swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  		 enum dma_data_direction dir)
>  {
> -	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_unmap_sg);
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-30 11:54   ` Krzysztof Kozlowski
                     ` (4 preceding siblings ...)
  (?)
@ 2016-05-31 18:15   ` Konrad Rzeszutek Wilk
  -1 siblings, 0 replies; 24+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-05-31 18:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, hch, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
> The dma-mapping core and the implementations do not change the
> DMA attributes passed by pointer.  Thus the pointer can point to const
> data.  However the attributes do not have to be a bitfield. Instead
> unsigned long will do fine:
> 
> 1. This is just simpler.  Both in terms of reading the code and setting
>    attributes.  Instead of initializing local attributes on the stack and
>    passing pointer to it to dma_set_attr(), just set the bits.
> 
> 2. It brings safeness and checking for const correctness because the
>    attributes are passed by value.


.. why not go the next step a do an enum? Perhaps that should be mentioned
as part of the description?

Thanks.
> 
> Please have in mind that this is RFC, not finished yet.  Only ARM and
> ARM64 are fixed (and not everywhere).
> However other API users also have to be converted which is quite
> intrusive.  I would rather avoid it until the overall approach is
> accepted.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
>  Documentation/DMA-API.txt                 |   2 +-
>  Documentation/DMA-attributes.txt          |   2 +-
>  arch/arm/include/asm/dma-mapping.h        |  13 ++--
>  arch/arm/include/asm/xen/page-coherent.h  |  16 ++---
>  arch/arm/mm/dma-mapping.c                 |  82 +++++++++++------------
>  arch/arm/xen/mm.c                         |   4 +-
>  arch/arm64/mm/dma-mapping.c               |  57 ++++++++--------
>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_gem.c   |  20 +++---
>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |   2 +-
>  drivers/iommu/dma-iommu.c                 |   6 +-
>  drivers/xen/swiotlb-xen.c                 |  14 ++--
>  include/linux/dma-attrs.h                 |  71 --------------------
>  include/linux/dma-iommu.h                 |   6 +-
>  include/linux/dma-mapping.h               | 105 +++++++++++++++++-------------
>  include/linux/swiotlb.h                   |  10 +--
>  include/xen/swiotlb-xen.h                 |  12 ++--
>  lib/dma-noop.c                            |   9 +--
>  lib/swiotlb.c                             |  13 ++--
>  20 files changed, 195 insertions(+), 252 deletions(-)
>  delete mode 100644 include/linux/dma-attrs.h
> 
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index 45ef3f279c3b..0b55cb7c5aaa 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -391,7 +391,7 @@ without the _attrs suffixes, except that they pass an optional
>  struct dma_attrs*.
>  
>  struct dma_attrs encapsulates a set of "DMA attributes". For the
> -definition of struct dma_attrs see linux/dma-attrs.h.
> +definition of struct dma_attrs see linux/dma-mapping.h.
>  
>  The interpretation of DMA attributes is architecture-specific, and
>  each attribute should be documented in Documentation/DMA-attributes.txt.
> diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
> index e8cf9cf873b3..2d455a5cf671 100644
> --- a/Documentation/DMA-attributes.txt
> +++ b/Documentation/DMA-attributes.txt
> @@ -2,7 +2,7 @@
>  			==============
>  
>  This document describes the semantics of the DMA attributes that are
> -defined in linux/dma-attrs.h.
> +defined in linux/dma-mapping.h.
>  
>  DMA_ATTR_WRITE_BARRIER
>  ----------------------
> diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> index a83570f10124..d009f7911ffc 100644
> --- a/arch/arm/include/asm/dma-mapping.h
> +++ b/arch/arm/include/asm/dma-mapping.h
> @@ -5,7 +5,6 @@
>  
>  #include <linux/mm_types.h>
>  #include <linux/scatterlist.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  
>  #include <asm/memory.h>
> @@ -174,7 +173,7 @@ static inline void dma_mark_clean(void *addr, size_t size) { }
>   * to be the device-viewed address.
>   */
>  extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -			   gfp_t gfp, struct dma_attrs *attrs);
> +			   gfp_t gfp, unsigned long attrs);
>  
>  /**
>   * arm_dma_free - free memory allocated by arm_dma_alloc
> @@ -191,7 +190,7 @@ extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * during and after this call executing are illegal.
>   */
>  extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			 dma_addr_t handle, struct dma_attrs *attrs);
> +			 dma_addr_t handle, unsigned long attrs);
>  
>  /**
>   * arm_dma_mmap - map a coherent DMA allocation into user space
> @@ -208,7 +207,7 @@ extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>   */
>  extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs);
> +			unsigned long attrs);
>  
>  /*
>   * This can be called during early boot to increase the size of the atomic
> @@ -262,16 +261,16 @@ extern void dmabounce_unregister_dev(struct device *);
>   * The scatter list versions of the above methods.
>   */
>  extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
> -		enum dma_data_direction, struct dma_attrs *attrs);
> +		enum dma_data_direction, unsigned long attrs);
>  extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
>  		enum dma_data_direction);
>  extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  
>  #endif /* __KERNEL__ */
>  #endif
> diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
> index 9408a994cc91..95ce6ac3a971 100644
> --- a/arch/arm/include/asm/xen/page-coherent.h
> +++ b/arch/arm/include/asm/xen/page-coherent.h
> @@ -2,15 +2,14 @@
>  #define _ASM_ARM_XEN_PAGE_COHERENT_H
>  
>  #include <asm/page.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-mapping.h>
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs);
> +	     enum dma_data_direction dir, unsigned long attrs);
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs);
> +		unsigned long attrs);
>  void __xen_dma_sync_single_for_cpu(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
> @@ -18,22 +17,20 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
>  		dma_addr_t handle, size_t size, enum dma_data_direction dir);
>  
>  static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t flags,
> -		struct dma_attrs *attrs)
> +		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
>  {
>  	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
>  }
>  
>  static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> -		void *cpu_addr, dma_addr_t dma_handle,
> -		struct dma_attrs *attrs)
> +		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
>  {
>  	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
>  }
>  
>  static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long page_pfn = page_to_xen_pfn(page);
>  	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> @@ -58,8 +55,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>  }
>  
>  static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	unsigned long pfn = PFN_DOWN(handle);
>  	/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ff7ed5697d3e..fe31fbfd926d 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -124,7 +124,7 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
>   */
>  static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -133,7 +133,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
>  
>  static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
>  }
> @@ -153,8 +153,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
>   * whatever the device wrote there.
>   */
>  static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
> @@ -194,12 +193,12 @@ struct dma_map_ops arm_dma_ops = {
>  EXPORT_SYMBOL(arm_dma_ops);
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs);
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs);
> +				  dma_addr_t handle, unsigned long attrs);
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs);
> +		 unsigned long attrs);
>  
>  struct dma_map_ops arm_coherent_dma_ops = {
>  	.alloc			= arm_coherent_dma_alloc,
> @@ -621,7 +620,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
>  	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
>  }
>  
> -static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
> +static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
>  {
>  	prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
>  			    pgprot_writecombine(prot) :
> @@ -732,7 +731,7 @@ static struct arm_dma_allocator remap_allocator = {
>  
>  static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  			 gfp_t gfp, pgprot_t prot, bool is_coherent,
> -			 struct dma_attrs *attrs, const void *caller)
> +			 unsigned long attrs, const void *caller)
>  {
>  	u64 mask = get_coherent_dma_mask(dev);
>  	struct page *page = NULL;
> @@ -814,7 +813,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   * virtual and bus address for that space.
>   */
>  void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> -		    gfp_t gfp, struct dma_attrs *attrs)
> +		    gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  
> @@ -823,7 +822,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>  }
>  
>  static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> -	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
>  			   attrs, __builtin_return_address(0));
> @@ -831,7 +830,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
>  
>  static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  #ifdef CONFIG_MMU
> @@ -859,14 +858,14 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   */
>  static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
>  }
>  
>  int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>  		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  #ifdef CONFIG_MMU
>  	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> @@ -878,7 +877,7 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
>   * Free a buffer as defined by the above mapping.
>   */
>  static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -			   dma_addr_t handle, struct dma_attrs *attrs,
> +			   dma_addr_t handle, unsigned long attrs,
>  			   bool is_coherent)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
> @@ -900,20 +899,20 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>  }
>  
>  void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -		  dma_addr_t handle, struct dma_attrs *attrs)
> +		  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
>  }
>  
>  static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> -				  dma_addr_t handle, struct dma_attrs *attrs)
> +				  dma_addr_t handle, unsigned long attrs)
>  {
>  	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
>  }
>  
>  int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
>  		 void *cpu_addr, dma_addr_t handle, size_t size,
> -		 struct dma_attrs *attrs)
> +		 unsigned long attrs)
>  {
>  	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
>  	int ret;
> @@ -1046,7 +1045,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
>   * here.
>   */
>  int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1080,7 +1079,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
> @@ -1253,7 +1252,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>  static const int iommu_order_array[] = { 9, 8, 4, 0 };
>  
>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> -					  gfp_t gfp, struct dma_attrs *attrs)
> +					  gfp_t gfp, unsigned long attrs)
>  {
>  	struct page **pages;
>  	int count = size >> PAGE_SHIFT;
> @@ -1342,7 +1341,7 @@ error:
>  }
>  
>  static int __iommu_free_buffer(struct device *dev, struct page **pages,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	int count = size >> PAGE_SHIFT;
>  	int i;
> @@ -1439,7 +1438,7 @@ static struct page **__atomic_get_pages(void *addr)
>  	return (struct page **)page;
>  }
>  
> -static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
> +static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  
> @@ -1484,7 +1483,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>  }
>  
>  static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +	    dma_addr_t *handle, gfp_t gfp, unsigned long attrs)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1532,7 +1531,7 @@ err_buffer:
>  
>  static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		    struct dma_attrs *attrs)
> +		    unsigned long attrs)
>  {
>  	unsigned long uaddr = vma->vm_start;
>  	unsigned long usize = vma->vm_end - vma->vm_start;
> @@ -1568,7 +1567,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   * Must not be called with IRQs disabled.
>   */
>  void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			  dma_addr_t handle, struct dma_attrs *attrs)
> +			  dma_addr_t handle, unsigned long attrs)
>  {
>  	struct page **pages;
>  	size = PAGE_ALIGN(size);
> @@ -1595,7 +1594,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  
>  static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t dma_addr,
> -				 size_t size, struct dma_attrs *attrs)
> +				 size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
> @@ -1633,7 +1632,7 @@ static int __dma_direction_to_prot(enum dma_data_direction dir)
>   */
>  static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
>  			  size_t size, dma_addr_t *handle,
> -			  enum dma_data_direction dir, struct dma_attrs *attrs,
> +			  enum dma_data_direction dir, unsigned long attrs,
>  			  bool is_coherent)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> @@ -1676,7 +1675,7 @@ fail:
>  }
>  
>  static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs,
> +		     enum dma_data_direction dir, unsigned long attrs,
>  		     bool is_coherent)
>  {
>  	struct scatterlist *s = sg, *dma = sg, *start = sg;
> @@ -1734,7 +1733,7 @@ bad_mapping:
>   * obtained via sg_dma_{address,length}.
>   */
>  int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1752,14 +1751,14 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
>   * sg_dma_{address,length}.
>   */
>  int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
>  }
>  
>  static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
> -		bool is_coherent)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs, bool is_coherent)
>  {
>  	struct scatterlist *s;
>  	int i;
> @@ -1786,7 +1785,8 @@ static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
> -		int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		int nents, enum dma_data_direction dir,
> +		unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
>  }
> @@ -1802,7 +1802,8 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
>   * rules concerning calls here are the same as for dma_unmap_single().
>   */
>  void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -			enum dma_data_direction dir, struct dma_attrs *attrs)
> +			enum dma_data_direction dir,
> +			unsigned long attrs)
>  {
>  	__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
>  }
> @@ -1855,7 +1856,7 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>   */
>  static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t dma_addr;
> @@ -1889,7 +1890,7 @@ fail:
>   */
>  static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>  	     unsigned long offset, size_t size, enum dma_data_direction dir,
> -	     struct dma_attrs *attrs)
> +	     unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_cpu_to_dev(page, offset, size, dir);
> @@ -1907,8 +1908,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
>   * Coherent IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1932,8 +1932,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>   * IOMMU aware version of arm_dma_unmap_page()
>   */
>  static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
> -		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		size_t size, enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
>  	dma_addr_t iova = handle & PAGE_MASK;
> @@ -1944,6 +1943,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
>  	if (!iova)
>  		return;
>  
> +	// FIXME: replace get with simple check
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__dma_page_dev_to_cpu(page, offset, size, dir);
>  
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index c5f9a9e3d1f3..fc67ed236a10 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -98,7 +98,7 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
>  
>  void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  	     dma_addr_t dev_addr, unsigned long offset, size_t size,
> -	     enum dma_data_direction dir, struct dma_attrs *attrs)
> +	     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	if (is_device_dma_coherent(hwdev))
>  		return;
> @@ -110,7 +110,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
>  
>  void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
>  		size_t size, enum dma_data_direction dir,
> -		struct dma_attrs *attrs)
> +		unsigned long attrs)
>  
>  {
>  	if (is_device_dma_coherent(hwdev))
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index c566ec83719f..a7686028dfeb 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -29,7 +29,7 @@
>  
>  #include <asm/cacheflush.h>
>  
> -static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
> +static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
>  				 bool coherent)
>  {
>  	if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
> @@ -88,7 +88,7 @@ static int __free_from_pool(void *start, size_t size)
>  
>  static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  				  dma_addr_t *dma_handle, gfp_t flags,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	if (dev == NULL) {
>  		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
> @@ -118,7 +118,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  
>  static void __dma_free_coherent(struct device *dev, size_t size,
>  				void *vaddr, dma_addr_t dma_handle,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool freed;
>  	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
> @@ -137,7 +137,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
>  
>  static void *__dma_alloc(struct device *dev, size_t size,
>  			 dma_addr_t *dma_handle, gfp_t flags,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct page *page;
>  	void *ptr, *coherent_ptr;
> @@ -185,7 +185,7 @@ no_mem:
>  
>  static void __dma_free(struct device *dev, size_t size,
>  		       void *vaddr, dma_addr_t dma_handle,
> -		       struct dma_attrs *attrs)
> +		       unsigned long attrs)
>  {
>  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
>  
> @@ -202,7 +202,7 @@ static void __dma_free(struct device *dev, size_t size,
>  static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  				     unsigned long offset, size_t size,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	dma_addr_t dev_addr;
>  
> @@ -216,7 +216,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
>  
>  static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  				 size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	if (!is_device_dma_coherent(dev))
>  		__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
> @@ -225,7 +225,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  
>  static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				  int nelems, enum dma_data_direction dir,
> -				  struct dma_attrs *attrs)
> +				  unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i, ret;
> @@ -242,7 +242,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __swiotlb_unmap_sg_attrs(struct device *dev,
>  				     struct scatterlist *sgl, int nelems,
>  				     enum dma_data_direction dir,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -303,7 +303,7 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
>  static int __swiotlb_mmap(struct device *dev,
>  			  struct vm_area_struct *vma,
>  			  void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	int ret = -ENXIO;
>  	unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
> @@ -330,7 +330,7 @@ static int __swiotlb_mmap(struct device *dev,
>  
>  static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
>  				 void *cpu_addr, dma_addr_t handle, size_t size,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
>  
> @@ -425,21 +425,21 @@ out:
>  
>  static void *__dummy_alloc(struct device *dev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	return NULL;
>  }
>  
>  static void __dummy_free(struct device *dev, size_t size,
>  			 void *vaddr, dma_addr_t dma_handle,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_mmap(struct device *dev,
>  			struct vm_area_struct *vma,
>  			void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	return -ENXIO;
>  }
> @@ -447,20 +447,20 @@ static int __dummy_mmap(struct device *dev,
>  static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	return DMA_ERROR_CODE;
>  }
>  
>  static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  }
>  
>  static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  			  int nelems, enum dma_data_direction dir,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	return 0;
>  }
> @@ -468,7 +468,7 @@ static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
>  static void __dummy_unmap_sg(struct device *dev,
>  			     struct scatterlist *sgl, int nelems,
>  			     enum dma_data_direction dir,
> -			     struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  }
>  
> @@ -540,7 +540,7 @@ static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
>  
>  static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  				 dma_addr_t *handle, gfp_t gfp,
> -				 struct dma_attrs *attrs)
> +				 unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
> @@ -600,7 +600,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>  }
>  
>  static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			       dma_addr_t handle, struct dma_attrs *attrs)
> +			       dma_addr_t handle,
> +			       unsigned long attrs)
>  {
>  	size_t iosize = size;
>  
> @@ -616,7 +617,7 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  	 * Hence how dodgy the below logic looks...
>  	 */
>  	if (__in_atomic_pool(cpu_addr, size)) {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_from_pool(cpu_addr, size);
>  	} else if (is_vmalloc_addr(cpu_addr)){
>  		struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -626,14 +627,14 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>  		iommu_dma_free(dev, area->pages, iosize, &handle);
>  		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>  	} else {
> -		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
> +		iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>  		__free_pages(virt_to_page(cpu_addr), get_order(size));
>  	}
>  }
>  
>  static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -			      struct dma_attrs *attrs)
> +			      unsigned long attrs)
>  {
>  	struct vm_struct *area;
>  	int ret;
> @@ -653,7 +654,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>  
>  static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>  			       void *cpu_addr, dma_addr_t dma_addr,
> -			       size_t size, struct dma_attrs *attrs)
> +			       size_t size, unsigned long attrs)
>  {
>  	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>  	struct vm_struct *area = find_vm_area(cpu_addr);
> @@ -694,7 +695,7 @@ static void __iommu_sync_single_for_device(struct device *dev,
>  static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  	int prot = dma_direction_to_prot(dir, coherent);
> @@ -709,7 +710,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
>  
>  static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs)
> +			       unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
> @@ -747,7 +748,7 @@ static void __iommu_sync_sg_for_device(struct device *dev,
>  
>  static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  				int nelems, enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	bool coherent = is_device_dma_coherent(dev);
>  
> @@ -761,7 +762,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
>  static void __iommu_unmap_sg_attrs(struct device *dev,
>  				   struct scatterlist *sgl, int nelems,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
>  		__iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> index 67dcd6831291..dd091175fc2d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> @@ -52,7 +52,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 493552368295..f65e6b7ef93b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -17,7 +17,6 @@
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include <linux/dma-mapping.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/of.h>
>  
>  #include <drm/drmP.h>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index cdf9f1af4347..f2ae72ba7d5a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -24,7 +24,7 @@
>  static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  {
>  	struct drm_device *dev = exynos_gem->base.dev;
> -	enum dma_attr attr;
> +	unsigned long attr;
>  	unsigned int nr_pages;
>  	struct sg_table sgt;
>  	int ret = -ENOMEM;
> @@ -34,7 +34,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  		return 0;
>  	}
>  
> -	init_dma_attrs(&exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs = 0;
>  
>  	/*
>  	 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
> @@ -42,7 +42,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	 * as possible.
>  	 */
>  	if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
> -		dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
> +		exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
>  
>  	/*
>  	 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
> @@ -54,8 +54,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  	else
>  		attr = DMA_ATTR_NON_CONSISTENT;
>  
> -	dma_set_attr(attr, &exynos_gem->dma_attrs);
> -	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
> +	exynos_gem->dma_attrs |= attr;
> +	exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
>  
>  	nr_pages = exynos_gem->size >> PAGE_SHIFT;
>  
> @@ -67,7 +67,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
>  					     &exynos_gem->dma_addr, GFP_KERNEL,
> -					     &exynos_gem->dma_attrs);
> +					     exynos_gem->dma_attrs);
>  	if (!exynos_gem->cookie) {
>  		DRM_ERROR("failed to allocate buffer.\n");
>  		goto err_free;
> @@ -75,7 +75,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
>  				    exynos_gem->dma_addr, exynos_gem->size,
> -				    &exynos_gem->dma_attrs);
> +				    exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to get sgtable.\n");
>  		goto err_dma_free;
> @@ -99,7 +99,7 @@ err_sgt_free:
>  	sg_free_table(&sgt);
>  err_dma_free:
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
> -		       exynos_gem->dma_addr, &exynos_gem->dma_attrs);
> +		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
>  err_free:
>  	drm_free_large(exynos_gem->pages);
>  
> @@ -120,7 +120,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
>  
>  	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
>  			(dma_addr_t)exynos_gem->dma_addr,
> -			&exynos_gem->dma_attrs);
> +			exynos_gem->dma_attrs);
>  
>  	drm_free_large(exynos_gem->pages);
>  }
> @@ -346,7 +346,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
>  
>  	ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
>  			     exynos_gem->dma_addr, exynos_gem->size,
> -			     &exynos_gem->dma_attrs);
> +			     exynos_gem->dma_attrs);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to mmap.\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> index 78100742281d..df7c543d6558 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
> @@ -50,7 +50,7 @@ struct exynos_drm_gem {
>  	void			*cookie;
>  	void __iomem		*kvaddr;
>  	dma_addr_t		dma_addr;
> -	struct dma_attrs	dma_attrs;
> +	unsigned long		dma_attrs;
>  	struct page		**pages;
>  	struct sg_table		*sgt;
>  };
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index ea5a9ebf0f78..6c1bda504fb1 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -286,7 +286,7 @@ void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>   *	   or NULL on failure.
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t))
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> @@ -400,7 +400,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
>  }
>  
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	__iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
>  }
> @@ -560,7 +560,7 @@ out_restore_sg:
>  }
>  
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs)
> +		enum dma_data_direction dir, unsigned long attrs)
>  {
>  	/*
>  	 * The scatterlist segments are mapped into a single
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index 7399782c0998..87e6035c9e81 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -294,7 +294,7 @@ error:
>  void *
>  xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			   dma_addr_t *dma_handle, gfp_t flags,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	void *ret;
>  	int order = get_order(size);
> @@ -346,7 +346,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
>  
>  void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
> -			  dma_addr_t dev_addr, struct dma_attrs *attrs)
> +			  dma_addr_t dev_addr, unsigned long attrs)
>  {
>  	int order = get_order(size);
>  	phys_addr_t phys;
> @@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
>  dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				unsigned long offset, size_t size,
>  				enum dma_data_direction dir,
> -				struct dma_attrs *attrs)
> +				unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = xen_phys_to_bus(phys);
> @@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
>   */
>  static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  			     size_t size, enum dma_data_direction dir,
> -				 struct dma_attrs *attrs)
> +			     unsigned long attrs)
>  {
>  	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
>  
> @@ -462,7 +462,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			    size_t size, enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
>  }
> @@ -538,7 +538,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
>  int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs)
> +			 unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -599,7 +599,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
>  void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs)
> +			   unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
> deleted file mode 100644
> index 5246239a4953..000000000000
> --- a/include/linux/dma-attrs.h
> +++ /dev/null
> @@ -1,71 +0,0 @@
> -#ifndef _DMA_ATTR_H
> -#define _DMA_ATTR_H
> -
> -#include <linux/bitmap.h>
> -#include <linux/bitops.h>
> -#include <linux/bug.h>
> -
> -/**
> - * an enum dma_attr represents an attribute associated with a DMA
> - * mapping. The semantics of each attribute should be defined in
> - * Documentation/DMA-attributes.txt.
> - */
> -enum dma_attr {
> -	DMA_ATTR_WRITE_BARRIER,
> -	DMA_ATTR_WEAK_ORDERING,
> -	DMA_ATTR_WRITE_COMBINE,
> -	DMA_ATTR_NON_CONSISTENT,
> -	DMA_ATTR_NO_KERNEL_MAPPING,
> -	DMA_ATTR_SKIP_CPU_SYNC,
> -	DMA_ATTR_FORCE_CONTIGUOUS,
> -	DMA_ATTR_ALLOC_SINGLE_PAGES,
> -	DMA_ATTR_MAX,
> -};
> -
> -#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
> -
> -/**
> - * struct dma_attrs - an opaque container for DMA attributes
> - * @flags - bitmask representing a collection of enum dma_attr
> - */
> -struct dma_attrs {
> -	unsigned long flags[__DMA_ATTRS_LONGS];
> -};
> -
> -#define DEFINE_DMA_ATTRS(x) 					\
> -	struct dma_attrs x = {					\
> -		.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },	\
> -	}
> -
> -static inline void init_dma_attrs(struct dma_attrs *attrs)
> -{
> -	bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
> -}
> -
> -/**
> - * dma_set_attr - set a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	__set_bit(attr, attrs->flags);
> -}
> -
> -/**
> - * dma_get_attr - check for a specific attribute
> - * @attr: attribute to set
> - * @attrs: struct dma_attrs (may be NULL)
> - */
> -static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
> -{
> -	if (attrs == NULL)
> -		return 0;
> -	BUG_ON(attr >= DMA_ATTR_MAX);
> -	return test_bit(attr, attrs->flags);
> -}
> -
> -#endif /* _DMA_ATTR_H */
> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> index 8443bbb5c071..81c5c8d167ad 100644
> --- a/include/linux/dma-iommu.h
> +++ b/include/linux/dma-iommu.h
> @@ -39,7 +39,7 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);
>   * the arch code to take care of attributes and cache maintenance
>   */
>  struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
> -		struct dma_attrs *attrs, int prot, dma_addr_t *handle,
> +		unsigned long attrs, int prot, dma_addr_t *handle,
>  		void (*flush_page)(struct device *, const void *, phys_addr_t));
>  void iommu_dma_free(struct device *dev, struct page **pages, size_t size,
>  		dma_addr_t *handle);
> @@ -56,9 +56,9 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>   * directly as DMA mapping callbacks for simplicity
>   */
>  void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> -		enum dma_data_direction dir, struct dma_attrs *attrs);
> +		enum dma_data_direction dir, unsigned long attrs);
>  int iommu_dma_supported(struct device *dev, u64 mask);
>  int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>  
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 71c1b215ef66..19e581d5f8b4 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -5,13 +5,25 @@
>  #include <linux/string.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> -#include <linux/dma-attrs.h>
>  #include <linux/dma-debug.h>
>  #include <linux/dma-direction.h>
>  #include <linux/scatterlist.h>
>  #include <linux/kmemcheck.h>
>  #include <linux/bug.h>
>  
> +/**
> + * List of possible attributes associated with a DMA mapping. The semantics
> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
> + */
> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> +
>  /*
>   * 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.  A CPU cannot
> @@ -21,34 +33,35 @@
>  struct dma_map_ops {
>  	void* (*alloc)(struct device *dev, size_t size,
>  				dma_addr_t *dma_handle, gfp_t gfp,
> -				struct dma_attrs *attrs);
> +				unsigned long attrs);
>  	void (*free)(struct device *dev, size_t size,
>  			      void *vaddr, dma_addr_t dma_handle,
> -			      struct dma_attrs *attrs);
> +			      unsigned long attrs);
>  	int (*mmap)(struct device *, struct vm_area_struct *,
> -			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
> +			  void *, dma_addr_t, size_t,
> +			  unsigned long attrs);
>  
>  	int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *,
> -			   dma_addr_t, size_t, struct dma_attrs *attrs);
> +			   dma_addr_t, size_t, unsigned long attrs);
>  
>  	dma_addr_t (*map_page)(struct device *dev, struct page *page,
>  			       unsigned long offset, size_t size,
>  			       enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  	void (*unmap_page)(struct device *dev, dma_addr_t dma_handle,
>  			   size_t size, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  	/*
>  	 * map_sg returns 0 on error and a value > 0 on success.
>  	 * It should never return a value < 0.
>  	 */
>  	int (*map_sg)(struct device *dev, struct scatterlist *sg,
>  		      int nents, enum dma_data_direction dir,
> -		      struct dma_attrs *attrs);
> +		      unsigned long attrs);
>  	void (*unmap_sg)(struct device *dev,
>  			 struct scatterlist *sg, int nents,
>  			 enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  	void (*sync_single_for_cpu)(struct device *dev,
>  				    dma_addr_t dma_handle, size_t size,
>  				    enum dma_data_direction dir);
> @@ -88,6 +101,16 @@ static inline int is_device_dma_capable(struct device *dev)
>  	return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
>  }
>  
> +/**
> + * dma_get_attr - check for a specific attribute
> + * @attr: attribute to look for
> + * @attrs: attributes to check within
> + */
> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
> +{
> +	return !!(attr & attrs);
> +}
> +
>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>  /*
>   * These three functions are only for dma allocator.
> @@ -123,7 +146,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
>  static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  					      size_t size,
>  					      enum dma_data_direction dir,
> -					      struct dma_attrs *attrs)
> +					      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	dma_addr_t addr;
> @@ -142,7 +165,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
>  static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>  					  size_t size,
>  					  enum dma_data_direction dir,
> -					  struct dma_attrs *attrs)
> +					  unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -158,7 +181,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
>   */
>  static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				   int nents, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs)
> +				   unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	int i, ents;
> @@ -176,7 +199,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>  
>  static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
>  				      int nents, enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -195,7 +218,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
>  
>  	kmemcheck_mark_initialized(page_address(page) + offset, size);
>  	BUG_ON(!valid_dma_direction(dir));
> -	addr = ops->map_page(dev, page, offset, size, dir, NULL);
> +	addr = ops->map_page(dev, page, offset, size, dir, 0);
>  	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
>  
>  	return addr;
> @@ -208,7 +231,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
>  
>  	BUG_ON(!valid_dma_direction(dir));
>  	if (ops->unmap_page)
> -		ops->unmap_page(dev, addr, size, dir, NULL);
> +		ops->unmap_page(dev, addr, size, dir, 0);
>  	debug_dma_unmap_page(dev, addr, size, dir, false);
>  }
>  
> @@ -289,10 +312,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>  
>  }
>  
> -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
> -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
> -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
> -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
> +#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
> +#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
> +#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
> +#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
>  
>  extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
>  			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
> @@ -321,7 +344,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
>   */
>  static inline int
>  dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
> -	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +	       dma_addr_t dma_addr, size_t size, unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -330,7 +353,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
>  	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
> +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
>  
>  int
>  dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> @@ -338,7 +361,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
>  
>  static inline int
>  dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
> -		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
> +		      dma_addr_t dma_addr, size_t size,
> +		      unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	BUG_ON(!ops);
> @@ -348,7 +372,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
>  }
>  
> -#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
> +#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
>  
>  #ifndef arch_dma_alloc_attrs
>  #define arch_dma_alloc_attrs(dev, flag)	(true)
> @@ -356,7 +380,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
>  
>  static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  				       dma_addr_t *dma_handle, gfp_t flag,
> -				       struct dma_attrs *attrs)
> +				       unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  	void *cpu_addr;
> @@ -378,7 +402,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
>  
>  static inline void dma_free_attrs(struct device *dev, size_t size,
>  				     void *cpu_addr, dma_addr_t dma_handle,
> -				     struct dma_attrs *attrs)
> +				     unsigned long attrs)
>  {
>  	struct dma_map_ops *ops = get_dma_ops(dev);
>  
> @@ -398,31 +422,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
>  static inline void *dma_alloc_coherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t flag)
>  {
> -	return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
> +	return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
>  }
>  
>  static inline void dma_free_coherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0);
>  }
>  
>  static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
>  		dma_addr_t *dma_handle, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_handle, gfp,
> +			       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline void dma_free_noncoherent(struct device *dev, size_t size,
>  		void *cpu_addr, dma_addr_t dma_handle)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -
> -	dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
> -	dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
> +	dma_free_attrs(dev, size, cpu_addr, dma_handle,
> +		       DMA_ATTR_NON_CONSISTENT);
>  }
>  
>  static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> @@ -646,9 +666,8 @@ static inline void dmam_release_declared_memory(struct device *dev)
>  static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  				 dma_addr_t *dma_addr, gfp_t gfp)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs);
> +	return dma_alloc_attrs(dev, size, dma_addr, gfp,
> +			       DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_alloc_writecombine
>  #define dma_alloc_writecombine dma_alloc_wc
> @@ -657,9 +676,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size,
>  static inline void dma_free_wc(struct device *dev, size_t size,
>  			       void *cpu_addr, dma_addr_t dma_addr)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs);
> +	return dma_free_attrs(dev, size, cpu_addr, dma_addr,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_free_writecombine
>  #define dma_free_writecombine dma_free_wc
> @@ -670,9 +688,8 @@ static inline int dma_mmap_wc(struct device *dev,
>  			      void *cpu_addr, dma_addr_t dma_addr,
>  			      size_t size)
>  {
> -	DEFINE_DMA_ATTRS(attrs);
> -	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
> -	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
> +	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
> +			      DMA_ATTR_WRITE_COMBINE);
>  }
>  #ifndef dma_mmap_writecombine
>  #define dma_mmap_writecombine dma_mmap_wc
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 017fced60242..5f81f8a187f2 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -6,7 +6,6 @@
>  #include <linux/types.h>
>  
>  struct device;
> -struct dma_attrs;
>  struct page;
>  struct scatterlist;
>  
> @@ -68,10 +67,10 @@ swiotlb_free_coherent(struct device *hwdev, size_t size,
>  extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  				   unsigned long offset, size_t size,
>  				   enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			       size_t size, enum dma_data_direction dir,
> -			       struct dma_attrs *attrs);
> +			       unsigned long attrs);
>  
>  extern int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
> @@ -83,12 +82,13 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
>  
>  extern int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs);
> +		     enum dma_data_direction dir,
> +		     unsigned long attrs);
>  
>  extern void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  		       int nelems, enum dma_data_direction dir,
> -		       struct dma_attrs *attrs);
> +		       unsigned long attrs);
>  
>  extern void
>  swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
> index 8b2eb93ae8ba..7c35e279d1e3 100644
> --- a/include/xen/swiotlb-xen.h
> +++ b/include/xen/swiotlb-xen.h
> @@ -9,30 +9,30 @@ extern int xen_swiotlb_init(int verbose, bool early);
>  extern void
>  *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t flags,
> -			    struct dma_attrs *attrs);
> +			    unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
>  			  void *vaddr, dma_addr_t dma_handle,
> -			  struct dma_attrs *attrs);
> +			  unsigned long attrs);
>  
>  extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>  				       unsigned long offset, size_t size,
>  				       enum dma_data_direction dir,
> -				       struct dma_attrs *attrs);
> +				       unsigned long attrs);
>  
>  extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  				   size_t size, enum dma_data_direction dir,
> -				   struct dma_attrs *attrs);
> +				   unsigned long attrs);
>  extern int
>  xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			 int nelems, enum dma_data_direction dir,
> -			 struct dma_attrs *attrs);
> +			 unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
>  			   int nelems, enum dma_data_direction dir,
> -			   struct dma_attrs *attrs);
> +			   unsigned long attrs);
>  
>  extern void
>  xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
> diff --git a/lib/dma-noop.c b/lib/dma-noop.c
> index 72145646857e..3d766e78fbe2 100644
> --- a/lib/dma-noop.c
> +++ b/lib/dma-noop.c
> @@ -10,7 +10,7 @@
>  
>  static void *dma_noop_alloc(struct device *dev, size_t size,
>  			    dma_addr_t *dma_handle, gfp_t gfp,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	void *ret;
>  
> @@ -22,7 +22,7 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
>  
>  static void dma_noop_free(struct device *dev, size_t size,
>  			  void *cpu_addr, dma_addr_t dma_addr,
> -			  struct dma_attrs *attrs)
> +			  unsigned long attrs)
>  {
>  	free_pages((unsigned long)cpu_addr, get_order(size));
>  }
> @@ -30,13 +30,14 @@ static void dma_noop_free(struct device *dev, size_t size,
>  static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
>  				      unsigned long offset, size_t size,
>  				      enum dma_data_direction dir,
> -				      struct dma_attrs *attrs)
> +				      unsigned long attrs)
>  {
>  	return page_to_phys(page) + offset;
>  }
>  
>  static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
> -			     enum dma_data_direction dir, struct dma_attrs *attrs)
> +			     enum dma_data_direction dir,
> +			     unsigned long attrs)
>  {
>  	int i;
>  	struct scatterlist *sg;
> diff --git a/lib/swiotlb.c b/lib/swiotlb.c
> index 76f29ecba8f4..22e13a0e19d7 100644
> --- a/lib/swiotlb.c
> +++ b/lib/swiotlb.c
> @@ -738,7 +738,7 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
>  dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
>  			    unsigned long offset, size_t size,
>  			    enum dma_data_direction dir,
> -			    struct dma_attrs *attrs)
> +			    unsigned long attrs)
>  {
>  	phys_addr_t map, phys = page_to_phys(page) + offset;
>  	dma_addr_t dev_addr = phys_to_dma(dev, phys);
> @@ -807,7 +807,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
>  
>  void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
>  			size_t size, enum dma_data_direction dir,
> -			struct dma_attrs *attrs)
> +			unsigned long attrs)
>  {
>  	unmap_single(hwdev, dev_addr, size, dir);
>  }
> @@ -877,7 +877,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_device);
>   */
>  int
>  swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
> -		     enum dma_data_direction dir, struct dma_attrs *attrs)
> +		     enum dma_data_direction dir, unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -914,7 +914,7 @@ int
>  swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  	       enum dma_data_direction dir)
>  {
> -	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_map_sg);
>  
> @@ -924,7 +924,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
>   */
>  void
>  swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
> -		       int nelems, enum dma_data_direction dir, struct dma_attrs *attrs)
> +		       int nelems, enum dma_data_direction dir,
> +		       unsigned long attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -941,7 +942,7 @@ void
>  swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
>  		 enum dma_data_direction dir)
>  {
> -	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
> +	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
>  }
>  EXPORT_SYMBOL(swiotlb_unmap_sg);
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-31 17:04     ` Christoph Hellwig
@ 2016-06-01  5:36       ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  5:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu,
	sstabellini, Bartlomiej Zolnierkiewicz

On 05/31/2016 07:04 PM, Christoph Hellwig wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
>>
>> Please have in mind that this is RFC, not finished yet.  Only ARM and
>> ARM64 are fixed (and not everywhere).
>> However other API users also have to be converted which is quite
>> intrusive.  I would rather avoid it until the overall approach is
>> accepted.
> 
> This looks great!  Please continue doing the full conversion.
> 
>> +/**
>> + * List of possible attributes associated with a DMA mapping. The semantics
>> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
>> + */
>> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
>> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
>> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
>> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
>> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
>> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
>> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
>> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> 
> No really for this patch, but I would much prefer to document them next
> to the code in the long run.  Also I really think these BIT() macros
> are a distraction compared to the (1 << N) notation.

Not much difference to me but maybe plain number:
...	0x01u
...	0x02u
?

> 
>> +/**
>> + * dma_get_attr - check for a specific attribute
>> + * @attr: attribute to look for
>> + * @attrs: attributes to check within
>> + */
>> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
>> +{
>> +	return !!(attr & attrs);
>> +}
> 
> I'd just kill this helper, much easier to simply open code it in the
> caller.

Keeping it for now helps reducing the number of changes in the patch.
The patch will be quite big as it has to replace all the uses atomically.

I can get rid of the helper in consecutive patch.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-06-01  5:36       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  5:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/31/2016 07:04 PM, Christoph Hellwig wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
>>
>> Please have in mind that this is RFC, not finished yet.  Only ARM and
>> ARM64 are fixed (and not everywhere).
>> However other API users also have to be converted which is quite
>> intrusive.  I would rather avoid it until the overall approach is
>> accepted.
> 
> This looks great!  Please continue doing the full conversion.
> 
>> +/**
>> + * List of possible attributes associated with a DMA mapping. The semantics
>> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
>> + */
>> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
>> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
>> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
>> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
>> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
>> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
>> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
>> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> 
> No really for this patch, but I would much prefer to document them next
> to the code in the long run.  Also I really think these BIT() macros
> are a distraction compared to the (1 << N) notation.

Not much difference to me but maybe plain number:
...	0x01u
...	0x02u
?

> 
>> +/**
>> + * dma_get_attr - check for a specific attribute
>> + * @attr: attribute to look for
>> + * @attrs: attributes to check within
>> + */
>> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
>> +{
>> +	return !!(attr & attrs);
>> +}
> 
> I'd just kill this helper, much easier to simply open code it in the
> caller.

Keeping it for now helps reducing the number of changes in the patch.
The patch will be quite big as it has to replace all the uses atomically.

I can get rid of the helper in consecutive patch.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-31 17:04     ` Christoph Hellwig
  (?)
  (?)
@ 2016-06-01  5:36     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  5:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, iommu, linux-samsung-soc,
	sstabellini, Andy Lutomirski, xen-devel, Andrew Morton,
	Mel Gorman, linux-arm-kernel, Marek Szyprowski

On 05/31/2016 07:04 PM, Christoph Hellwig wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
>>
>> Please have in mind that this is RFC, not finished yet.  Only ARM and
>> ARM64 are fixed (and not everywhere).
>> However other API users also have to be converted which is quite
>> intrusive.  I would rather avoid it until the overall approach is
>> accepted.
> 
> This looks great!  Please continue doing the full conversion.
> 
>> +/**
>> + * List of possible attributes associated with a DMA mapping. The semantics
>> + * of each attribute should be defined in Documentation/DMA-attributes.txt.
>> + */
>> +#define DMA_ATTR_WRITE_BARRIER		BIT(1)
>> +#define DMA_ATTR_WEAK_ORDERING		BIT(2)
>> +#define DMA_ATTR_WRITE_COMBINE		BIT(3)
>> +#define DMA_ATTR_NON_CONSISTENT		BIT(4)
>> +#define DMA_ATTR_NO_KERNEL_MAPPING	BIT(5)
>> +#define DMA_ATTR_SKIP_CPU_SYNC		BIT(6)
>> +#define DMA_ATTR_FORCE_CONTIGUOUS	BIT(7)
>> +#define DMA_ATTR_ALLOC_SINGLE_PAGES	BIT(8)
> 
> No really for this patch, but I would much prefer to document them next
> to the code in the long run.  Also I really think these BIT() macros
> are a distraction compared to the (1 << N) notation.

Not much difference to me but maybe plain number:
...	0x01u
...	0x02u
?

> 
>> +/**
>> + * dma_get_attr - check for a specific attribute
>> + * @attr: attribute to look for
>> + * @attrs: attributes to check within
>> + */
>> +static inline bool dma_get_attr(unsigned long attr, unsigned long attrs)
>> +{
>> +	return !!(attr & attrs);
>> +}
> 
> I'd just kill this helper, much easier to simply open code it in the
> caller.

Keeping it for now helps reducing the number of changes in the patch.
The patch will be quite big as it has to replace all the uses atomically.

I can get rid of the helper in consecutive patch.

Best regards,
Krzysztof



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-31 18:15     ` Konrad Rzeszutek Wilk
@ 2016-06-01  6:08       ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  6:08 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: Russell King, Catalin Marinas, Will Deacon, Joerg Roedel,
	Andrew Morton, Marek Szyprowski, Michal Hocko, Mel Gorman,
	Arnd Bergmann, Andy Lutomirski, linux-doc, linux-kernel,
	linux-arm-kernel, xen-devel, dri-devel, linux-samsung-soc, iommu,
	hch, sstabellini, Bartlomiej Zolnierkiewicz

On 05/31/2016 08:15 PM, Konrad Rzeszutek Wilk wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
> 
> 
> .. why not go the next step a do an enum? Perhaps that should be mentioned
> as part of the description?

These are additive flags so to me this would look a little bit weird:
enum dma_attr {
	DMA_ATTR_WRITE_BARRIER	= 0x1,
	DMA_ATTR_WEAK_ORDERING	= 0x2,
	DMA_ATTR_WRITE_COMBINE	= 0x4,
	DMA_ATTR_NON_CONSISTENT	= 0x8,
	...
}

It doesn't really look like enumeration.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-06-01  6:08       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/31/2016 08:15 PM, Konrad Rzeszutek Wilk wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
> 
> 
> .. why not go the next step a do an enum? Perhaps that should be mentioned
> as part of the description?

These are additive flags so to me this would look a little bit weird:
enum dma_attr {
	DMA_ATTR_WRITE_BARRIER	= 0x1,
	DMA_ATTR_WEAK_ORDERING	= 0x2,
	DMA_ATTR_WRITE_COMBINE	= 0x4,
	DMA_ATTR_NON_CONSISTENT	= 0x8,
	...
}

It doesn't really look like enumeration.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-05-31 18:15     ` Konrad Rzeszutek Wilk
  (?)
  (?)
@ 2016-06-01  6:08     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2016-06-01  6:08 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, hch, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On 05/31/2016 08:15 PM, Konrad Rzeszutek Wilk wrote:
> On Mon, May 30, 2016 at 01:54:06PM +0200, Krzysztof Kozlowski wrote:
>> The dma-mapping core and the implementations do not change the
>> DMA attributes passed by pointer.  Thus the pointer can point to const
>> data.  However the attributes do not have to be a bitfield. Instead
>> unsigned long will do fine:
>>
>> 1. This is just simpler.  Both in terms of reading the code and setting
>>    attributes.  Instead of initializing local attributes on the stack and
>>    passing pointer to it to dma_set_attr(), just set the bits.
>>
>> 2. It brings safeness and checking for const correctness because the
>>    attributes are passed by value.
> 
> 
> .. why not go the next step a do an enum? Perhaps that should be mentioned
> as part of the description?

These are additive flags so to me this would look a little bit weird:
enum dma_attr {
	DMA_ATTR_WRITE_BARRIER	= 0x1,
	DMA_ATTR_WEAK_ORDERING	= 0x2,
	DMA_ATTR_WRITE_COMBINE	= 0x4,
	DMA_ATTR_NON_CONSISTENT	= 0x8,
	...
}

It doesn't really look like enumeration.

Best regards,
Krzysztof

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-06-01  5:36       ` Krzysztof Kozlowski
  (?)
@ 2016-06-01  7:51         ` Christoph Hellwig
  -1 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-06-01  7:51 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Joerg Roedel, Andrew Morton, Marek Szyprowski, Michal Hocko,
	Mel Gorman, Arnd Bergmann, Andy Lutomirski, linux-doc,
	linux-kernel, linux-arm-kernel, xen-devel, dri-devel,
	linux-samsung-soc, iommu, sstabellini, Bartlomiej Zolnierkiewicz

On Wed, Jun 01, 2016 at 07:36:42AM +0200, Krzysztof Kozlowski wrote:
> > No really for this patch, but I would much prefer to document them next
> > to the code in the long run.  Also I really think these BIT() macros
> > are a distraction compared to the (1 << N) notation.
> 
> Not much difference to me but maybe plain number:
> ...	0x01u
> ...	0x02u
> ?

I prefer the little bit shifts, but even the explicit values are much
better than the obsfucating macros :)  Anyway, your patch and in the end
all three methods will get the work done.

> > I'd just kill this helper, much easier to simply open code it in the
> > caller.
> 
> Keeping it for now helps reducing the number of changes in the patch.
> The patch will be quite big as it has to replace all the uses atomically.
> 
> I can get rid of the helper in consecutive patch.

Sounds fine.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-06-01  7:51         ` Christoph Hellwig
  0 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-06-01  7:51 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, Christoph Hellwig, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On Wed, Jun 01, 2016 at 07:36:42AM +0200, Krzysztof Kozlowski wrote:
> > No really for this patch, but I would much prefer to document them next
> > to the code in the long run.  Also I really think these BIT() macros
> > are a distraction compared to the (1 << N) notation.
> 
> Not much difference to me but maybe plain number:
> ...	0x01u
> ...	0x02u
> ?

I prefer the little bit shifts, but even the explicit values are much
better than the obsfucating macros :)  Anyway, your patch and in the end
all three methods will get the work done.

> > I'd just kill this helper, much easier to simply open code it in the
> > caller.
> 
> Keeping it for now helps reducing the number of changes in the patch.
> The patch will be quite big as it has to replace all the uses atomically.
> 
> I can get rid of the helper in consecutive patch.

Sounds fine.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [RFC v2] dma-mapping: Use unsigned long for dma_attrs
@ 2016-06-01  7:51         ` Christoph Hellwig
  0 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-06-01  7:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 01, 2016 at 07:36:42AM +0200, Krzysztof Kozlowski wrote:
> > No really for this patch, but I would much prefer to document them next
> > to the code in the long run.  Also I really think these BIT() macros
> > are a distraction compared to the (1 << N) notation.
> 
> Not much difference to me but maybe plain number:
> ...	0x01u
> ...	0x02u
> ?

I prefer the little bit shifts, but even the explicit values are much
better than the obsfucating macros :)  Anyway, your patch and in the end
all three methods will get the work done.

> > I'd just kill this helper, much easier to simply open code it in the
> > caller.
> 
> Keeping it for now helps reducing the number of changes in the patch.
> The patch will be quite big as it has to replace all the uses atomically.
> 
> I can get rid of the helper in consecutive patch.

Sounds fine.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v2] dma-mapping: Use unsigned long for dma_attrs
  2016-06-01  5:36       ` Krzysztof Kozlowski
  (?)
  (?)
@ 2016-06-01  7:51       ` Christoph Hellwig
  -1 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2016-06-01  7:51 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michal Hocko, Arnd Bergmann, linux-doc, Catalin Marinas,
	Joerg Roedel, Bartlomiej Zolnierkiewicz, Will Deacon,
	Russell King, dri-devel, linux-kernel, Christoph Hellwig, iommu,
	linux-samsung-soc, sstabellini, Andy Lutomirski, xen-devel,
	Andrew Morton, Mel Gorman, linux-arm-kernel, Marek Szyprowski

On Wed, Jun 01, 2016 at 07:36:42AM +0200, Krzysztof Kozlowski wrote:
> > No really for this patch, but I would much prefer to document them next
> > to the code in the long run.  Also I really think these BIT() macros
> > are a distraction compared to the (1 << N) notation.
> 
> Not much difference to me but maybe plain number:
> ...	0x01u
> ...	0x02u
> ?

I prefer the little bit shifts, but even the explicit values are much
better than the obsfucating macros :)  Anyway, your patch and in the end
all three methods will get the work done.

> > I'd just kill this helper, much easier to simply open code it in the
> > caller.
> 
> Keeping it for now helps reducing the number of changes in the patch.
> The patch will be quite big as it has to replace all the uses atomically.
> 
> I can get rid of the helper in consecutive patch.

Sounds fine.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-06-01  7:52 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-30 11:54 [RFC v2] Change dma_attrs from bitfield to unsigned long Krzysztof Kozlowski
2016-05-30 11:54 ` Krzysztof Kozlowski
2016-05-30 11:54 ` [RFC v2] dma-mapping: Use unsigned long for dma_attrs Krzysztof Kozlowski
2016-05-30 11:54 ` Krzysztof Kozlowski
2016-05-30 11:54   ` Krzysztof Kozlowski
2016-05-30 11:54   ` Krzysztof Kozlowski
2016-05-31 17:04   ` Christoph Hellwig
2016-05-31 17:04   ` Christoph Hellwig
2016-05-31 17:04     ` Christoph Hellwig
2016-05-31 17:04     ` Christoph Hellwig
2016-06-01  5:36     ` Krzysztof Kozlowski
2016-06-01  5:36     ` Krzysztof Kozlowski
2016-06-01  5:36       ` Krzysztof Kozlowski
2016-06-01  7:51       ` Christoph Hellwig
2016-06-01  7:51         ` Christoph Hellwig
2016-06-01  7:51         ` Christoph Hellwig
2016-06-01  7:51       ` Christoph Hellwig
2016-05-31 18:15   ` Konrad Rzeszutek Wilk
2016-05-31 18:15     ` Konrad Rzeszutek Wilk
2016-05-31 18:15     ` Konrad Rzeszutek Wilk
2016-06-01  6:08     ` Krzysztof Kozlowski
2016-06-01  6:08     ` Krzysztof Kozlowski
2016-06-01  6:08       ` Krzysztof Kozlowski
2016-05-31 18:15   ` Konrad Rzeszutek Wilk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.