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>
This commit is contained in:
Cyril Chemparathy 2010-05-07 17:06:39 -04:00 committed by Kevin Hilman
parent 779b0d53ca
commit bcd6a1c695
4 changed files with 27 additions and 12 deletions

View File

@ -1210,9 +1210,8 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
void __init da830_init(void) 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); 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");
} }

View File

@ -1099,6 +1099,8 @@ void __init da850_init(void)
{ {
unsigned int v; unsigned int v;
davinci_common_init(&davinci_soc_info_da850);
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
return; return;
@ -1107,8 +1109,6 @@ void __init da850_init(void)
if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
return; return;
davinci_common_init(&davinci_soc_info_da850);
/* /*
* Move the clock source of Async3 domain to PLL1 SYSCLK2. * Move the clock source of Async3 domain to PLL1 SYSCLK2.
* This helps keeping the peripherals on this domain insulated * This helps keeping the peripherals on this domain insulated

View File

@ -39,7 +39,13 @@ struct davinci_timer_info {
struct davinci_gpio_controller; 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 davinci_soc_info {
struct map_desc *io_desc; struct map_desc *io_desc;
unsigned long io_desc_num; unsigned long io_desc_num;

View File

@ -12,19 +12,29 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/mach/map.h>
#define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) #include <mach/common.h>
#define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst)))
/* /*
* Intercept ioremap() requests for addresses in our fixed mapping regions. * Intercept ioremap() requests for addresses in our fixed mapping regions.
*/ */
void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type) void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
{ {
if (BETWEEN(p, IO_PHYS, IO_SIZE)) struct map_desc *desc = davinci_soc_info.io_desc;
return XLATE(p, IO_PHYS, IO_VIRT); 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); EXPORT_SYMBOL(davinci_ioremap);