From fced80c735941fa518ac67c0b61bbe153fb8c050 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Sat, 6 Sep 2008 12:10:45 +0100
Subject: [ARM] Convert asm/io.h to linux/io.h

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/gic.c        | 2 +-
 arch/arm/common/locomo.c     | 2 +-
 arch/arm/common/sa1111.c     | 2 +-
 arch/arm/common/scoop.c      | 2 +-
 arch/arm/common/time-acorn.c | 2 +-
 arch/arm/common/uengine.c    | 2 +-
 arch/arm/common/via82c505.c  | 2 +-
 arch/arm/common/vic.c        | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 0c89bd35e06f..7fc9860a97d7 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -27,9 +27,9 @@
 #include <linux/list.h>
 #include <linux/smp.h>
 #include <linux/cpumask.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/gic.h>
 
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 283051eaf931..534b23d95864 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -24,9 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ec8a5471bf06..fb86f248aab8 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -25,10 +25,10 @@
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/sizes.h>
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index ae39553589dd..697c64913990 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -15,7 +15,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/gpio.h>
 #include <asm/hardware/scoop.h>
 
diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c
index df0983aafe69..deeed561b168 100644
--- a/arch/arm/common/time-acorn.c
+++ b/arch/arm/common/time-acorn.c
@@ -17,9 +17,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/hardware/ioc.h>
 
 #include <asm/mach/time.h>
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
index 7ecd3c0ab011..b520e56216a9 100644
--- a/arch/arm/common/uengine.c
+++ b/arch/arm/common/uengine.c
@@ -16,9 +16,9 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/hardware/uengine.h>
-#include <asm/io.h>
 
 #if defined(CONFIG_ARCH_IXP2000)
 #define IXP_UENGINE_CSR_VIRT_BASE	IXP2000_UENGINE_CSR_VIRT_BASE
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
index 79a8206e62ac..8421d39109b3 100644
--- a/arch/arm/common/via82c505.c
+++ b/arch/arm/common/via82c505.c
@@ -4,8 +4,8 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include <asm/mach/pci.h>
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index c026fa2214a3..f1e4b8f60cab 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -20,8 +20,8 @@
  */
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
-- 
cgit v1.2.3


From afd1a321c49a250dab97cef6f2d3c3c9b9d0174a Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 16:30:57 +0100
Subject: [ARM] Update dma_map_sg()/dma_unmap_sg() API

Update the ARM DMA scatter gather APIs for the scatterlist changes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        |  33 ++++++-----
 arch/arm/include/asm/dma-mapping.h | 115 ++-----------------------------------
 arch/arm/mm/dma-mapping.c          |  92 +++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 125 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index aecc6c3f908f..35c72bcf3d0b 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -435,6 +435,7 @@ int
 dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 		enum dma_data_direction dir)
 {
+	struct scatterlist *s;
 	int i;
 
 	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
@@ -442,14 +443,13 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
 	BUG_ON(dir == DMA_NONE);
 
-	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg_page(sg);
-		unsigned int offset = sg->offset;
-		unsigned int length = sg->length;
+	for_each_sg(sg, s, nents, i) {
+		struct page *page = sg_page(s);
+		unsigned int offset = s->offset;
+		unsigned int length = s->length;
 		void *ptr = page_address(page) + offset;
 
-		sg->dma_address =
-			map_single(dev, ptr, length, dir);
+		s->dma_address = map_single(dev, ptr, length, dir);
 	}
 
 	return nents;
@@ -459,6 +459,7 @@ void
 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 		enum dma_data_direction dir)
 {
+	struct scatterlist *s;
 	int i;
 
 	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
@@ -466,9 +467,9 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 
 	BUG_ON(dir == DMA_NONE);
 
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
+	for_each_sg(sg, s, nents, i) {
+		dma_addr_t dma_addr = s->dma_address;
+		unsigned int length = s->length;
 
 		unmap_single(dev, dma_addr, length, dir);
 	}
@@ -502,6 +503,7 @@ void
 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
 			enum dma_data_direction dir)
 {
+	struct scatterlist *s;
 	int i;
 
 	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
@@ -509,9 +511,9 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
 
 	BUG_ON(dir == DMA_NONE);
 
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
+	for_each_sg(sg, s, nents, i) {
+		dma_addr_t dma_addr = s->dma_address;
+		unsigned int length = s->length;
 
 		sync_single(dev, dma_addr, length, dir);
 	}
@@ -521,6 +523,7 @@ void
 dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
 			enum dma_data_direction dir)
 {
+	struct scatterlist *s;
 	int i;
 
 	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
@@ -528,9 +531,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
 
 	BUG_ON(dir == DMA_NONE);
 
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
+	for_each_sg(sg, s, nents, i) {
+		dma_addr_t dma_addr = s->dma_address;
+		unsigned int length = s->length;
 
 		sync_single(dev, dma_addr, length, dir);
 	}
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 7b95d2058395..eff954852c2b 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -281,75 +281,6 @@ dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
 	dma_unmap_single(dev, handle, size, dir);
 }
 
-/**
- * dma_map_sg - map a set of SG buffers for streaming mode DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above dma_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	   enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt;
-
-		sg->dma_address = page_to_dma(dev, sg_page(sg)) + sg->offset;
-		virt = sg_virt(sg);
-
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-
-	return nents;
-}
-#else
-extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-#endif
-
-/**
- * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Unmap a set of streaming mode DMA translations.
- * Again, CPU read rules concerning calls here are the same as for
- * dma_unmap_single() above.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-	     enum dma_data_direction dir)
-{
-
-	/* nothing to do */
-}
-#else
-extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-#endif
-
-
 /**
  * dma_sync_single_range_for_cpu
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -405,50 +336,14 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
 	dma_sync_single_range_for_device(dev, handle, 0, size, dir);
 }
 
-
-/**
- * dma_sync_sg_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as dma_sync_single_for_* but for a scatter-gather list,
- * same rules and usage.
+/*
+ * The scatter list versions of the above methods.
  */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-		    enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt = sg_virt(sg);
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
-		       enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt = sg_virt(sg);
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-}
-#else
+extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
+extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
 extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction);
 extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction);
-#endif
+
 
 #ifdef CONFIG_DMABOUNCE
 /*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 9f312248d5af..7bf3e6fdfb57 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -512,3 +512,95 @@ void dma_cache_maint(const void *start, size_t size, int direction)
 	}
 }
 EXPORT_SYMBOL(dma_cache_maint);
+
+#ifndef CONFIG_DMABOUNCE
+/**
+ * dma_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * This is the scatter-gather version of the dma_map_single interface.
+ * Here the scatter gather list elements are each tagged with the
+ * appropriate dma address and length.  They are obtained via
+ * sg_dma_{address,length}.
+ *
+ * Device ownership issues as mentioned for dma_map_single are the same
+ * here.
+ */
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		s->dma_address = page_to_dma(dev, sg_page(s)) + s->offset;
+
+		if (!arch_is_coherent())
+			dma_cache_maint(sg_virt(s), s->length, dir);
+	}
+
+	return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+/**
+ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+		enum dma_data_direction dir)
+{
+	/* nothing to do */
+}
+EXPORT_SYMBOL(dma_unmap_sg);
+
+/**
+ * dma_sync_sg_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		if (!arch_is_coherent())
+			dma_cache_maint(sg_virt(s), s->length, dir);
+	}
+}
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+/**
+ * dma_sync_sg_for_device
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		if (!arch_is_coherent())
+			dma_cache_maint(sg_virt(s), s->length, dir);
+	}
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+#endif
-- 
cgit v1.2.3


From 56f55f8b58a02e95b401cb50df05086cabeaeeb5 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 20:59:12 +0100
Subject: [ARM] dma: provide a better dma_map_page() implementation

We can translate a struct page directly to a DMA address using
page_to_dma().  No need to use page_address() followed by
virt_to_dma().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        | 13 +++++++++++++
 arch/arm/include/asm/dma-mapping.h | 11 ++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 35c72bcf3d0b..c7f23ced0a36 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -412,6 +412,19 @@ dma_map_single(struct device *dev, void *ptr, size_t size,
 	return dma_addr;
 }
 
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction dir)
+{
+	dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
+		__func__, page, offset, size, dir);
+
+	BUG_ON(dir == DMA_NONE);
+
+	return map_single(dev, page_address(page) + offset, size, dir);
+}
+EXPORT_SYMBOL(dma_map_page);
+
 /*
  * see if a mapped address was really a "safe" buffer and if so, copy
  * the data from the safe buffer back to the unsafe buffer and free up
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index eff954852c2b..856ee1bdee57 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -227,13 +227,22 @@ extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_d
  * can regain ownership by calling dma_unmap_page() or
  * dma_sync_single_for_cpu().
  */
+#ifndef CONFIG_DMABOUNCE
 static inline dma_addr_t
 dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size,
 	     enum dma_data_direction dir)
 {
-	return dma_map_single(dev, page_address(page) + offset, size, dir);
+	if (!arch_is_coherent())
+		dma_cache_maint(page_address(page) + offset, size, dir);
+
+	return page_to_dma(dev, page) + offset;
 }
