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

SoCs that need ioremap() to fill up davinci_soc_info may directly call
davinci_io_init() and use ioremap() as needed.  Such SoCs must not fill
io_desc and io_desc_num entries in struct davinci_soc_info.

Signed-off-by: Cyril Chemparathy <[email protected]>
Tested-by: Sandeep Paulraj <[email protected]>
---
v4: removed __davinci_ioremap() and related infrastructure
v4: split davinci_io_init() out of davinci_common_init()

 arch/arm/mach-davinci/common.c          |   13 +-------
 arch/arm/mach-davinci/da830.c           |    2 +
 arch/arm/mach-davinci/da850.c           |    2 +
 arch/arm/mach-davinci/include/mach/io.h |    5 +++
 arch/arm/mach-davinci/io.c              |   49 +++++++++++++++++++++++++++---
 5 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 94f27cb..aac43b1 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -65,17 +65,8 @@ void __init davinci_common_init(struct davinci_soc_info 
*soc_info)
 
        memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info));
 
-       if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0))
-               iotable_init(davinci_soc_info.io_desc,
-                               davinci_soc_info.io_desc_num);
-
-       /*
-        * Normally devicemaps_init() would flush caches and tlb after
-        * mdesc->map_io(), but we must also do it here because of the CPU
-        * revision check below.
-        */
-       local_flush_tlb_all();
-       flush_cache_all();
+       davinci_io_init(davinci_soc_info.io_desc,
+                       davinci_soc_info.io_desc_num);
 
        /*
         * We want to check CPU revision early for cpu_is_xxxx() macros.
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 68e5233..4bcdc6f 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1210,6 +1210,8 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
 
 void __init da830_init(void)
 {
+       davinci_io_init(da830_io_desc, ARRAY_SIZE(da830_io_desc));
+
        da8xx_syscfg0_base = 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 8aefcff..c2c2d58 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_io_init(da850_io_desc, ARRAY_SIZE(da850_io_desc));
+
        da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
        if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
                return;
diff --git a/arch/arm/mach-davinci/include/mach/io.h 
b/arch/arm/mach-davinci/include/mach/io.h
index 62b0a90..3f456b7 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -25,8 +25,13 @@
 #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 phys, size_t size,
                              unsigned int type);
 void davinci_iounmap(volatile void __iomem *addr);
+
+void davinci_io_init(struct map_desc *desc, unsigned long desc_num);
+
 #endif
 #endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index a1c0b6b..81862ec 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -12,19 +12,31 @@
 #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>
+
+static struct map_desc *davinci_io_desc;
+static unsigned long   davinci_io_desc_num;
 
 /*
  * 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_io_desc;
+       int i;
+
+       for (i = 0; i < davinci_io_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));
+       return __arm_ioremap_caller(p, size, type,
+                                       __builtin_return_address(0));
 }
 EXPORT_SYMBOL(davinci_ioremap);
 
@@ -36,3 +48,30 @@ void davinci_iounmap(volatile void __iomem *addr)
                __iounmap(addr);
 }
 EXPORT_SYMBOL(davinci_iounmap);
+
+void __init davinci_io_init(struct map_desc *desc, unsigned long desc_num)
+{
+       if (!desc || !desc_num)
+               return;
+
+       /* silently refuse to init twice ...*/
+       if (davinci_io_desc) {
+               /* ... unless things change */
+               BUG_ON(davinci_io_desc != desc ||
+                       davinci_io_desc_num != desc_num);
+               return;
+       }
+
+       davinci_io_desc = desc;
+       davinci_io_desc_num = desc_num;
+
+       iotable_init(desc, desc_num);
+
+       /*
+        * Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but we must also do it here because of the CPU
+        * revision check below.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+}
-- 
1.6.3.3

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to