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,
for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
u32 eccpos;
ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
if (ret < 0) {
if (ret != -ERANGE)
return ret;
......@@ -526,7 +526,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
for (i = 0; i < ARRAY_SIZE(to->eccpos);) {
u32 eccpos;
ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
if (ret < 0) {
if (ret != -ERANGE)
return ret;
......
......@@ -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 */
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];
int errors;
errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
return errors;
return (eccstat >> ((3 - bufnum % 4) * 8)) & 15;
}
/*
......@@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
u32 eccstat[4];
u32 eccstat;
int i;
/* set the chip select for NAND Transaction */
......@@ -228,19 +223,17 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
if (nctrl->eccread) {
int errors;
int bufnum = nctrl->page & priv->bufnum_mask;
int sector = bufnum * chip->ecc.steps;
int sector_end = sector + chip->ecc.steps - 1;
int sector_start = bufnum * chip->ecc.steps;
int sector_end = sector_start + chip->ecc.steps - 1;
__be32 *eccstat_regs;
if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
eccstat_regs = ifc->ifc_nand.v2_nand_eccstat;
else
eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
eccstat_regs = ifc->ifc_nand.nand_eccstat;
eccstat = ifc_in32(&eccstat_regs[sector_start / 4]);
for (i = sector / 4; i <= sector_end / 4; i++)
eccstat[i] = ifc_in32(&eccstat_regs[i]);
for (i = sector_start; i <= sector_end; 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);
if (errors == 15) {
......@@ -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_runtime __iomem *ifc = ctrl->rregs;
u32 nand_fsr;
int status;
/* Use READ_STATUS command, but wait for the device to be ready */
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)
fsl_ifc_run_command(mtd);
nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
status = nand_fsr >> 24;
/*
* The chip always seems to report that it is
* 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 {
u32 res19[0x10];
__be32 nand_fsr;
u32 res20;
/* The V1 nand_eccstat is actually 4 words that overlaps the
* V2 nand_eccstat.
*/
__be32 v1_nand_eccstat[2];
__be32 v2_nand_eccstat[6];
__be32 nand_eccstat[8];
u32 res21[0x1c];
__be32 nanndcr;
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