+#else
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction dir);
+#endif
 
 /**
  * dma_unmap_single - unmap a single buffer previously mapped
-- 
cgit v1.2.3


From 01135d92c1a540cd3370f7cf3d1c762320b85034 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 21:05:02 +0100
Subject: [ARM] dma: Reduce to one dma_map_sg()/dma_unmap_sg() implementation

No point having two of these; dma_map_page() can do all the work
for us.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c | 46 ---------------------------------------------
 arch/arm/mm/dma-mapping.c   | 24 +++++++++++++++--------
 2 files changed, 16 insertions(+), 54 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index c7f23ced0a36..20d967376fa9 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -444,50 +444,6 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 	unmap_single(dev, dma_addr, size, dir);
 }
 
-int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir)
-{
-	struct scatterlist *s;
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for_each_sg(sg, s, nents, i) {
-		struct page *page = sg_page(s);
-		unsigned int offset = s->offset;
-		unsigned int length = s->length;
-		void *ptr = page_address(page) + offset;
-
-		s->dma_address = map_single(dev, ptr, length, dir);
-	}
-
-	return nents;
-}
-
-void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir)
-{
-	struct scatterlist *s;
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for_each_sg(sg, s, nents, i) {
-		dma_addr_t dma_addr = s->dma_address;
-		unsigned int length = s->length;
-
-		unmap_single(dev, dma_addr, length, dir);
-	}
-}
-
 void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_addr,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir)
@@ -662,8 +618,6 @@ dmabounce_unregister_dev(struct device *dev)
 
 EXPORT_SYMBOL(dma_map_single);
 EXPORT_SYMBOL(dma_unmap_single);
-EXPORT_SYMBOL(dma_map_sg);
-EXPORT_SYMBOL(dma_unmap_sg);
 EXPORT_SYMBOL(dma_sync_sg_for_cpu);
 EXPORT_SYMBOL(dma_sync_sg_for_device);
 EXPORT_SYMBOL(dmabounce_register_dev);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7bf3e6fdfb57..c9c1206e358c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -513,7 +513,6 @@ void dma_cache_maint(const void *start, size_t size, int direction)
 }
 EXPORT_SYMBOL(dma_cache_maint);
 
-#ifndef CONFIG_DMABOUNCE
 /**
  * dma_map_sg - map a set of SG buffers for streaming mode DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -534,16 +533,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 		enum dma_data_direction dir)
 {
 	struct scatterlist *s;
-	int i;
+	int i, j;
 
 	for_each_sg(sg, s, nents, i) {
-		s->dma_address = page_to_dma(dev, sg_page(s)) + s->offset;
-
-		if (!arch_is_coherent())
-			dma_cache_maint(sg_virt(s), s->length, dir);
+		s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+						s->length, dir);
+		if (dma_mapping_error(dev, s->dma_address))
+			goto bad_mapping;
 	}
-
 	return nents;
+
+ bad_mapping:
+	for_each_sg(sg, s, i, j)
+		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+	return 0;
 }
 EXPORT_SYMBOL(dma_map_sg);
 
@@ -560,10 +563,15 @@ EXPORT_SYMBOL(dma_map_sg);
 void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 		enum dma_data_direction dir)
 {
-	/* nothing to do */
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i)
+		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
 }
 EXPORT_SYMBOL(dma_unmap_sg);
 
+#ifndef CONFIG_DMABOUNCE
 /**
  * dma_sync_sg_for_cpu
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
-- 
cgit v1.2.3


From 2638b4dbe768aba023a06acd8e7eba708bb76ee6 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 21:38:41 +0100
Subject: [ARM] dma: Reduce to one dma_sync_sg_* implementation

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        | 48 ++++++++++----------------------------
 arch/arm/include/asm/dma-mapping.h | 11 +++++++++
 arch/arm/mm/dma-mapping.c          | 10 ++++++--
 3 files changed, 31 insertions(+), 38 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 20d967376fa9..0a98148279b1 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -468,45 +468,23 @@ void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_addr,
 }
 EXPORT_SYMBOL(dma_sync_single_range_for_device);
 
-void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir)
+int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
+		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	struct scatterlist *s;
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for_each_sg(sg, s, nents, i) {
-		dma_addr_t dma_addr = s->dma_address;
-		unsigned int length = s->length;
-
-		sync_single(dev, dma_addr, length, dir);
-	}
+	dev_dbg(dev, "%s(dma=%#lx,off=%#lx,sz=%zx,dir=%x)\n",
+		__func__, addr, off, sz, dir);
+	return sync_single(dev, addr, off + sz, dir);
 }
+EXPORT_SYMBOL(dmabounce_sync_for_cpu);
 
-void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir)
+int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
+		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	struct scatterlist *s;
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for_each_sg(sg, s, nents, i) {
-		dma_addr_t dma_addr = s->dma_address;
-		unsigned int length = s->length;
-
-		sync_single(dev, dma_addr, length, dir);
-	}
+	dev_dbg(dev, "%s(dma=%#lx,off=%#lx,sz=%zx,dir=%x)\n",
+		__func__, addr, off, sz, dir);
+	return sync_single(dev, addr, off + sz, dir);
 }
+EXPORT_SYMBOL(dmabounce_sync_for_device);
 
 static int
 dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
@@ -618,8 +596,6 @@ dmabounce_unregister_dev(struct device *dev)
 
 EXPORT_SYMBOL(dma_map_single);
 EXPORT_SYMBOL(dma_unmap_single);
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-EXPORT_SYMBOL(dma_sync_sg_for_device);
 EXPORT_SYMBOL(dmabounce_register_dev);
 EXPORT_SYMBOL(dmabounce_unregister_dev);
 
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 856ee1bdee57..29404f71ab87 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -410,6 +410,17 @@ extern void dmabounce_unregister_dev(struct device *);
  *
  */
 extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
+
+/*
+ * Private functions
+ */
+int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
+			size_t, enum dma_data_direction);
+int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
+			size_t, enum dma_data_direction);
+#else
+#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
+#define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
 #endif /* CONFIG_DMABOUNCE */
 
 #endif /* __KERNEL__ */
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c9c1206e358c..0e28cf33f7dd 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -571,7 +571,6 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 }
 EXPORT_SYMBOL(dma_unmap_sg);
 
-#ifndef CONFIG_DMABOUNCE
 /**
  * dma_sync_sg_for_cpu
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -586,6 +585,10 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
+		if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+					sg_dma_len(s), dir))
+			continue;
+
 		if (!arch_is_coherent())
 			dma_cache_maint(sg_virt(s), s->length, dir);
 	}
@@ -606,9 +609,12 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
+		if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
+					sg_dma_len(s), dir))
+			continue;
+
 		if (!arch_is_coherent())
 			dma_cache_maint(sg_virt(s), s->length, dir);
 	}
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
-#endif
-- 
cgit v1.2.3


From 8c8a0ec57ee285ff407e9a64b3a5a37eaf800ad8 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 21:52:49 +0100
Subject: [ARM] dma: use new dmabounce_sync_for_xxx() for dma_sync_single_xxx()

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        |  24 ------
 arch/arm/include/asm/dma-mapping.h | 150 +++++++++++++++++++------------------
 2 files changed, 76 insertions(+), 98 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 0a98148279b1..1cb880b734df 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -444,30 +444,6 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 	unmap_single(dev, dma_addr, size, dir);
 }
 
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_addr,
-				   unsigned long offset, size_t size,
-				   enum dma_data_direction dir)
-{
-	dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
-		__func__, dma_addr, offset, size, dir);
-
-	if (sync_single(dev, dma_addr, offset + size, dir))
-		dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
-}
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_addr,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir)
-{
-	dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
-		__func__, dma_addr, offset, size, dir);
-
-	if (sync_single(dev, dma_addr, offset + size, dir))
-		dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
-}
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
 int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
 		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 29404f71ab87..c003ad390def 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -184,6 +184,76 @@ int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
 			  void *cpu_addr, dma_addr_t handle, size_t size);
 
 
+#ifdef CONFIG_DMABOUNCE
+/*
+ * For SA-1111, IXP425, and ADI systems  the dma-mapping functions are "magic"
+ * and utilize bounce buffers as needed to work around limited DMA windows.
+ *
+ * On the SA-1111, a bug limits DMA to only certain regions of RAM.
+ * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
+ *
+ * The following are helper functions used by the dmabounce subystem
+ *
+ */
+
+/**
+ * dmabounce_register_dev
+ *
+ * @dev: valid struct device pointer
+ * @small_buf_size: size of buffers to use with small buffer pool
+ * @large_buf_size: size of buffers to use with large buffer pool (can be 0)
+ *
+ * This function should be called by low-level platform code to register
+ * a device as requireing DMA buffer bouncing. The function will allocate
+ * appropriate DMA pools for the device.
+ *
+ */
+extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long);
+
+/**
+ * dmabounce_unregister_dev
+ *
+ * @dev: valid struct device pointer
+ *
+ * This function should be called by low-level platform code when device
+ * that was previously registered with dmabounce_register_dev is removed
+ * from the system.
+ *
+ */
+extern void dmabounce_unregister_dev(struct device *);
+
+/**
+ * dma_needs_bounce
+ *
+ * @dev: valid struct device pointer
+ * @dma_handle: dma_handle of unbounced buffer
+ * @size: size of region being mapped
+ *
+ * Platforms that utilize the dmabounce mechanism must implement
+ * this function.
+ *
+ * The dmabounce routines call this function whenever a dma-mapping
+ * is requested to determine whether a given buffer needs to be bounced
+ * or not. The function must return 0 if the buffer is OK for
+ * DMA access and 1 if the buffer needs to be bounced.
+ *
+ */
+extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
+
+/*
+ * Private functions
+ */
+int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
+			size_t, enum dma_data_direction);
+int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
+			size_t, enum dma_data_direction);
+#else
+#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
+#define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
+#endif /* CONFIG_DMABOUNCE */
+
+
 /**
  * dma_map_single - map a single buffer for streaming DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -308,12 +378,14 @@ dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
  * must first the perform a dma_sync_for_device, and then the
  * device again owns the buffer.
  */
