summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyril Chemparathy <cyril@ti.com>2010-05-08 01:06:39 +0400
committerKevin Hilman <khilman@deeprootsystems.com>2010-05-13 21:05:31 +0400
commitbcd6a1c695c8b404bfde22b276186ac52a20291b (patch)
tree548f1308faa72bd90308632d16fb656718cf6090
parent779b0d53ca41873d59225eb776c5d4493a0abd0f (diff)
downloadlinux-bcd6a1c695c8b404bfde22b276186ac52a20291b.tar.xz
Davinci: iotable based ioremap() interception
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>
-rw-r--r--arch/arm/mach-davinci/da830.c7
-rw-r--r--arch/arm/mach-davinci/da850.c4
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h8
-rw-r--r--arch/arm/mach-davinci/io.c20
4 files changed, 27 insertions, 12 deletions
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 94fe971f276a..3a7a96fe7b84 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 74d4e49d4064..6b8331bf8cf3 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 2e072482c119..a57cba21e21e 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 a1c0b6b99edf..8ea60a8b2495 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);