diff mbox

Davinci: iotable based ioremap() interception

Message ID 1270831964-22661-1-git-send-email-cyril@ti.com (mailing list archive)
State Superseded
Headers show

Commit Message

Cyril Chemparathy April 9, 2010, 4:52 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 122e61a..168f277 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1206,9 +1206,14 @@  static struct davinci_soc_info davinci_soc_info_da830 = {
 	.emac_pdata		= &da8xx_emac_pdata,
 };
 
+#define da830_early_ioremap(p, s)				\
+	__davinci_ioremap(p, s,					\
+			davinci_soc_info_da830.io_desc,		\
+			davinci_soc_info_da830.io_desc_num)
+
 void __init da830_init(void)
 {
-	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+	da8xx_syscfg0_base = da830_early_ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
 		return;
 
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index d0fd756..27eb32e 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1093,15 +1093,20 @@  static struct davinci_soc_info davinci_soc_info_da850 = {
 	.sram_len		= SZ_8K,
 };
 
+#define da850_early_ioremap(p, s)				\
+	__davinci_ioremap(p, s,					\
+			davinci_soc_info_da850.io_desc,		\
+			davinci_soc_info_da850.io_desc_num)
+
 void __init da850_init(void)
 {
 	unsigned int v;
 
-	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+	da8xx_syscfg0_base = da850_early_ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
 		return;
 
-	da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
+	da8xx_syscfg1_base = da850_early_ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
 	if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
 		return;
 
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
index 62b0a90..4aa301c 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -25,6 +25,10 @@ 
 #define __arch_ioremap(p, s, t)	davinci_ioremap(p, s, t)
 #define __arch_iounmap(v)	davinci_iounmap(v)
 
+struct map_desc;
+
+void __iomem *__davinci_ioremap(unsigned long p, size_t size,
+		struct map_desc *io_desc, int io_desc_num);
 void __iomem *davinci_ioremap(unsigned long phys, size_t size,
 			      unsigned int type);
 void davinci_iounmap(volatile void __iomem *addr);
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index a1c0b6b..3a62f14 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -12,17 +12,42 @@ 
 #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>
+
+/*
+ * Remap io addresses based on a soc-specific io-descriptor table. This is
+ * useful in early arch init code before davinci_common_init().  After
+ * davinci_common_init(), regular ioremap() calls should be used.
+ */
+void __iomem *__davinci_ioremap(unsigned long p, size_t size,
+		struct map_desc *io_desc, int io_desc_num)
+{
+	int i;
+
+	for (i = 0; i < io_desc_num; i++, io_desc++) {
+		unsigned long iophys = __pfn_to_phys(io_desc->pfn);
+		unsigned long iosize = io_desc->length;
+
+		if (p >= iophys && (p + size) <= (iophys + iosize))
+			return __io(io_desc->virtual + p - iophys);
+	}
+
+	return NULL;
+}
 
 /*
  * 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);
+	void __iomem *ret;
+
+	ret = __davinci_ioremap(p, size, davinci_soc_info.io_desc,
+			davinci_soc_info.io_desc_num);
+	if (ret)
+		return ret;
 
 	return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
 }