-#ifndef CONFIG_DMABOUNCE
 static inline void
 dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
 			      unsigned long offset, size_t size,
 			      enum dma_data_direction dir)
 {
+	if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
+		return;
+
 	if (!arch_is_coherent())
 		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
 }
@@ -323,13 +395,12 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
 				 unsigned long offset, size_t size,
 				 enum dma_data_direction dir)
 {
+	if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
+		return;
+
 	if (!arch_is_coherent())
 		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
 }
-#else
-extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t, unsigned long, size_t, enum dma_data_direction);
-extern void dma_sync_single_range_for_device(struct device *, dma_addr_t, unsigned long, size_t, enum dma_data_direction);
-#endif
 
 static inline void
 dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
@@ -354,74 +425,5 @@ extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum d
 extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction);
 
 
-#ifdef CONFIG_DMABOUNCE
-/*
- * For SA-1111, IXP425, and ADI systems  the dma-mapping functions are "magic"
- * and utilize bounce buffers as needed to work around limited DMA windows.
- *
- * On the SA-1111, a bug limits DMA to only certain regions of RAM.
- * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
- * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
- *
- * The following are helper functions used by the dmabounce subystem
- *
- */
-
-/**
- * dmabounce_register_dev
- *
- * @dev: valid struct device pointer
- * @small_buf_size: size of buffers to use with small buffer pool
- * @large_buf_size: size of buffers to use with large buffer pool (can be 0)
- *
- * This function should be called by low-level platform code to register
- * a device as requireing DMA buffer bouncing. The function will allocate
- * appropriate DMA pools for the device.
- *
- */
-extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long);
-
-/**
- * dmabounce_unregister_dev
- *
- * @dev: valid struct device pointer
- *
- * This function should be called by low-level platform code when device
- * that was previously registered with dmabounce_register_dev is removed
- * from the system.
- *
- */
-extern void dmabounce_unregister_dev(struct device *);
-
-/**
- * dma_needs_bounce
- *
- * @dev: valid struct device pointer
- * @dma_handle: dma_handle of unbounced buffer
- * @size: size of region being mapped
- *
- * Platforms that utilize the dmabounce mechanism must implement
- * this function.
- *
- * The dmabounce routines call this function whenever a dma-mapping
- * is requested to determine whether a given buffer needs to be bounced
- * or not. The function must return 0 if the buffer is OK for
- * DMA access and 1 if the buffer needs to be bounced.
- *
- */
-extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
-
-/*
- * Private functions
- */
-int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
-			size_t, enum dma_data_direction);
-int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
-			size_t, enum dma_data_direction);
-#else
-#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
-#define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
-#endif /* CONFIG_DMABOUNCE */
-
 #endif /* __KERNEL__ */
 #endif
-- 
cgit v1.2.3


From 125ab12acf64ff86b55d20e14db20becd917b7c4 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 22:16:22 +0100
Subject: [ARM] dma: fix dmabounce dma_sync_xxx() implementations

The dmabounce dma_sync_xxx() implementation have been broken for
quite some time; they all copy data between the DMA buffer and
the CPU visible buffer no irrespective of the change of ownership.
(IOW, a DMA_FROM_DEVICE mapping copies data from the DMA buffer
to the CPU buffer during a call to dma_sync_single_for_device().)

Fix it by getting rid of sync_single(), moving the contents into
the recently created dmabounce_sync_for_xxx() functions and adjusting
appropriately.

This also makes it possible to properly support the DMA range sync
functions.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        | 144 +++++++++++++++----------------------
 arch/arm/include/asm/dma-mapping.h |  26 +++----
 2 files changed, 69 insertions(+), 101 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 1cb880b734df..d4b0c608fdee 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -205,6 +205,21 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
 
 /* ************************************************** */
 
+static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
+		dma_addr_t dma_addr, const char *where)
+{
+	if (!dev || !dev->archdata.dmabounce)
+		return NULL;
+	if (dma_mapping_error(dev, dma_addr)) {
+		if (dev)
+			dev_err(dev, "Trying to %s invalid mapping\n", where);
+		else
+			pr_err("unknown device: Trying to %s invalid mapping\n", where);
+		return NULL;
+	}
+	return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
+}
+
 static inline dma_addr_t
 map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
@@ -274,19 +289,7 @@ static inline void
 unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		enum dma_data_direction dir)
 {
-	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
-	struct safe_buffer *buf = NULL;
-
-	/*
-	 * Trying to unmap an invalid mapping
-	 */
-	if (dma_mapping_error(dev, dma_addr)) {
-		dev_err(dev, "Trying to unmap invalid mapping\n");
-		return;
-	}
-
-	if (device_info)
-		buf = find_safe_buffer(device_info, dma_addr);
+	struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap");
 
 	if (buf) {
 		BUG_ON(buf->size != size);
@@ -296,7 +299,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 			__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
 			buf->safe, buf->safe_dma_addr);
 
-		DO_STATS ( device_info->bounce_count++ );
+		DO_STATS(dev->archdata.dmabounce->bounce_count++);
 
 		if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
 			void *ptr = buf->ptr;
@@ -317,74 +320,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 			dmac_clean_range(ptr, ptr + size);
 			outer_clean_range(__pa(ptr), __pa(ptr) + size);
 		}
-		free_safe_buffer(device_info, buf);
-	}
-}
-
-static int sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-			enum dma_data_direction dir)
-{
-	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
-	struct safe_buffer *buf = NULL;
-
-	if (device_info)
-		buf = find_safe_buffer(device_info, dma_addr);
-
-	if (buf) {
-		/*
-		 * Both of these checks from original code need to be
-		 * commented out b/c some drivers rely on the following:
-		 *
-		 * 1) Drivers may map a large chunk of memory into DMA space
-		 *    but only sync a small portion of it. Good example is
-		 *    allocating a large buffer, mapping it, and then
-		 *    breaking it up into small descriptors. No point
-		 *    in syncing the whole buffer if you only have to
-		 *    touch one descriptor.
-		 *
-		 * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are
-		 *    usually only synced in one dir at a time.
-		 *
-		 * See drivers/net/eepro100.c for examples of both cases.
-		 *
-		 * -ds
-		 *
-		 * BUG_ON(buf->size != size);
-		 * BUG_ON(buf->direction != dir);
-		 */
-
-		dev_dbg(dev,
-			"%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
-			__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
-			buf->safe, buf->safe_dma_addr);
-
-		DO_STATS ( device_info->bounce_count++ );
-
-		switch (dir) {
-		case DMA_FROM_DEVICE:
-			dev_dbg(dev,
-				"%s: copy back safe %p to unsafe %p size %d\n",
-				__func__, buf->safe, buf->ptr, size);
-			memcpy(buf->ptr, buf->safe, size);
-			break;
-		case DMA_TO_DEVICE:
-			dev_dbg(dev,
-				"%s: copy out unsafe %p to safe %p, size %d\n",
-				__func__,buf->ptr, buf->safe, size);
-			memcpy(buf->safe, buf->ptr, size);
-			break;
-		case DMA_BIDIRECTIONAL:
-			BUG();	/* is this allowed?  what does it mean? */
-		default:
-			BUG();
-		}
-		/*
-		 * No need to sync the safe buffer - it was allocated
-		 * via the coherent allocators.
-		 */
-		return 0;
-	} else {
-		return 1;
+		free_safe_buffer(dev->archdata.dmabounce, buf);
 	}
 }
 
@@ -447,18 +383,54 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
 		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	dev_dbg(dev, "%s(dma=%#lx,off=%#lx,sz=%zx,dir=%x)\n",
+	struct safe_buffer *buf;
+
+	dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
 		__func__, addr, off, sz, dir);
