This patch allows for a more flexible ioremap() interception. The mechanism works by translating physical addresses based on soc-specific iotable contents (davinci_soc_info.io_desc), once davinci_soc_info is populated by davinci_common_init().
This change has been tested on dm365 and dm355 by Sandeep. With additional changes (not included here), this was also tested on tnetv107x. Signed-off-by: Cyril Chemparathy <[email protected]> Tested-by: Sandeep Paulraj <[email protected]> --- arch/arm/mach-davinci/da830.c | 7 +++++- arch/arm/mach-davinci/da850.c | 9 ++++++- arch/arm/mach-davinci/include/mach/io.h | 4 +++ arch/arm/mach-davinci/io.c | 33 +++++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 122e61a..168f277 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -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; diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index d0fd756..27eb32e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -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; diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h index 62b0a90..4aa301c 100644 --- a/arch/arm/mach-davinci/include/mach/io.h +++ b/arch/arm/mach-davinci/include/mach/io.h @@ -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); diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c index a1c0b6b..3a62f14 100644 --- a/arch/arm/mach-davinci/io.c +++ b/arch/arm/mach-davinci/io.c @@ -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)); } -- 1.6.3.3 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
