diff mbox

[v3,8/8] Davinci: iotable based ioremap() interception

Message ID 1273266399-17164-9-git-send-email-cyril@ti.com (mailing list archive)
State Accepted
Headers show

Commit Message

Cyril Chemparathy May 7, 2010, 9:06 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 94fe971..3a7a96f 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1210,9 +1210,8 @@  static struct davinci_soc_info davinci_soc_info_da830 = {
 
 void __init da830_init(void)
 {
-	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
-	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
-		return;
-
 	davinci_common_init(&davinci_soc_info_da830);
+
+	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+	WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 74d4e49..6b8331b 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1099,6 +1099,8 @@  void __init da850_init(void)
 {
 	unsigned int v;
 
+	davinci_common_init(&davinci_soc_info_da850);
+
 	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
 		return;
@@ -1107,8 +1109,6 @@  void __init da850_init(void)
 	if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
 		return;
 
-	davinci_common_init(&davinci_soc_info_da850);
-
 	/*
 	 * Move the clock source of Async3 domain to PLL1 SYSCLK2.
 	 * This helps keeping the peripherals on this domain insulated
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 2e07248..a57cba2 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -39,7 +39,13 @@  struct davinci_timer_info {
 
 struct davinci_gpio_controller;
 
-/* SoC specific init support */
+/*
+ * SoC info passed into common davinci modules.
+ *
+ * Base addresses in this structure should be physical and not virtual.
+ * Modules that take such base addresses, should internally ioremap() them to
+ * use.
+ */
 struct davinci_soc_info {
 	struct map_desc			*io_desc;
 	unsigned long			io_desc_num;
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index a1c0b6b..8ea60a8 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);