-	return sync_single(dev, addr, off + sz, dir);
+
+	buf = find_safe_buffer_dev(dev, addr, __func__);
+	if (!buf)
+		return 1;
+
+	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+		buf->safe, buf->safe_dma_addr);
+
+	DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+	if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+		dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n",
+			__func__, buf->safe + off, buf->ptr + off, sz);
+		memcpy(buf->ptr + off, buf->safe + off, sz);
+	}
+	return 0;
 }
 EXPORT_SYMBOL(dmabounce_sync_for_cpu);
 
 int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
 		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	dev_dbg(dev, "%s(dma=%#lx,off=%#lx,sz=%zx,dir=%x)\n",
+	struct safe_buffer *buf;
+
+	dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
 		__func__, addr, off, sz, dir);
-	return sync_single(dev, addr, off + sz, dir);
+
+	buf = find_safe_buffer_dev(dev, addr, __func__);
+	if (!buf)
+		return 1;
+
+	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+		buf->safe, buf->safe_dma_addr);
+
+	DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) {
+		dev_dbg(dev, "%s: copy out unsafe %p to safe %p, size %d\n",
+			__func__,buf->ptr + off, buf->safe + off, sz);
+		memcpy(buf->safe + off, buf->ptr + off, sz);
+	}
+	return 0;
 }
 EXPORT_SYMBOL(dmabounce_sync_for_device);
 
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index c003ad390def..1204dc958c43 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -241,6 +241,15 @@ extern void dmabounce_unregister_dev(struct device *);
  */
 extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
 
+/*
+ * The DMA API, implemented by dmabounce.c.  See below for descriptions.
+ */
+extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction);
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction dir);
+extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction);
+
 /*
  * Private functions
  */
@@ -251,7 +260,6 @@ int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
 #else
 #define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
 #define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
-#endif /* CONFIG_DMABOUNCE */
 
 
 /**
@@ -268,7 +276,6 @@ int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
  * can regain ownership by calling dma_unmap_single() or
  * dma_sync_single_for_cpu().
  */
-#ifndef CONFIG_DMABOUNCE
 static inline dma_addr_t
 dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 	       enum dma_data_direction dir)
@@ -278,9 +285,7 @@ dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 
 	return virt_to_dma(dev, cpu_addr);
 }
-#else
-extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction);
-#endif
+
 
 /**
  * dma_map_page - map a portion of a page for streaming DMA
@@ -297,7 +302,6 @@ extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_d
  * can regain ownership by calling dma_unmap_page() or
  * dma_sync_single_for_cpu().
  */
-#ifndef CONFIG_DMABOUNCE
 static inline dma_addr_t
 dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size,
@@ -308,11 +312,6 @@ dma_map_page(struct device *dev, struct page *page,
 
 	return page_to_dma(dev, page) + offset;
 }
-#else
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-			unsigned long offset, size_t size,
-			enum dma_data_direction dir);
-#endif
 
 /**
  * dma_unmap_single - unmap a single buffer previously mapped
@@ -328,16 +327,13 @@ extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
  * After this call, reads by the CPU to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
-#ifndef CONFIG_DMABOUNCE
 static inline void
 dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
 		 enum dma_data_direction dir)
 {
 	/* nothing to do */
 }
-#else
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction);
-#endif
+#endif /* CONFIG_DMABOUNCE */
 
 /**
  * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
-- 
cgit v1.2.3


From 3216a97bb0d5166ec5795aa3db1c3a02415ac060 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Thu, 25 Sep 2008 22:23:31 +0100
Subject: [ARM] dma: coding style cleanups

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        |  48 ++++++-----------
 arch/arm/include/asm/dma-mapping.h | 104 +++++++++++++++++--------------------
 2 files changed, 64 insertions(+), 88 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index d4b0c608fdee..22aec95c9863 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -154,9 +154,7 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
 #endif
 
 	write_lock_irqsave(&device_info->lock, flags);
-
 	list_add(&buf->node, &device_info->safe_buffers);
-
 	write_unlock_irqrestore(&device_info->lock, flags);
 
 	return buf;
@@ -220,8 +218,7 @@ static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
 	return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
 }
 
-static inline dma_addr_t
-map_single(struct device *dev, void *ptr, size_t size,
+static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
 {
 	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
@@ -285,9 +282,8 @@ map_single(struct device *dev, void *ptr, size_t size,
 	return dma_addr;
 }
 
-static inline void
-unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		enum dma_data_direction dir)
+static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
+		size_t size, enum dma_data_direction dir)
 {
 	struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap");
 
@@ -332,25 +328,20 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
  * substitute the safe buffer for the unsafe one.
  * (basically move the buffer from an unsafe area to a safe one)
  */
-dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_addr_t dma_addr;
-
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, ptr, size, dir);
 
 	BUG_ON(dir == DMA_NONE);
 
-	dma_addr = map_single(dev, ptr, size, dir);
-
-	return dma_addr;
+	return map_single(dev, ptr, size, dir);
 }
+EXPORT_SYMBOL(dma_map_single);
 
 dma_addr_t dma_map_page(struct device *dev, struct page *page,
-			unsigned long offset, size_t size,
-			enum dma_data_direction dir)
+		unsigned long offset, size_t size, enum dma_data_direction dir)
 {
 	dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
 		__func__, page, offset, size, dir);
@@ -368,9 +359,8 @@ EXPORT_SYMBOL(dma_map_page);
  * should be)
  */
 
-void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-			enum dma_data_direction dir)
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		enum dma_data_direction dir)
 {
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);
@@ -379,6 +369,7 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 
 	unmap_single(dev, dma_addr, size, dir);
 }
+EXPORT_SYMBOL(dma_unmap_single);
 
 int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
 		unsigned long off, size_t sz, enum dma_data_direction dir)
@@ -434,9 +425,8 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
 }
 EXPORT_SYMBOL(dmabounce_sync_for_device);
 
-static int
-dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
-		    unsigned long size)
+static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
+		const char *name, unsigned long size)
 {
 	pool->size = size;
 	DO_STATS(pool->allocs = 0);
@@ -447,9 +437,8 @@ dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char
 	return pool->pool ? 0 : -ENOMEM;
 }
 
-int
-dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
-			unsigned long large_buffer_size)
+int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
+		unsigned long large_buffer_size)
 {
 	struct dmabounce_device_info *device_info;
 	int ret;
@@ -505,9 +494,9 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 	kfree(device_info);
 	return ret;
 }
+EXPORT_SYMBOL(dmabounce_register_dev);
 
-void
-dmabounce_unregister_dev(struct device *dev)
+void dmabounce_unregister_dev(struct device *dev)
 {
 	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
 
@@ -540,11 +529,6 @@ dmabounce_unregister_dev(struct device *dev)
 
 	dev_info(dev, "dmabounce: device unregistered\n");
 }
-
-
-EXPORT_SYMBOL(dma_map_single);
-EXPORT_SYMBOL(dma_unmap_single);
-EXPORT_SYMBOL(dmabounce_register_dev);
 EXPORT_SYMBOL(dmabounce_unregister_dev);
 
 MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>");
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 1204dc958c43..1532b7a6079d 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -104,15 +104,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
  * Dummy noncoherent implementation.  We don't provide a dma_cache_sync
  * function so drivers using this API are highlighted with build warnings.
  */
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+		dma_addr_t *handle, gfp_t gfp)
 {
 	return NULL;
 }
 
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
-		     dma_addr_t handle)
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+		void *cpu_addr, dma_addr_t handle)
 {
 }
 
@@ -127,8 +126,7 @@ dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
  * return the CPU-viewed address, and sets @handle to be the
  * device-viewed address.
  */
-extern void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
 
 /**
  * dma_free_coherent - free memory allocated by dma_alloc_coherent
@@ -143,9 +141,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
  * References to memory and mappings associated with cpu_addr/handle
  * during and after this call executing are illegal.
  */
-extern void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle);
+extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
 
 /**
  * dma_mmap_coherent - map a coherent DMA allocation into user space
@@ -159,8 +155,8 @@ dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
  * into user space.  The coherent DMA buffer must not be freed by the
  * driver until the user space mapping has been released.
  */
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-		      void *cpu_addr, dma_addr_t handle, size_t size);
+int dma_mmap_coherent(struct device *, struct vm_area_struct *,
+		void *, dma_addr_t, size_t);
 
 
 /**
@@ -174,14 +170,14 @@ int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
  * return the CPU-viewed address, and sets @handle to be the
  * device-viewed address.
  */
-extern void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
+		gfp_t);
 
 #define dma_free_writecombine(dev,size,cpu_addr,handle) \
 	dma_free_coherent(dev,size,cpu_addr,handle)
 
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
-			  void *cpu_addr, dma_addr_t handle, size_t size);
+int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
+		void *, dma_addr_t, size_t);
 
 
 #ifdef CONFIG_DMABOUNCE
