Commit a580657a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mtd/fixes-for-4.16-rc7' of git://git.infradead.org/linux-mtd

Pull MTD fixes from Boris Brezillon:

 - Fix several problems in the fsl_ifc NAND controller driver

 - Fix misuse of mtd_ooblayout_ecc() in mtdchar.c

* tag 'mtd/fixes-for-4.16-rc7' of git://git.infradead.org/linux-mtd:
  mtd: nand: fsl_ifc: Read ECCSTAT0 and ECCSTAT1 registers for IFC 2.0
  mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0
  mtd: nand: fsl_ifc: Fix nand waitfunc return value
  mtdchar: fix usage of mtd_ooblayout_ecc()
parents 935c200a 6b00c351
...@@ -479,7 +479,7 @@ static int shrink_ecclayout(struct mtd_info *mtd, ...@@ -479,7 +479,7 @@ static int shrink_ecclayout(struct mtd_info *mtd,
for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) { for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
u32 eccpos; u32 eccpos;
ret = mtd_ooblayout_ecc(mtd, section, &oobregion); ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
if (ret < 0) { if (ret < 0) {
if (ret != -ERANGE) if (ret != -ERANGE)
return ret; return ret;
...@@ -526,7 +526,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to) ...@@ -526,7 +526,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
for (i = 0; i < ARRAY_SIZE(to->eccpos);) { for (i = 0; i < ARRAY_SIZE(to->eccpos);) {
u32 eccpos; u32 eccpos;
ret = mtd_ooblayout_ecc(mtd, section, &oobregion); ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
if (ret < 0) { if (ret < 0) {
if (ret != -ERANGE) if (ret != -ERANGE)
return ret; return ret;
......
...@@ -173,14 +173,9 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) ...@@ -173,14 +173,9 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
/* returns nonzero if entire page is blank */ /* returns nonzero if entire page is blank */
static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
u32 *eccstat, unsigned int bufnum) u32 eccstat, unsigned int bufnum)
{ {
u32 reg = eccstat[bufnum / 4]; return (eccstat >> ((3 - bufnum % 4) * 8)) & 15;
int errors;
errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
return errors;
} }
/* /*
...@@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) ...@@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
u32 eccstat[4]; u32 eccstat;
int i; int i;
/* set the chip select for NAND Transaction */ /* set the chip select for NAND Transaction */
...@@ -228,19 +223,17 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) ...@@ -228,19 +223,17 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
if (nctrl->eccread) { if (nctrl->eccread) {
int errors; int errors;
int bufnum = nctrl->page & priv->bufnum_mask; int bufnum = nctrl->page & priv->bufnum_mask;
int sector = bufnum * chip->ecc.steps; int sector_start = bufnum * chip->ecc.steps;
int sector_end = sector + chip->ecc.steps - 1; int sector_end = sector_start + chip->ecc.steps - 1;
__be32 *eccstat_regs; __be32 *eccstat_regs;
if (ctrl->version >= FSL_IFC_VERSION_2_0_0) eccstat_regs = ifc->ifc_nand.nand_eccstat;
eccstat_regs = ifc->ifc_nand.v2_nand_eccstat; eccstat = ifc_in32(&eccstat_regs[sector_start / 4]);
else
eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
for (i = sector / 4; i <= sector_end / 4; i++) for (i = sector_start; i <= sector_end; i++) {
eccstat[i] = ifc_in32(&eccstat_regs[i]); if (i != sector_start && !(i % 4))
eccstat = ifc_in32(&eccstat_regs[i / 4]);
for (i = sector; i <= sector_end; i++) {
errors = check_read_ecc(mtd, ctrl, eccstat, i); errors = check_read_ecc(mtd, ctrl, eccstat, i);
if (errors == 15) { if (errors == 15) {
...@@ -626,6 +619,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) ...@@ -626,6 +619,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
u32 nand_fsr; u32 nand_fsr;
int status;
/* Use READ_STATUS command, but wait for the device to be ready */ /* Use READ_STATUS command, but wait for the device to be ready */
ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
...@@ -640,12 +634,12 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) ...@@ -640,12 +634,12 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
fsl_ifc_run_command(mtd); fsl_ifc_run_command(mtd);
nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr); nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
status = nand_fsr >> 24;
/* /*
* The chip always seems to report that it is * The chip always seems to report that it is
* write-protected, even when it is not. * write-protected, even when it is not.
*/ */
return nand_fsr | NAND_STATUS_WP; return status | NAND_STATUS_WP;
} }
/* /*
......
...@@ -734,11 +734,7 @@ struct fsl_ifc_nand { ...@@ -734,11 +734,7 @@ struct fsl_ifc_nand {
u32 res19[0x10]; u32 res19[0x10];
__be32 nand_fsr; __be32 nand_fsr;
u32 res20; u32 res20;
/* The V1 nand_eccstat is actually 4 words that overlaps the __be32 nand_eccstat[8];
* V2 nand_eccstat.
*/
__be32 v1_nand_eccstat[2];
__be32 v2_nand_eccstat[6];
u32 res21[0x1c]; u32 res21[0x1c];
__be32 nanndcr; __be32 nanndcr;
u32 res22[0x2]; u32 res22[0x2];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment