diff options
author | Cyril Chemparathy <cyril@ti.com> | 2010-05-07 17:06:39 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-05-13 13:05:31 -0400 |
commit | bcd6a1c695c8b404bfde22b276186ac52a20291b (patch) | |
tree | 548f1308faa72bd90308632d16fb656718cf6090 /arch | |
parent | 779b0d53ca41873d59225eb776c5d4493a0abd0f (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-davinci/da830.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-davinci/da850.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/common.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-davinci/io.c | 20 |
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 = { | |||
1210 | 1210 | ||
1211 | void __init da830_init(void) | 1211 | void __init da830_init(void) |
1212 | { | 1212 | { |
1213 | da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); | ||
1214 | if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) | ||
1215 | return; | ||
1216 | |||
1217 | davinci_common_init(&davinci_soc_info_da830); | 1213 | davinci_common_init(&davinci_soc_info_da830); |
1214 | |||
1215 | da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); | ||
1216 | WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"); | ||
1218 | } | 1217 | } |
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) | |||
1099 | { | 1099 | { |
1100 | unsigned int v; | 1100 | unsigned int v; |
1101 | 1101 | ||
1102 | davinci_common_init(&davinci_soc_info_da850); | ||
1103 | |||
1102 | da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); | 1104 | da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); |
1103 | if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) | 1105 | if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) |
1104 | return; | 1106 | return; |
@@ -1107,8 +1109,6 @@ void __init da850_init(void) | |||
1107 | if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) | 1109 | if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) |
1108 | return; | 1110 | return; |
1109 | 1111 | ||
1110 | davinci_common_init(&davinci_soc_info_da850); | ||
1111 | |||
1112 | /* | 1112 | /* |
1113 | * Move the clock source of Async3 domain to PLL1 SYSCLK2. | 1113 | * Move the clock source of Async3 domain to PLL1 SYSCLK2. |
1114 | * This helps keeping the peripherals on this domain insulated | 1114 | * 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 { | |||
39 | 39 | ||
40 | struct davinci_gpio_controller; | 40 | struct davinci_gpio_controller; |
41 | 41 | ||
42 | /* SoC specific init support */ | 42 | /* |
43 | * SoC info passed into common davinci modules. | ||
44 | * | ||
45 | * Base addresses in this structure should be physical and not virtual. | ||
46 | * Modules that take such base addresses, should internally ioremap() them to | ||
47 | * use. | ||
48 | */ | ||
43 | struct davinci_soc_info { | 49 | struct davinci_soc_info { |
44 | struct map_desc *io_desc; | 50 | struct map_desc *io_desc; |
45 | unsigned long io_desc_num; | 51 | 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 @@ | |||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | 13 | ||
14 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
15 | #include <asm/mach/map.h> | ||
15 | 16 | ||
16 | #define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) | 17 | #include <mach/common.h> |
17 | #define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst))) | ||
18 | 18 | ||
19 | /* | 19 | /* |
20 | * Intercept ioremap() requests for addresses in our fixed mapping regions. | 20 | * Intercept ioremap() requests for addresses in our fixed mapping regions. |
21 | */ | 21 | */ |
22 | void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type) | 22 | void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type) |
23 | { | 23 | { |
24 | if (BETWEEN(p, IO_PHYS, IO_SIZE)) | 24 | struct map_desc *desc = davinci_soc_info.io_desc; |
25 | return XLATE(p, IO_PHYS, IO_VIRT); | 25 | int desc_num = davinci_soc_info.io_desc_num; |
26 | int i; | ||
26 | 27 | ||
27 | return __arm_ioremap_caller(p, size, type, __builtin_return_address(0)); | 28 | for (i = 0; i < desc_num; i++, desc++) { |
29 | unsigned long iophys = __pfn_to_phys(desc->pfn); | ||
30 | unsigned long iosize = desc->length; | ||
31 | |||
32 | if (p >= iophys && (p + size) <= (iophys + iosize)) | ||
33 | return __io(desc->virtual + p - iophys); | ||
34 | } | ||
35 | |||
36 | return __arm_ioremap_caller(p, size, type, | ||
37 | __builtin_return_address(0)); | ||
28 | } | 38 | } |
29 | EXPORT_SYMBOL(davinci_ioremap); | 39 | EXPORT_SYMBOL(davinci_ioremap); |
30 | 40 | ||