@@ -209,7 +205,8 @@ int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
  * appropriate DMA pools for the device.
  *
  */
-extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long);
+extern int dmabounce_register_dev(struct device *, unsigned long,
+		unsigned long);
 
 /**
  * dmabounce_unregister_dev
@@ -244,19 +241,20 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
 /*
  * The DMA API, implemented by dmabounce.c.  See below for descriptions.
  */
-extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-			unsigned long offset, size_t size,
-			enum dma_data_direction dir);
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction);
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+		enum dma_data_direction);
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+		unsigned long, size_t, enum dma_data_direction);
+extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+		enum dma_data_direction);
 
 /*
  * Private functions
  */
 int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
-			size_t, enum dma_data_direction);
+		size_t, enum dma_data_direction);
 int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
-			size_t, enum dma_data_direction);
+		size_t, enum dma_data_direction);
 #else
 #define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
 #define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
@@ -276,9 +274,8 @@ int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
  * can regain ownership by calling dma_unmap_single() or
  * dma_sync_single_for_cpu().
  */
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-	       enum dma_data_direction dir)
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+		size_t size, enum dma_data_direction dir)
 {
 	if (!arch_is_coherent())
 		dma_cache_maint(cpu_addr, size, dir);
@@ -286,7 +283,6 @@ dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 	return virt_to_dma(dev, cpu_addr);
 }
 
-
 /**
  * dma_map_page - map a portion of a page for streaming DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -302,10 +298,8 @@ dma_map_single(struct device *dev, void *cpu_addr, size_t size,
  * can regain ownership by calling dma_unmap_page() or
  * dma_sync_single_for_cpu().
  */
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-	     unsigned long offset, size_t size,
-	     enum dma_data_direction dir)
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	     unsigned long offset, size_t size, enum dma_data_direction dir)
 {
 	if (!arch_is_coherent())
 		dma_cache_maint(page_address(page) + offset, size, dir);
@@ -327,9 +321,8 @@ dma_map_page(struct device *dev, struct page *page,
  * After this call, reads by the CPU to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
-		 enum dma_data_direction dir)
+static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
+		size_t size, enum dma_data_direction dir)
 {
 	/* nothing to do */
 }
@@ -349,9 +342,8 @@ dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
  * After this call, reads by the CPU to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-	       enum dma_data_direction dir)
+static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
+		size_t size, enum dma_data_direction dir)
 {
 	dma_unmap_single(dev, handle, size, dir);
 }
@@ -374,10 +366,9 @@ dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
  * must first the perform a dma_sync_for_device, and then the
  * device again owns the buffer.
  */
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
-			      unsigned long offset, size_t size,
-			      enum dma_data_direction dir)
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+		dma_addr_t handle, unsigned long offset, size_t size,
+		enum dma_data_direction dir)
 {
 	if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
 		return;
@@ -386,10 +377,9 @@ dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
 		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
-				 unsigned long offset, size_t size,
-				 enum dma_data_direction dir)
+static inline void dma_sync_single_range_for_device(struct device *dev,
+		dma_addr_t handle, unsigned long offset, size_t size,
+		enum dma_data_direction dir)
 {
 	if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
 		return;
@@ -398,16 +388,14 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
 		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
-			enum dma_data_direction dir)
+static inline void dma_sync_single_for_cpu(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
 	dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
 }
 
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
-			   enum dma_data_direction dir)
+static inline void dma_sync_single_for_device(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
 	dma_sync_single_range_for_device(dev, handle, 0, size, dir);
 }
@@ -415,10 +403,14 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
 /*
  * The scatter list versions of the above methods.
  */
-extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction);
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_unmap_sg(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
 
 
 #endif /* __KERNEL__ */
-- 
cgit v1.2.3


From 0e18b5d7c6339311f1e32e7b186ae3556c5b6d33 Mon Sep 17 00:00:00 2001
From: Russell King <rmk@dyn-67.arm.linux.org.uk>
Date: Mon, 29 Sep 2008 13:48:17 +0100
Subject: [ARM] dma: add validation of DMA params

Validate the direction argument like x86 does.  In addition,
validate the dma_unmap_* parameters against those passed to
dma_map_* when using the DMA bounce code.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/dmabounce.c        | 11 +++++++----
 arch/arm/include/asm/dma-mapping.h |  8 ++++++++
 2 files changed, 15 insertions(+), 4 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 22aec95c9863..f030f0775be7 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -289,6 +289,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
 
 	if (buf) {
 		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != dir);
 
 		dev_dbg(dev,
 			"%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
@@ -334,7 +335,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, ptr, size, dir);
 
-	BUG_ON(dir == DMA_NONE);
+	BUG_ON(!valid_dma_direction(dir));
 
 	return map_single(dev, ptr, size, dir);
 }
@@ -346,7 +347,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
 	dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
 		__func__, page, offset, size, dir);
 
-	BUG_ON(dir == DMA_NONE);
+	BUG_ON(!valid_dma_direction(dir));
 
 	return map_single(dev, page_address(page) + offset, size, dir);
 }
@@ -365,8 +366,6 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);
 
-	BUG_ON(dir == DMA_NONE);
-
 	unmap_single(dev, dma_addr, size, dir);
 }
 EXPORT_SYMBOL(dma_unmap_single);
@@ -383,6 +382,8 @@ int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
 	if (!buf)
 		return 1;
 
+	BUG_ON(buf->direction != dir);
+
 	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
 		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
 		buf->safe, buf->safe_dma_addr);
@@ -410,6 +411,8 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
 	if (!buf)
 		return 1;
 
+	BUG_ON(buf->direction != dir);
+
 	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
 		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
 		buf->safe, buf->safe_dma_addr);
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 1532b7a6079d..2544a087c213 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -277,6 +277,8 @@ int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
 static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
 		size_t size, enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
+
 	if (!arch_is_coherent())
 		dma_cache_maint(cpu_addr, size, dir);
 
@@ -301,6 +303,8 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
 static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
+
 	if (!arch_is_coherent())
 		dma_cache_maint(page_address(page) + offset, size, dir);
 
@@ -370,6 +374,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
 		dma_addr_t handle, unsigned long offset, size_t size,
 		enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
+
 	if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
 		return;
 
@@ -381,6 +387,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
 		dma_addr_t handle, unsigned long offset, size_t size,
 		enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
+
 	if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
 		return;
 
-- 
cgit v1.2.3


From ec36b16d0d1ae0a43eb8c395e9bf58efdadad1d7 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 27 Dec 2007 14:19:44 +0100
Subject: [ARM] 4733/1: export sharpsl_param

EXPORT sharpsl_param which is necessary to support modular build of some depending drivers.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/sharpsl_param.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
index aad4d94ba8f5..d56c932580eb 100644
--- a/arch/arm/common/sharpsl_param.c
+++ b/arch/arm/common/sharpsl_param.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <asm/mach/sharpsl_param.h>
 
@@ -36,6 +37,7 @@
 #define PHAD_MAGIC	MAGIC_CHG('P','H','A','D')
 
 struct sharpsl_param_info sharpsl_param;
