Cyril Chemparathy <[email protected]> writes:
> 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]>
Hmm, I don't like having a special class of ioremap without a *very*
well defined structure for when to use and not to use.
I'd rather just see the iotable stuff pulled out of _common_init()
and put into its own function that can be called early.
Kevin
> ---
> 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