Davinci: iotable based ioremap() interception
authorCyril Chemparathy <cyril@ti.com>
Fri, 7 May 2010 21:06:39 +0000 (17:06 -0400)
committerKevin Hilman <khilman@deeprootsystems.com>
Thu, 13 May 2010 17:05:31 +0000 (10:05 -0700)
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>
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/include/mach/common.h
arch/arm/mach-davinci/io.c

index 94fe971f276aedddc4ba805a017d4e5faad348d2..3a7a96fe7b84f16856eafcaecec038e1461ec8d9 100644 (file)
@@ -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");
 }
index 74d4e49d406441f3311c037c2548d1acf9322bf8..6b8331bf8cf3dea8ba5306111559fdf82ccbf5d2 100644 (file)
@@ -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
index 2e072482c1198cf23d64632c7f5deb7577f899bf..a57cba21e21e1e150a949971deda4f46f38c50d7 100644 (file)
@@ -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;
index a1c0b6b99edf03e1fa4ad6847797995a8a349d0f..8ea60a8b2495d33f6d7f26c844b39b6f4e12d1a2 100644 (file)
 #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);