+EXPORT_SYMBOL(sharpsl_param);
 
 void sharpsl_save_param(void)
 {
-- 
cgit v1.2.3


From d8aa0251f12546e9bd1e9ee1d9782d6492819a04 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 9 Oct 2008 13:36:24 +0100
Subject: [ARM] 5298/1: Drop desc_handle_irq()

desc_handle_irq() was declared as obsolete since long ago.
Replace it with generic_handle_irq()

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/common/it8152.c                 | 14 +++-----------
 arch/arm/common/locomo.c                 | 26 ++++++++------------------
 arch/arm/kernel/ecard.c                  |  6 ++----
 arch/arm/kernel/irq.c                    | 11 +++++------
 arch/arm/mach-at91/gpio.c                |  3 +--
 arch/arm/mach-davinci/gpio.c             |  5 +----
 arch/arm/mach-ep93xx/core.c              |  7 +++----
 arch/arm/mach-footbridge/isa-irq.c       |  3 +--
 arch/arm/mach-h720x/common.c             |  4 +---
 arch/arm/mach-h720x/cpu-h7202.c          |  4 +---
 arch/arm/mach-imx/irq.c                  |  4 +---
 arch/arm/mach-integrator/integrator_cp.c |  3 +--
 arch/arm/mach-iop13xx/msi.c              |  3 +--
 arch/arm/mach-ixp2000/core.c             |  6 ++----
 arch/arm/mach-ixp2000/ixdp2x00.c         |  4 +---
 arch/arm/mach-ixp2000/ixdp2x01.c         |  4 +---
 arch/arm/mach-ixp23xx/core.c             |  4 +---
 arch/arm/mach-ixp23xx/ixdp2351.c         |  8 ++------
 arch/arm/mach-lh7a40x/arch-kev7a400.c    |  2 +-
 arch/arm/mach-lh7a40x/arch-lpd7a40x.c    |  4 ++--
 arch/arm/mach-lh7a40x/common.h           |  1 -
 arch/arm/mach-lh7a40x/irq-lpd7a40x.c     |  4 ++--
 arch/arm/mach-netx/generic.c             |  5 +----
 arch/arm/mach-ns9xxx/board-a9m9750dev.c  |  5 +----
 arch/arm/mach-omap1/board-voiceblue.c    |  1 +
 arch/arm/mach-omap1/fpga.c               |  4 +---
 arch/arm/mach-orion5x/irq.c              |  2 +-
 arch/arm/mach-pxa/gpio.c                 |  2 +-
 arch/arm/mach-pxa/lpd270.c               |  3 +--
 arch/arm/mach-pxa/lubbock.c              |  3 +--
 arch/arm/mach-pxa/mainstone.c            |  3 +--
 arch/arm/mach-pxa/pcm990-baseboard.c     |  3 +--
 arch/arm/mach-s3c2410/bast-irq.c         |  3 +--
 arch/arm/mach-s3c2412/irq.c              |  4 ++--
 arch/arm/mach-s3c2440/irq.c              |  7 ++-----
 arch/arm/mach-s3c2443/irq.c              |  5 +----
 arch/arm/mach-sa1100/irq.c               |  4 +---
 arch/arm/mach-sa1100/neponset.c          | 11 +++--------
 arch/arm/mach-versatile/core.c           |  3 +--
 arch/arm/plat-omap/gpio.c                |  5 +----
 arch/arm/plat-s3c24xx/irq.c              | 24 +++++++-----------------
 arch/arm/plat-s3c24xx/s3c244x-irq.c      |  7 ++-----
 42 files changed, 72 insertions(+), 162 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 5fe9588db077..2793447621c3 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -66,14 +66,6 @@ static void it8152_unmask_irq(unsigned int irq)
        }
 }
 
-static inline void it8152_irq(int irq)
-{
-	struct irq_desc *desc;
-
-	desc = irq_desc + irq;
-	desc_handle_irq(irq, desc);
-}
-
 static struct irq_chip it8152_irq_chip = {
 	.name		= "it8152",
 	.ack		= it8152_mask_irq,
@@ -128,21 +120,21 @@ void it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
 	       bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1);
 	       while (bits_pd) {
 		       i = __ffs(bits_pd);
-		       it8152_irq(IT8152_PD_IRQ(i));
+		       generic_handle_irq(IT8152_PD_IRQ(i));
 		       bits_pd &= ~(1 << i);
 	       }
 
 	       bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1);
 	       while (bits_lp) {
 		       i = __ffs(bits_lp);
-		       it8152_irq(IT8152_LP_IRQ(i));
+		       generic_handle_irq(IT8152_LP_IRQ(i));
 		       bits_lp &= ~(1 << i);
 	       }
 
 	       bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1);
 	       while (bits_ld) {
 		       i = __ffs(bits_ld);
-		       it8152_irq(IT8152_LD_IRQ(i));
+		       generic_handle_irq(IT8152_LD_IRQ(i));
 		       bits_ld &= ~(1 << i);
 	       }
        }
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 283051eaf931..8f473b7c3494 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -169,7 +169,6 @@ static struct locomo_dev_info locomo_devices[] = {
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	/* Acknowledge the parent IRQ */
@@ -181,10 +180,9 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 	if (req) {
 		/* generate the next interrupt(s) */
 		irq = LOCOMO_IRQ_START;
-		d = irq_desc + irq;
-		for (i = 0; i <= 3; i++, d++, irq++) {
+		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0100 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 
 		}
@@ -222,12 +220,10 @@ static struct irq_chip locomo_chip = {
 
 static void locomo_key_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
-		d = irq_desc + LOCOMO_IRQ_KEY_START;
-		desc_handle_irq(LOCOMO_IRQ_KEY_START, d);
+		generic_handle_irq(LOCOMO_IRQ_KEY_START);
 	}
 }
 
@@ -268,7 +264,6 @@ static struct irq_chip locomo_key_chip = {
 static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	req = 	locomo_readl(mapbase + LOCOMO_GIR) &
@@ -277,10 +272,9 @@ static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
 
 	if (req) {
 		irq = LOCOMO_IRQ_GPIO_START;
-		d = irq_desc + LOCOMO_IRQ_GPIO_START;
-		for (i = 0; i <= 15; i++, irq++, d++) {
+		for (i = 0; i <= 15; i++, irq++) {
 			if (req & (0x0001 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 		}
 	}
@@ -361,12 +355,10 @@ static struct irq_chip locomo_gpio_chip = {
 
 static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
-		d = irq_desc + LOCOMO_IRQ_LT_START;
-		desc_handle_irq(LOCOMO_IRQ_LT_START, d);
+		generic_handle_irq(LOCOMO_IRQ_LT_START);
 	}
 }
 
@@ -407,17 +399,15 @@ static struct irq_chip locomo_lt_chip = {
 static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
 	if (req) {
 		irq = LOCOMO_IRQ_SPI_START;
-		d = irq_desc + irq;
 
-		for (i = 0; i <= 3; i++, irq++, d++) {
+		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0001 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 		}
 	}
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 7a50575a8d4d..60c079d85355 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -587,8 +587,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 			pending = ecard_default_ops.irqpending(ec);
 
 		if (pending) {
-			struct irq_desc *d = irq_desc + ec->irq;
-			desc_handle_irq(ec->irq, d);
+			generic_handle_irq(ec->irq);
 			called ++;
 		}
 	}
@@ -622,7 +621,6 @@ ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc)
 		ecard_t *ec = slot_to_ecard(slot);
 
 		if (ec->claimed) {
-			struct irq_desc *d = irq_desc + ec->irq;
 			/*
 			 * this ugly code is so that we can operate a
 			 * prioritorising system:
@@ -635,7 +633,7 @@ ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc)
 			 * Serial cards should go in 0/1, ethernet/scsi in 2/3
 			 * otherwise you will lose serial data at high speeds!
 			 */
-			desc_handle_irq(ec->irq, d);
+			generic_handle_irq(ec->irq);
 		} else {
 			printk(KERN_WARNING "card%d: interrupt from unclaimed "
 			       "card???\n", slot);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index f88efb135b70..2f3eb795fa6e 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -112,18 +112,17 @@ static struct irq_desc bad_irq_desc = {
 asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	struct irq_desc *desc = irq_desc + irq;
+
+	irq_enter();
 
 	/*
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
 	 */
 	if (irq >= NR_IRQS)
-		desc = &bad_irq_desc;
-
-	irq_enter();
-
-	desc_handle_irq(irq, desc);
+		handle_bad_irq(irq, &bad_irq_desc);
+	else
+		generic_handle_irq(irq);
 
 	/* AT91 specific workaround */
 	irq_finish(irq);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 8392d5b517f1..94c2f96811f9 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -404,7 +404,6 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		}
 
 		pin = bank->chipbase;
-		gpio = &irq_desc[pin];
 
 		while (isr) {
 			if (isr & 1) {
@@ -417,7 +416,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 					gpio_irq_mask(pin);
 				}
 				else
-					desc_handle_irq(pin, gpio);
+					generic_handle_irq(pin);
 			}
 			pin++;
 			gpio++;
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index c9cb4f09b18f..574cb810a500 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -201,7 +201,6 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 	desc->chip->ack(irq);
 	while (1) {
 		u32		status;
-		struct irq_desc	*gpio;
 		int		n;
 		int		res;
 
@@ -215,12 +214,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 		/* now demux them to the right lowlevel handler */
 		n = (int)get_irq_data(irq);
-		gpio = &irq_desc[n];
 		while (status) {
 			res = ffs(status);
 			n += res;
-			gpio += res;
-			desc_handle_irq(n - 1, gpio - 1);
+			generic_handle_irq(n - 1);
 			status >>= res;
 		}
 	}
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index f99f43669392..68ee82b49597 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -192,8 +192,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
-			desc = irq_desc + gpio_irq;
-			desc_handle_irq(gpio_irq, desc);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 
@@ -202,7 +201,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
 			desc = irq_desc + gpio_irq;
-			desc_handle_irq(gpio_irq, desc);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 }
@@ -217,7 +216,7 @@ static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
 	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
 
-	desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
+	generic_handle_irq(gpio_irq);
 }
 
 static void ep93xx_gpio_irq_ack(unsigned int irq)
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index 7132e522c366..d5a29a0e7d9d 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -94,8 +94,7 @@ isa_irq_handler(unsigned int irq, struct irq_desc *desc)
 		return;
 	}
 
-	desc = irq_desc + isa_irq;
-	desc_handle_irq(isa_irq, desc);
+	generic_handle_irq(isa_irq);
 }
 
 static struct irqaction irq_cascade = {
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index b5f9741ae13c..c1fa44cff38d 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -104,14 +104,12 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq,
                  struct irq_desc *desc)
 {
 	IRQDBG("%s irq: %d\n", __func__, irq);
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1) {
 			IRQDBG("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 53e1f62f2e79..fd33a19c813a 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -120,12 +120,10 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 
 	mask >>= 1;
 	irq = IRQ_TIMER1;
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1)
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c
index 798f221eb3b7..cbdd7d1dac92 100644
--- a/arch/arm/mach-imx/irq.c
+++ b/arch/arm/mach-imx/irq.c
@@ -182,14 +182,12 @@ static void
 imx_gpio_handler(unsigned int mask, unsigned int irq,
                  struct irq_desc *desc)
 {
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1) {
 			DEBUG_IRQ("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 6b99e9c258bd..0c9a91d6ec83 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -217,8 +217,7 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
 
 		irq += IRQ_SIC_START;
 
-		desc = irq_desc + irq;
-		desc_handle_irq(irq, desc);
+		generic_handle_irq(irq);
 	} while (status);
 }
 
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index 63ef1124ca5c..f34b0ed80630 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -110,8 +110,7 @@ static void iop13xx_msi_handler(unsigned int irq, struct irq_desc *desc)
 		do {
 			j = find_first_bit(&status, 32);
 			(write_imipr[i])(1 << j); /* write back to clear bit */
-			desc = irq_desc + IRQ_IOP13XX_MSI_0 + j + (32*i);
-			desc_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i),	desc);
+			generic_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i));
 			status = (read_imipr[i])();
 		} while (status);
 	}
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index a6a4f93085fd..e193a34e4175 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -311,8 +311,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
 		   
 	for (i = 0; i <= 7; i++) {
 		if (status & (1<<i)) {
-			desc = irq_desc + i + IRQ_IXP2000_GPIO0;
-			desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc);
+			generic_handle_irq(i + IRQ_IXP2000_GPIO0);
 		}
 	}
 }
