Patchwork [3/3,v3] P4080/mtd: Fix the freescale lbc issue with 36bit mode

login
register
mail settings
Submitter Zang Roy-R61911
Date Sept. 16, 2010, 6:41 a.m.
Message ID <1284619284-23614-3-git-send-email-tie-fei.zang@freescale.com>
Download mbox | patch
Permalink /patch/64944/
State New
Headers show

Comments

Zang Roy-R61911 - Sept. 16, 2010, 6:41 a.m.
From: Lan Chunhe-B25806 <b25806@freescale.com>

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>
---
 arch/powerpc/include/asm/fsl_lbc.h |    1 +
 arch/powerpc/sysdev/fsl_lbc.c      |   23 ++++++++++++++++++++++-
 drivers/mtd/nand/fsl_elbc_nand.c   |    2 +-
 3 files changed, 24 insertions(+), 2 deletions(-)
Anton Vorontsov - Sept. 16, 2010, 7:31 a.m.
On Thu, Sep 16, 2010 at 02:41:24PM +0800, Roy Zang wrote:
> From: Lan Chunhe-B25806 <b25806@freescale.com>
> 
> 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>
> ---
>  arch/powerpc/include/asm/fsl_lbc.h |    1 +
>  arch/powerpc/sysdev/fsl_lbc.c      |   23 ++++++++++++++++++++++-
>  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 db94698..5638b1e 100644
> --- a/arch/powerpc/include/asm/fsl_lbc.h
> +++ b/arch/powerpc/include/asm/fsl_lbc.h
> @@ -246,6 +246,7 @@ struct fsl_upm {
>  	int width;
>  };
>  
> +extern unsigned int fsl_lbc_addr(phys_addr_t addr_base);

u32 here.

Other than that, the patch looks good.

Reviewed-by: Anton Vorontsov <cbouatmailru@gmail.com>

Thanks!
Zang Roy-R61911 - Sept. 16, 2010, 7:36 a.m.
> -----Original Message-----
> From: Anton Vorontsov [mailto:cbouatmailru@gmail.com]
> Sent: Thursday, September 16, 2010 15:32 PM
> To: Zang Roy-R61911
> Cc: linux-mtd@lists.infradead.org; dwmw2@infradead.org; dedekind1@gmail.com;
> akpm@linux-foundation.org; Lan Chunhe-B25806; Wood Scott-B07421; Gala Kumar-
> B11780; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 3/3 v3] P4080/mtd: Fix the freescale lbc issue with 36bit
> mode
> 
> On Thu, Sep 16, 2010 at 02:41:24PM +0800, Roy Zang wrote:
> > From: Lan Chunhe-B25806 <b25806@freescale.com>
> >
> > 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>
> > ---
> >  arch/powerpc/include/asm/fsl_lbc.h |    1 +
> >  arch/powerpc/sysdev/fsl_lbc.c      |   23 ++++++++++++++++++++++-
> >  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 db94698..5638b1e 100644
> > --- a/arch/powerpc/include/asm/fsl_lbc.h
> > +++ b/arch/powerpc/include/asm/fsl_lbc.h
> > @@ -246,6 +246,7 @@ struct fsl_upm {
> >  	int width;
> >  };
> >
> > +extern unsigned int fsl_lbc_addr(phys_addr_t addr_base);
> 
> u32 here.
> 
> Other than that, the patch looks good.
> 
> Reviewed-by: Anton Vorontsov <cbouatmailru@gmail.com>
I will correct this together with previous patches.
Do you have any more comments for the previous two patches?
Thanks.
Roy

Patch

diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h
index db94698..5638b1e 100644
--- a/arch/powerpc/include/asm/fsl_lbc.h
+++ b/arch/powerpc/include/asm/fsl_lbc.h
@@ -246,6 +246,7 @@  struct fsl_upm {
 	int width;
 };
 
+extern unsigned int 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 edd6d95..8a835ef 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;
 	}
 
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 91c5c05..85858e3 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -865,7 +865,7 @@  static int __devinit fsl_elbc_nand_probe(struct platform_device *dev)
 		    (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM &&
 		    (in_be32(&lbc->bank[bank].br) &
 		     in_be32(&lbc->bank[bank].or) & BR_BA)
-		     == res.start)
+		     == fsl_lbc_addr(res.start))
 			break;
 
 	if (bank >= MAX_BANKS) {