diff options
author | Lan Chunhe-B25806 <b25806@freescale.com> | 2010-10-18 07:22:32 (GMT) |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-25 14:41:04 (GMT) |
commit | 0b824d2b10eacd496c608a7c41a046862d48563b (patch) | |
tree | 7322d0b478f1ece6312980b77a5313639cf73d13 /arch | |
parent | 3ab8f2a2e7011c5e83363b42950757e46ef06824 (diff) | |
download | linux-0b824d2b10eacd496c608a7c41a046862d48563b.tar.xz |
P4080/mtd: Fix the freescale lbc issue with 36bit mode
When system uses 36bit physical address, res.start is 36bit
physical address. But the function of in_be32 returns 32bit
physical address. Then both of them compared each other is
wrong. So by converting the address of res.start into
the right format fixes this issue.
Signed-off-by: Lan Chunhe-B25806 <b25806@freescale.com>
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
Reviewed-by: Anton Vorontsov <cbouatmailru@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/fsl_lbc.h | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_lbc.c | 23 |
2 files changed, 23 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h index 06a1112..5c1bf34 100644 --- a/arch/powerpc/include/asm/fsl_lbc.h +++ b/arch/powerpc/include/asm/fsl_lbc.h @@ -248,6 +248,7 @@ struct fsl_upm { int width; }; +extern u32 fsl_lbc_addr(phys_addr_t addr_base); extern int fsl_lbc_find(phys_addr_t addr_base); extern int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm); diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 91c9c53..4fcb5a4 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -34,6 +34,27 @@ struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev; EXPORT_SYMBOL(fsl_lbc_ctrl_dev); /** + * fsl_lbc_addr - convert the base address + * @addr_base: base address of the memory bank + * + * This function converts a base address of lbc into the right format for the + * BR register. If the SOC has eLBC then it returns 32bit physical address + * else it convers a 34bit local bus physical address to correct format of + * 32bit address for BR register (Example: MPC8641). + */ +u32 fsl_lbc_addr(phys_addr_t addr_base) +{ + struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node; + u32 addr = addr_base & 0xffff8000; + + if (of_device_is_compatible(np, "fsl,elbc")) + return addr; + + return addr | ((addr_base & 0x300000000ull) >> 19); +} +EXPORT_SYMBOL(fsl_lbc_addr); + +/** * fsl_lbc_find - find Localbus bank * @addr_base: base address of the memory bank * @@ -55,7 +76,7 @@ int fsl_lbc_find(phys_addr_t addr_base) __be32 br = in_be32(&lbc->bank[i].br); __be32 or = in_be32(&lbc->bank[i].or); - if (br & BR_V && (br & or & BR_BA) == addr_base) + if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base)) return i; } |