@@ -404,8 +403,7 @@ static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	for(i = 31; i >= 0; i--) {
 		if(status & (1 << i)) {
-			desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
-			desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc);
+			generic_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i);
 		}
 	}
 }
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 5a781fd9757a..4c749d490241 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -129,10 +129,8 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	for(i = 0; i < board_irq_count; i++) {
 		if(ex_interrupt & (1 << i))  {
-			struct irq_desc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 78a2341dee2c..b78c08d1f638 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -79,10 +79,8 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	for (i = 0; i < IXP2000_BOARD_IRQS; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 68b4ac5b2481..aa4c4420ff3d 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -253,7 +253,6 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 {
 	u32 pci_interrupt;
 	unsigned int irqno;
-	struct irq_desc *int_desc;
 
 	pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
 
@@ -268,8 +267,7 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 		BUG();
 	}
 
-	int_desc = irq_desc + irqno;
-	desc_handle_irq(irqno, int_desc);
+	generic_handle_irq(irqno);
 
 	desc->chip->unmask(irq);
 }
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index b6e0bfa44df9..f1b124a709ab 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -68,11 +68,9 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
 
 	for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq =
 				IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
@@ -105,11 +103,9 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
 
 	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq =
 				IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 551b97261826..3d7bd50b9095 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -77,7 +77,7 @@ static void kev7a400_cpld_handler (unsigned int irq, struct irq_desc *desc)
 	irq = IRQ_KEV7A400_CPLD;
 	for (; mask; mask >>= 1, ++irq)
 		if (mask & 1)
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 }
 
 void __init lh7a40x_init_board_irq (void)
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index e373fb8e2699..cb15e5d32120 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -214,11 +214,11 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 	desc->chip->ack (irq);
 
 	if ((mask & (1<<0)) == 0)	/* WLAN */
-		IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
+		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
 
 #if defined (IRQ_TOUCH)
 	if ((mask & (1<<1)) == 0)	/* Touch */
-		IRQ_DISPATCH (IRQ_TOUCH);
+		generic_handle_irq(IRQ_TOUCH);
 #endif
 
 	desc->chip->unmask (irq); /* Level-triggered need this */
diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
index 0ca20c6c83b7..6ed3f6b6db76 100644
--- a/arch/arm/mach-lh7a40x/common.h
+++ b/arch/arm/mach-lh7a40x/common.h
@@ -15,4 +15,3 @@ extern void lh7a404_init_irq (void);
 extern void lh7a40x_clcd_init (void);
 extern void lh7a40x_init_board_irq (void);
 
-#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq))
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
index 0d5063ebda10..fd033bb4342f 100644
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -63,10 +63,10 @@ static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 	desc->chip->ack (irq);
 
 	if ((mask & 0x1) == 0)	/* WLAN */
-		IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
+		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
 
 	if ((mask & 0x2) == 0)	/* Touch */
-		IRQ_DISPATCH (IRQ_LPD7A400_TS);
+		generic_handle_irq(IRQ_LPD7A400_TS);
 
 	desc->chip->unmask (irq); /* Level-triggered need this */
 }
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 1b40483ea753..3830eca2438a 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -77,15 +77,12 @@ netx_hif_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 	stat = ((readl(NETX_DPMAS_INT_EN) &
 		readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;
 
-	desc = irq_desc + NETX_IRQ_HIF_CHAINED(0);
-
 	while (stat) {
 		if (stat & 1) {
 			DEBUG_IRQ("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		stat >>= 1;
 	}
 }
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index a22a608a7aba..b45bb3b802f1 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -86,13 +86,10 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 
 	while (stat != 0) {
 		int irqno = fls(stat) - 1;
-		struct irq_desc *fpgadesc;
 
 		stat &= ~(1 << irqno);
 
-		fpgadesc = irq_desc + FPGA_IRQ(irqno);
-
-		desc_handle_irq(FPGA_IRQ(irqno), fpgadesc);
+		generic_handle_irq(FPGA_IRQ(irqno));
 	}
 
 	desc->chip->unmask(irq);
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 213b48787102..45a01311669a 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -21,6 +21,7 @@
 #include <linux/reboot.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 4449d86095f6..23f2c3aeb384 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -86,7 +86,6 @@ static void fpga_mask_ack_irq(unsigned int irq)
 
 void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	u32 stat;
 	int fpga_irq;
 
@@ -99,8 +98,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
 	     (fpga_irq < OMAP_FPGA_IRQ_END) && stat;
 	     fpga_irq++, stat >>= 1) {
 		if (stat & 1) {
-			d = irq_desc + fpga_irq;
-			desc_handle_irq(fpga_irq, d);
+			generic_handle_irq(fpga_irq);
 		}
 	}
 }
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index 2545ff9e5830..15f27aa7f53e 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -162,7 +162,7 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 				polarity ^= 1 << pin;
 				writel(polarity, GPIO_IN_POL);
 			}
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 	}
 }
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
index 07acc1b23857..e92bec510e5e 100644
--- a/arch/arm/mach-pxa/gpio.c
+++ b/arch/arm/mach-pxa/gpio.c
@@ -275,7 +275,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 			loop = 1;
 
 			n = PXA_GPIO_IRQ_BASE + bit;
-			desc_handle_irq(n, irq_desc + n);
+			generic_handle_irq(n);
 
 			bit = find_next_bit(gedr, GEDR_BITS, bit + 1);
 		}
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 92728a37298a..de3f67daaacf 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -125,8 +125,7 @@ static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc)
 		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
 		if (likely(pending)) {
 			irq = LPD270_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 
 			pending = __raw_readw(LPD270_INT_STATUS) &
 						lpd270_irq_enabled;
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index ecbfbb9f46a2..bff704354c1a 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -155,8 +155,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
 		GEDR(0) = GPIO_bit(0);	/* clear our parent irq */
 		if (likely(pending)) {
 			irq = LUBBOCK_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a02edfd4fc0a..f2c7ad8f2b6b 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -162,8 +162,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
 		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
 		if (likely(pending)) {
 			irq = MAINSTONE_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = MST_INTSETCLR & mainstone_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index e9efb80bb339..f601425f1b1e 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -262,8 +262,7 @@ static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
 					GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
 		if (likely(pending)) {
 			irq = PCM027_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index c66021b5fa4d..44140bd99ed3 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -130,8 +130,7 @@ bast_irq_pc104_demux(unsigned int irq,
 		for (i = 0; stat != 0; i++, stat >>= 1) {
 			if (stat & 1) {
 				irqno = bast_pc104_irqs[i];
-				desc = irq_desc + irqno;
-				desc_handle_irq(irqno, desc);
+				generic_handle_irq(irqno);
 			}
 		}
 	}
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index ac62b79044f4..72159d31966e 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -123,10 +123,10 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
 	subsrc  &= ~submsk;
 
 	if (subsrc & INTBIT(IRQ_S3C2412_SDI))
-		desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);
+		generic_handle_irq(IRQ_S3C2412_SDI);
 
 	if (subsrc & INTBIT(IRQ_S3C2412_CF))
-		desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
+		generic_handle_irq(IRQ_S3C2412_CF);
 }
 
 #define INTMSK_CFSDI	(1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 276b823f4e27..ad68b4d88353 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -44,7 +44,6 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
 				  struct irq_desc *desc)
 {
 	unsigned int subsrc, submsk;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -58,12 +57,10 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_WDT;
-			desc_handle_irq(IRQ_S3C2440_WDT, mydesc);
+			generic_handle_irq(IRQ_S3C2440_WDT);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_AC97;
-			desc_handle_irq(IRQ_S3C2440_AC97, mydesc);
+			generic_handle_irq(IRQ_S3C2440_AC97);
 		}
 	}
 }
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 9674de7223fd..1570d3a6e15f 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -44,7 +44,6 @@ static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
 {
 	unsigned int subsrc, submsk;
 	unsigned int end;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -57,13 +56,11 @@ static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
 	subsrc  &= (1 << len)-1;
 
 	end = len + irq;
-	mydesc = irq_desc + irq;
 
 	for (; irq < end && subsrc; irq++) {
 		if (subsrc & 1)
-			desc_handle_irq(irq, mydesc);
+			generic_handle_irq(irq);
 
-		mydesc++;
 		subsrc >>= 1;
 	}
 }
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 86369a8f0cea..3093d46a9c6f 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -122,14 +122,12 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
 		GEDR = mask;
 
 		irq = IRQ_GPIO11;
