diff options
author | Lan Chunhe-B25806 <b25806@freescale.com> | 2010-10-18 03:22:32 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-25 10:41:04 -0400 |
commit | 0b824d2b10eacd496c608a7c41a046862d48563b (patch) | |
tree | 7322d0b478f1ece6312980b77a5313639cf73d13 | |
parent | 3ab8f2a2e7011c5e83363b42950757e46ef06824 (diff) |
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>
-rw-r--r-- | arch/powerpc/include/asm/fsl_lbc.h | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_lbc.c | 23 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 2 |
3 files changed, 24 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h index 06a11124dde1..5c1bf3466749 100644 --- a/arch/powerpc/include/asm/fsl_lbc.h +++ b/arch/powerpc/include/asm/fsl_lbc.h | |||
@@ -248,6 +248,7 @@ struct fsl_upm { | |||
248 | int width; | 248 | int width; |
249 | }; | 249 | }; |
250 | 250 | ||
251 | extern u32 fsl_lbc_addr(phys_addr_t addr_base); | ||
251 | extern int fsl_lbc_find(phys_addr_t addr_base); | 252 | extern int fsl_lbc_find(phys_addr_t addr_base); |
252 | extern int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm); | 253 | extern int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm); |
253 | 254 | ||
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 91c9c53b1845..4fcb5a4e60dd 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; | |||
34 | EXPORT_SYMBOL(fsl_lbc_ctrl_dev); | 34 | EXPORT_SYMBOL(fsl_lbc_ctrl_dev); |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * fsl_lbc_addr - convert the base address | ||
38 | * @addr_base: base address of the memory bank | ||
39 | * | ||
40 | * This function converts a base address of lbc into the right format for the | ||
41 | * BR register. If the SOC has eLBC then it returns 32bit physical address | ||
42 | * else it convers a 34bit local bus physical address to correct format of | ||
43 | * 32bit address for BR register (Example: MPC8641). | ||
44 | */ | ||
45 | u32 fsl_lbc_addr(phys_addr_t addr_base) | ||
46 | { | ||
47 | struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node; | ||
48 | u32 addr = addr_base & 0xffff8000; | ||
49 | |||
50 | if (of_device_is_compatible(np, "fsl,elbc")) | ||
51 | return addr; | ||
52 | |||
53 | return addr | ((addr_base & 0x300000000ull) >> 19); | ||
54 | } | ||
55 | EXPORT_SYMBOL(fsl_lbc_addr); | ||
56 | |||
57 | /** | ||
37 | * fsl_lbc_find - find Localbus bank | 58 | * fsl_lbc_find - find Localbus bank |
38 | * @addr_base: base address of the memory bank | 59 | * @addr_base: base address of the memory bank |
39 | * | 60 | * |
@@ -55,7 +76,7 @@ int fsl_lbc_find(phys_addr_t addr_base) | |||
55 | __be32 br = in_be32(&lbc->bank[i].br); | 76 | __be32 br = in_be32(&lbc->bank[i].br); |
56 | __be32 or = in_be32(&lbc->bank[i].or); | 77 | __be32 or = in_be32(&lbc->bank[i].or); |
57 | 78 | ||
58 | if (br & BR_V && (br & or & BR_BA) == addr_base) | 79 | if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base)) |
59 | return i; | 80 | return i; |
60 | } | 81 | } |
61 | 82 | ||
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index cd8de29e38cc..c141b07b25d1 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -868,7 +868,7 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) | |||
868 | (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM && | 868 | (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM && |
869 | (in_be32(&lbc->bank[bank].br) & | 869 | (in_be32(&lbc->bank[bank].br) & |
870 | in_be32(&lbc->bank[bank].or) & BR_BA) | 870 | in_be32(&lbc->bank[bank].or) & BR_BA) |
871 | == res.start) | 871 | == fsl_lbc_addr(res.start)) |
872 | break; | 872 | break; |
873 | 873 | ||
874 | if (bank >= MAX_BANKS) { | 874 | if (bank >= MAX_BANKS) { |