Message ID | 20180301133941.19660-3-joakim.tjernlund@infinera.com |
---|---|
State | Accepted |
Delegated to: | Boris Brezillon |
Headers | show |
Series | mtd: fix AMD/Intel flash bugs | expand |
Joakim, On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund <joakim.tjernlund@infinera.com> wrote: > From: Joakim Tjernlund <joakim.tjernlund@transmode.se> > > Some Micron chips does not work well wrt Erase suspend for > boot blocks. This avoids the issue by not allowing Erase suspend > for the boot blocks for the 28F00AP30(1GBit) chip. Is this bug documented somewhere? > Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> > Cc: <stable@vger.kernel.org> > --- > drivers/mtd/chips/cfi_cmdset_0001.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c > index b59872304ae7..64ae65dab877 100644 > --- a/drivers/mtd/chips/cfi_cmdset_0001.c > +++ b/drivers/mtd/chips/cfi_cmdset_0001.c > @@ -45,6 +45,7 @@ > #define I82802AB 0x00ad > #define I82802AC 0x00ac > #define PF38F4476 0x881c > +#define M28F00AP30 0x8963 > /* STMicroelectronics chips */ > #define M50LPW080 0x002F > #define M50FLW080A 0x0080 > @@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi, > extp->MinorVersion = '1'; > } > > +static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) > +{ > + /* > + * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t > + * Erase Supend for their small Erase Blocks(0x8000) > + */ > + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) > + return 1; > + return 0; > +} > + > static inline struct cfi_pri_intelext * > read_pri_intelext(struct map_info *map, __u16 adr) > { > @@ -854,6 +866,11 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long > chip->in_progress_block_addr) > goto sleep; > > + /* do not suspend small EBs, buggy Micron Chips */ > + if (cfi_is_micron_28F00AP30(cfi, chip) && > + (chip->in_progress_block_mask == ~(0x8000-1))) > + goto sleep; > + > /* Erase suspend */ > map_write(map, CMD(0xB0), chip->in_progress_block_addr); > > -- > 2.13.6 > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/
On Wed, 2018-03-21 at 00:06 +0100, Richard Weinberger wrote: > > Joakim, > > On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund > <joakim.tjernlund@infinera.com> wrote: > > From: Joakim Tjernlund <joakim.tjernlund@transmode.se> > > > > Some Micron chips does not work well wrt Erase suspend for > > boot blocks. This avoids the issue by not allowing Erase suspend > > for the boot blocks for the 28F00AP30(1GBit) chip. > > Is this bug documented somewhere? One would hope but no. We got confirmation of the problem from the supplier though but nothing written. Jocke
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index b59872304ae7..64ae65dab877 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -45,6 +45,7 @@ #define I82802AB 0x00ad #define I82802AC 0x00ac #define PF38F4476 0x881c +#define M28F00AP30 0x8963 /* STMicroelectronics chips */ #define M50LPW080 0x002F #define M50FLW080A 0x0080 @@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi, extp->MinorVersion = '1'; } +static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) +{ + /* + * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t + * Erase Supend for their small Erase Blocks(0x8000) + */ + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) + return 1; + return 0; +} + static inline struct cfi_pri_intelext * read_pri_intelext(struct map_info *map, __u16 adr) { @@ -854,6 +866,11 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long chip->in_progress_block_addr) goto sleep; + /* do not suspend small EBs, buggy Micron Chips */ + if (cfi_is_micron_28F00AP30(cfi, chip) && + (chip->in_progress_block_mask == ~(0x8000-1))) + goto sleep; + /* Erase suspend */ map_write(map, CMD(0xB0), chip->in_progress_block_addr);