-		desc = irq_desc + irq;
 		mask >>= 11;
 		do {
 			if (mask & 1)
-				desc_handle_irq(irq, desc);
+				generic_handle_irq(irq);
 			mask >>= 1;
 			irq++;
-			desc++;
 		} while (mask);
 
 		mask = GEDR & 0xfffff800;
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 4856a6bd2482..6ccd175bc4cf 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -33,8 +33,6 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 	unsigned int irr;
 
 	while (1) {
-		struct irq_desc *d;
-
 		/*
 		 * Acknowledge the parent IRQ.
 		 */
@@ -67,21 +65,18 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 			desc->chip->ack(irq);
 
 			if (irr & IRR_ETHERNET) {
-				d = irq_desc + IRQ_NEPONSET_SMC9196;
-				desc_handle_irq(IRQ_NEPONSET_SMC9196, d);
+				generic_handle_irq(IRQ_NEPONSET_SMC9196);
 			}
 
 			if (irr & IRR_USAR) {
-				d = irq_desc + IRQ_NEPONSET_USAR;
-				desc_handle_irq(IRQ_NEPONSET_USAR, d);
+				generic_handle_irq(IRQ_NEPONSET_USAR);
 			}
 
 			desc->chip->unmask(irq);
 		}
 
 		if (irr & IRR_SA1111) {
-			d = irq_desc + IRQ_NEPONSET_SA1111;
-			desc_handle_irq(IRQ_NEPONSET_SA1111, d);
+			generic_handle_irq(IRQ_NEPONSET_SA1111);
 		}
 	}
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index d75e795c893e..c3468bf2841e 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -95,8 +95,7 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
 
 		irq += IRQ_SIC_START;
 
-		desc = irq_desc + irq;
-		desc_handle_irq(irq, desc);
+		generic_handle_irq(irq);
 	} while (status);
 }
 
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9e1341ebc14e..960040aa71f7 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -1051,13 +1051,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 		gpio_irq = bank->virtual_irq_start;
 		for (; isr != 0; isr >>= 1, gpio_irq++) {
-			struct irq_desc *d;
-
 			if (!(isr & 1))
 				continue;
-			d = irq_desc + gpio_irq;
 
-			desc_handle_irq(gpio_irq, d);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 	/* if bank has any level sensitive GPIO pin interrupt
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 36cefe176835..b6c84f4f7a12 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -468,7 +468,6 @@ static void s3c_irq_demux_adc(unsigned int irq,
 {
 	unsigned int subsrc, submsk;
 	unsigned int offset = 9;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -482,12 +481,10 @@ static void s3c_irq_demux_adc(unsigned int irq,
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_TC;
-			desc_handle_irq(IRQ_TC, mydesc);
+			generic_handle_irq(IRQ_TC);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_ADC;
-			desc_handle_irq(IRQ_ADC, mydesc);
+			generic_handle_irq(IRQ_ADC);
 		}
 	}
 }
@@ -496,7 +493,6 @@ static void s3c_irq_demux_uart(unsigned int start)
 {
 	unsigned int subsrc, submsk;
 	unsigned int offset = start - IRQ_S3CUART_RX0;
-	struct irq_desc *desc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -512,20 +508,14 @@ static void s3c_irq_demux_uart(unsigned int start)
 	subsrc &= 7;
 
 	if (subsrc != 0) {
-		desc = irq_desc + start;
-
 		if (subsrc & 1)
-			desc_handle_irq(start, desc);
-
-		desc++;
+			generic_handle_irq(start);
 
 		if (subsrc & 2)
-			desc_handle_irq(start+1, desc);
-
-		desc++;
+			generic_handle_irq(start+1);
 
 		if (subsrc & 4)
-			desc_handle_irq(start+2, desc);
+			generic_handle_irq(start+2);
 	}
 }
 
@@ -572,7 +562,7 @@ s3c_irq_demux_extint8(unsigned int irq,
 		eintpnd &= ~(1<<irq);
 
 		irq += (IRQ_EINT4 - 4);
-		desc_handle_irq(irq, irq_desc + irq);
+		generic_handle_irq(irq);
 	}
 
 }
@@ -595,7 +585,7 @@ s3c_irq_demux_extint4t7(unsigned int irq,
 
 		irq += (IRQ_EINT4 - 4);
 
-		desc_handle_irq(irq, irq_desc + irq);
+		generic_handle_irq(irq);
 	}
 }
 
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
index f3dc38cf1de4..1e094fcb45a5 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -44,7 +44,6 @@ static void s3c_irq_demux_cam(unsigned int irq,
 			      struct irq_desc *desc)
 {
 	unsigned int subsrc, submsk;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -58,12 +57,10 @@ static void s3c_irq_demux_cam(unsigned int irq,
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-			desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc);
+			generic_handle_irq(IRQ_S3C2440_CAM_C);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-			desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc);
+			generic_handle_irq(IRQ_S3C2440_CAM_P);
 		}
 	}
 }
-- 
cgit v1.2.3


From 3bca103a1e658d23737d20e1989139d9ca8973bf Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nico@cam.org>
Date: Tue, 7 Oct 2008 20:14:55 +0100
Subject: [ARM] 5295/1: make ZONE_DMA optional

Most ARM machines don't need a special "DMA" memory zone, and
when configured out, the kernel becomes a bit smaller:

|   text    data     bss     dec     hex filename
|3826182  102384  111700 4040266  3da64a vmlinux
|3823593  101616  111700 4036909  3d992d vmlinux.nodmazone

This is because the system now has only one zone total which effect is
to optimize away many conditionals in page allocation paths.

So let's configure this zone only on machines that need split zones.

Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/Kconfig              | 4 +++-
 arch/arm/common/Kconfig       | 3 ++-
 arch/arm/include/asm/memory.h | 2 ++
 arch/arm/mach-pxa/Kconfig     | 1 +
 4 files changed, 8 insertions(+), 2 deletions(-)

(limited to 'arch/arm/common')

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f5bf38b5f38d..ea52fae33290 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -148,7 +148,6 @@ config ARCH_MAY_HAVE_PC_FDC
 
 config ZONE_DMA
 	bool
-	default y
 
 config GENERIC_ISA_DMA
 	bool
@@ -357,6 +356,7 @@ config ARCH_IXP4XX
 	select GENERIC_GPIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select ZONE_DMA if PCI
 	help
 	  Support for Intel's IXP4XX (XScale) family of processors.
 
@@ -503,6 +503,7 @@ config ARCH_SHARK
 	bool "Shark"
 	select ISA
 	select ISA_DMA
+	select ZONE_DMA
 	select PCI
 	help
 	  Support for the StrongARM based Digital DNARD machine, also known
@@ -524,6 +525,7 @@ config ARCH_DAVINCI
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select ZONE_DMA
 	help
 	  Support for TI's DaVinci platform.
 
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 3e073467caca..2e32acca02fb 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -12,7 +12,8 @@ config ICST307
 
 config SA1111
 	bool
-	select DMABOUNCE
+	select DMABOUNCE if !ARCH_PXA
+	select ZONE_DMA if !ARCH_PXA
 
 config DMABOUNCE
 	bool
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 7834adbe1774..809ff9ab853a 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -137,6 +137,8 @@
 
 #ifndef arch_adjust_zones
 #define arch_adjust_zones(node,size,holes) do { } while (0)
+#elif !defined(CONFIG_ZONE_DMA)
+#error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA"
 #endif
 
 /*
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e8ee7ec9ff6d..e484f609feda 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -210,6 +210,7 @@ config MACH_ARMCORE
 	bool "CompuLab CM-X270 modules"
 	select PXA27x
 	select IWMMXT
+	select ZONE_DMA if PCI
 
 config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
-- 
cgit v1.2.3