Davinci: iotable based ioremap() interception

This patch allows for a more flexible ioremap() interception based on iotable
contents.

With this patch, the ioremap() interception code can properly translate
addresses only after davinci_soc_info has been initialized.  Consequently,
in soc-specific init functions, davinci_common_init() has to happen before any
ioremap() attempts. The da8xx init sequence has been suitably modified to meet
this restriction.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index a1c0b6b..8ea60a8b 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -12,19 +12,29 @@
 #include <linux/io.h>
 
 #include <asm/tlb.h>
+#include <asm/mach/map.h>
 
-#define BETWEEN(p, st, sz)	((p) >= (st) && (p) < ((st) + (sz)))
-#define XLATE(p, pst, vst)	((void __iomem *)((p) - (pst) + (vst)))
+#include <mach/common.h>
 
 /*
  * Intercept ioremap() requests for addresses in our fixed mapping regions.
  */
 void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
 {
-	if (BETWEEN(p, IO_PHYS, IO_SIZE))
-		return XLATE(p, IO_PHYS, IO_VIRT);
+	struct map_desc *desc = davinci_soc_info.io_desc;
+	int desc_num = davinci_soc_info.io_desc_num;
+	int i;
 
-	return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
+	for (i = 0; i < desc_num; i++, desc++) {
+		unsigned long iophys = __pfn_to_phys(desc->pfn);
+		unsigned long iosize = desc->length;
+
+		if (p >= iophys && (p + size) <= (iophys + iosize))
+			return __io(desc->virtual + p - iophys);
+	}
+
+	return __arm_ioremap_caller(p, size, type,
+					__builtin_return_address(0));
 }
 EXPORT_SYMBOL(davinci_ioremap);