@@ -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;
@@ -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;
@@ -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);
@@ -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));
}