struct atmel_nand *nand = to_atmel_nand(chip);
        int ret;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        ret = atmel_nand_pmecc_enable(chip, NAND_ECC_WRITE, raw);
        if (ret)
                return ret;
 
        atmel_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
        struct mtd_info *mtd = nand_to_mtd(chip);
        int ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        ret = atmel_nand_pmecc_enable(chip, NAND_ECC_READ, raw);
        if (ret)
                return ret;
        chip->ecc.write_page = atmel_hsmc_nand_pmecc_write_page;
        chip->ecc.read_page_raw = atmel_hsmc_nand_pmecc_read_page_raw;
        chip->ecc.write_page_raw = atmel_hsmc_nand_pmecc_write_page_raw;
-       chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS;
 
        return 0;
 }
 
 static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                uint8_t *buf, int oob_required, int page)
 {
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
        bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
                struct nand_chip *chip, const uint8_t *buf, int oob_required,
                int page)
 {
-       bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 /*
 
        sas = mtd->oobsize / chip->ecc.steps;
 
        /* read without ecc for verification */
-       nand_read_page_op(chip, page, 0, NULL, 0);
        ret = chip->ecc.read_page_raw(mtd, chip, buf, true, page);
        if (ret)
                return ret;
        struct brcmnand_host *host = nand_get_controller_data(chip);
        u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        return brcmnand_read(mtd, chip, host->last_addr,
                        mtd->writesize >> FC_SHIFT, (u32 *)buf, oob);
 }
        u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL;
        int ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        brcmnand_set_ecc_enabled(host, 0);
        ret = brcmnand_read(mtd, chip, host->last_addr,
                        mtd->writesize >> FC_SHIFT, (u32 *)buf, oob);
        struct brcmnand_host *host = nand_get_controller_data(chip);
        void *oob = oob_required ? chip->oob_poi : NULL;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
        brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob);
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 static int brcmnand_write_page_raw(struct mtd_info *mtd,
        struct brcmnand_host *host = nand_get_controller_data(chip);
        void *oob = oob_required ? chip->oob_poi : NULL;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
        brcmnand_set_ecc_enabled(host, 0);
        brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob);
        brcmnand_set_ecc_enabled(host, 1);
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 static int brcmnand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 
                     cafe_readl(cafe, NAND_ECC_RESULT),
                     cafe_readl(cafe, NAND_ECC_SYN01));
 
-       chip->read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
        if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) {
 {
        struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-       chip->write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
        /* Set up ECC autogeneration */
        cafe->ctl2 |= (1<<30);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs)
 
                chip->read_buf = denali_read_buf;
                chip->write_buf = denali_write_buf;
        }
-       chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS;
        chip->ecc.read_page = denali_read_page;
        chip->ecc.read_page_raw = denali_read_page_raw;
        chip->ecc.write_page = denali_write_page;
 
 
        dev_dbg(doc->dev, "%s: page %08x\n", __func__, page);
 
+       nand_read_page_op(nand, page, 0, NULL, 0);
+
        writew(DOC_ECCCONF0_READ_MODE |
               DOC_ECCCONF0_ECC_ENABLE |
               DOC_ECCCONF0_UNKNOWN |
 }
 
 static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
-                      const uint8_t *buf, bool use_ecc)
+                     const uint8_t *buf, int page, bool use_ecc)
 {
        struct docg4_priv *doc = nand_get_controller_data(nand);
        void __iomem *docptr = doc->virtadr;
 
        dev_dbg(doc->dev, "%s...\n", __func__);
 
+       nand_prog_page_begin_op(nand, page, 0, NULL, 0);
+
        writew(DOC_ECCCONF0_ECC_ENABLE |
               DOC_ECCCONF0_UNKNOWN |
               DOCG4_BCH_SIZE,
        writew(0, docptr + DOC_DATAEND);
        write_nop(docptr);
 
-       return 0;
+       return nand_prog_page_end_op(nand);
 }
 
 static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
                                const uint8_t *buf, int oob_required, int page)
 {
-       return write_page(mtd, nand, buf, false);
+       return write_page(mtd, nand, buf, page, false);
 }
 
 static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
                             const uint8_t *buf, int oob_required, int page)
 {
-       return write_page(mtd, nand, buf, true);
+       return write_page(mtd, nand, buf, page, true);
 }
 
 static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
 
        struct fsl_lbc_ctrl *ctrl = priv->ctrl;
        struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
 
-       fsl_elbc_read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        if (oob_required)
                fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                                const uint8_t *buf, int oob_required, int page)
 {
-       fsl_elbc_write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 /* ECC will be calculated automatically, and errors will be detected in
                                uint32_t offset, uint32_t data_len,
                                const uint8_t *buf, int oob_required, int page)
 {
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
        fsl_elbc_write_buf(mtd, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
        struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
 
-       fsl_ifc_read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        if (oob_required)
                fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                               const uint8_t *buf, int oob_required, int page)
 {
-       fsl_ifc_write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
 
        unsigned int  max_bitflips = 0;
        int           ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        dev_dbg(this->dev, "page number is : %d\n", page);
        ret = read_page_prepare(this, buf, nfc_geo->payload_size,
                                        this->payload_virt, this->payload_phys,
        meta = geo->metadata_size;
        if (first) {
                col = meta + (size + ecc_parity_size) * first;
-               nand_change_read_column_op(chip, col, NULL, 0, false);
-
                meta = 0;
                buf = buf + first * size;
        }
 
+       nand_read_page_op(chip, page, col, NULL, 0);
+
        /* Save the old environment */
        r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
        r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
        int        ret;
 
        dev_dbg(this->dev, "ecc write page.\n");
+
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        if (this->swap_block_mark) {
                /*
                 * If control arrives here, we're doing block mark swapping.
                                payload_virt, payload_phys);
        }
 
-       return 0;
+       if (ret)
+               return ret;
+
+       return nand_prog_page_end_op(chip);
 }
 
 /*
        uint8_t *oob = chip->oob_poi;
        int step;
 
-       chip->read_buf(mtd, tmp_buf,
-                      mtd->writesize + mtd->oobsize);
+       nand_read_page_op(chip, page, 0, tmp_buf,
+                         mtd->writesize + mtd->oobsize);
 
        /*
         * If required, swap the bad block marker and the data stored in the
        if (this->swap_block_mark)
                swap(tmp_buf[0], tmp_buf[mtd->writesize]);
 
-       chip->write_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize);
-
-       return 0;
+       return nand_prog_page_op(chip, page, 0, tmp_buf,
+                                mtd->writesize + mtd->oobsize);
 }
 
 static int gpmi_ecc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
                                 int page)
 {
-       nand_read_page_op(chip, page, 0, NULL, 0);
-
        return gpmi_ecc_read_page_raw(mtd, chip, NULL, 1, page);
 }
 
 static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
                                 int page)
 {
-       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-
        return gpmi_ecc_write_page_raw(mtd, chip, NULL, 1, page);
 }
 
                /* Write the first page of the current stride. */
                dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
 
-               nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-               chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
-               status = nand_prog_page_end_op(chip);
+               status = chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
                if (status)
                        dev_err(dev, "[%s] Write failed.\n", __func__);
        }
 
        int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc;
        int stat_1, stat_2;
 
-       chip->read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
        /* errors which can not be corrected by ECC */
                struct nand_chip *chip, const uint8_t *buf, int oob_required,
                int page)
 {
-       chip->write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        if (oob_required)
                chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static void hisi_nfc_host_init(struct hinfc_host *host)
 
                memcpy(dma_buf, buf, mtd->writesize);
        }
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        for (i = 0; i < host->mlcsubpages; i++) {
                /* Start Encode */
                writeb(0x00, MLC_ECC_ENC_REG(host->io_base));
                /* Wait for Controller Ready */
                lpc32xx_waitfunc_controller(mtd, chip);
        }
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 
        uint8_t *pb;
        int error;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        /* Write data, calculate ECC on outbound data */
        error = lpc32xx_xfer(mtd, (uint8_t *)buf, chip->ecc.steps, 0);
        if (error)
 
        /* Write ECC data to device */
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 /*
                                                int oob_required, int page)
 {
        /* Raw writes can just use the FIFO interface */
-       chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+       nand_prog_page_begin_op(chip, page, 0, buf,
+                               chip->ecc.size * chip->ecc.steps);
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host)
 
        u32 reg;
        int ret;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        if (!raw) {
                /* OOB => FDM: from register,  ECC: from HW */
                reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN;
        if (!raw)
                mtk_ecc_disable(nfc->ecc);
 
-       return ret;
+       if (ret)
+               return ret;
+
+       return nand_prog_page_end_op(chip);
 }
 
 static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd,
 static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                                 int page)
 {
-       int ret;
-
-       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-
-       ret = mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page);
-       if (ret < 0)
-               return -EIO;
-
-       return nand_prog_page_end_op(chip);
+       return mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page);
 }
 
 static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors)
        len = sectors * chip->ecc.size + (raw ? sectors * spare : 0);
        buf = bufpoi + start * chip->ecc.size;
 
-       if (column != 0)
-               nand_change_read_column_op(chip, column, NULL, 0, false);
+       nand_read_page_op(chip, page, column, NULL, 0);
 
        addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE);
        rc = dma_mapping_error(nfc->dev, addr);
 static int mtk_nfc_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                                int page)
 {
-       nand_read_page_op(chip, page, 0, NULL, 0);
-
        return mtk_nfc_read_page_raw(mtd, chip, NULL, 1, page);
 }
 
 
 {
        int ret;
 
-       ret = nand_read_data_op(chip, buf, mtd->writesize, false);
+       ret = nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        if (ret)
                return ret;
 
        uint8_t *oob = chip->oob_poi;
        int steps, size, ret;
 
+       ret = nand_read_page_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (steps = chip->ecc.steps; steps > 0; steps--) {
                ret = nand_read_data_op(chip, buf, eccsize, false);
                if (ret)
 
        data_col_addr = start_step * chip->ecc.size;
        /* If we read not a page aligned data */
-       if (data_col_addr != 0)
-               chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
-
        p = bufpoi + data_col_addr;
-       ret = nand_read_data_op(chip, p, datafrag_len, false);
+       ret = nand_read_page_op(chip, page, data_col_addr, p, datafrag_len);
        if (ret)
                return ret;
 
        uint8_t *ecc_code = chip->buffers->ecccode;
        unsigned int max_bitflips = 0;
 
+       ret = nand_read_page_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                chip->ecc.hwctl(mtd, NAND_ECC_READ);
 
        uint8_t *oob = chip->oob_poi;
        unsigned int max_bitflips = 0;
 
+       ret = nand_read_page_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                int stat;
 
                                                 __func__, buf);
 
 read_retry:
-                       if (nand_standard_page_accessors(&chip->ecc)) {
-                               ret = nand_read_page_op(chip, page, 0, NULL, 0);
-                               if (ret)
-                                       break;
-                       }
-
                        /*
                         * Now read the page into the buffer.  Absent an error,
                         * the read methods return max bitflips per ecc step.
 {
        int ret;
 
-       ret = nand_write_data_op(chip, buf, mtd->writesize, false);
+       ret = nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        if (ret)
                return ret;
 
                        return ret;
        }
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 EXPORT_SYMBOL(nand_write_page_raw);
 
        uint8_t *oob = chip->oob_poi;
        int steps, size, ret;
 
+       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (steps = chip->ecc.steps; steps > 0; steps--) {
                ret = nand_write_data_op(chip, buf, eccsize, false);
                if (ret)
                        return ret;
        }
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 /**
  * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
        uint8_t *ecc_calc = chip->buffers->ecccalc;
        const uint8_t *p = buf;
 
+       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
 
        if (ret)
                return ret;
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 
        int oob_bytes       = mtd->oobsize / ecc_steps;
        int step, ret;
 
+       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (step = 0; step < ecc_steps; step++) {
                /* configure controller for WRITE access */
                chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
        if (ret)
                return ret;
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 
        uint8_t *oob = chip->oob_poi;
        int ret;
 
+       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+       if (ret)
+               return ret;
+
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
 
                        return ret;
        }
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 /**
        else
                subpage = 0;
 
-       if (nand_standard_page_accessors(&chip->ecc)) {
-               status = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-               if (status)
-                       return status;
-       }
-
        if (unlikely(raw))
                status = chip->ecc.write_page_raw(mtd, chip, buf,
                                                  oob_required, page);
        if (status < 0)
                return status;
 
-       if (nand_standard_page_accessors(&chip->ecc))
-               return nand_prog_page_end_op(chip);
-
        return 0;
 }
 
        return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
 }
 
-static bool invalid_ecc_page_accessors(struct nand_chip *chip)
-{
-       struct nand_ecc_ctrl *ecc = &chip->ecc;
-
-       if (nand_standard_page_accessors(ecc))
-               return false;
-
-       /*
-        * NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND
-        * controller driver implements all the page accessors because
-        * default helpers are not suitable when the core does not
-        * send the READ0/PAGEPROG commands.
-        */
-       return (!ecc->read_page || !ecc->write_page ||
-               !ecc->read_page_raw || !ecc->write_page_raw ||
-               (NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) ||
-               (NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage &&
-                ecc->hwctl && ecc->calculate));
-}
-
 /**
  * nand_scan_tail - [NAND Interface] Scan for the NAND device
  * @mtd: MTD device structure
                return -EINVAL;
        }
 
-       if (invalid_ecc_page_accessors(chip)) {
-               pr_err("Invalid ECC page accessors setup\n");
-               return -EINVAL;
-       }
-
        if (!(chip->options & NAND_OWN_BUFFERS)) {
                nbuf = kzalloc(sizeof(*nbuf), GFP_KERNEL);
                if (!nbuf)
 
        else if (status & NAND_STATUS_WRITE_RECOMMENDED)
                max_bitflips = chip->ecc.strength;
 
-       ret = nand_read_page_raw(mtd, chip, buf, oob_required, page);
+       ret = nand_read_data_op(chip, buf, mtd->writesize, false);
+       if (!ret && oob_required)
+               ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
+                                       false);
 
 out:
        micron_nand_on_die_ecc_setup(chip, false);
        if (ret)
                return ret;
 
-       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-       if (ret)
-               goto out;
-
        ret = nand_write_page_raw(mtd, chip, buf, oob_required, page);
-       if (ret)
-               return ret;
-
-       ret = nand_prog_page_end_op(chip);
-
-out:
        micron_nand_on_die_ecc_setup(chip, false);
 
        return ret;
 }
 
-static int
-micron_nand_read_page_raw_on_die_ecc(struct mtd_info *mtd,
-                                    struct nand_chip *chip,
-                                    uint8_t *buf, int oob_required,
-                                    int page)
-{
-       int ret;
-
-       ret = nand_read_page_op(chip, page, 0, NULL, 0);
-       if (ret)
-               return ret;
-
-       return nand_read_page_raw(mtd, chip, buf, oob_required, page);
-}
-
-static int
-micron_nand_write_page_raw_on_die_ecc(struct mtd_info *mtd,
-                                     struct nand_chip *chip,
-                                     const uint8_t *buf, int oob_required,
-                                     int page)
-{
-       int ret;
-
-       ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-       if (ret)
-               return ret;
-
-       ret = nand_write_page_raw(mtd, chip, buf, oob_required, page);
-       if (ret)
-               return ret;
-
-       return nand_prog_page_end_op(chip);
-}
-
 enum {
        /* The NAND flash doesn't support on-die ECC */
        MICRON_ON_DIE_UNSUPPORTED,
                        return -EINVAL;
                }
 
-               chip->ecc.options = NAND_ECC_CUSTOM_PAGE_ACCESS;
                chip->ecc.bytes = 8;
                chip->ecc.size = 512;
                chip->ecc.strength = 4;
                chip->ecc.algo = NAND_ECC_BCH;
                chip->ecc.read_page = micron_nand_read_page_on_die_ecc;
                chip->ecc.write_page = micron_nand_write_page_on_die_ecc;
-               chip->ecc.read_page_raw =
-                       micron_nand_read_page_raw_on_die_ecc;
-               chip->ecc.write_page_raw =
-                       micron_nand_write_page_raw_on_die_ecc;
+               chip->ecc.read_page_raw = nand_read_page_raw;
+               chip->ecc.write_page_raw = nand_write_page_raw;
 
                mtd_set_ooblayout(mtd, µn_nand_on_die_ooblayout_ops);
        }
 
        int ret;
        uint8_t *ecc_calc = chip->buffers->ecccalc;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        /* Enable GPMC ecc engine */
        chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
 
 
        /* Write ecc vector to OOB area */
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-       return 0;
+
+       return nand_prog_page_end_op(chip);
 }
 
 /**
         * ECC is calculated for all subpages but we choose
         * only what we want.
         */
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 
        /* Enable GPMC ECC engine */
        chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
        /* write OOB buffer to NAND device */
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 /**
        int stat, ret;
        unsigned int max_bitflips = 0;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        /* Enable GPMC ecc engine */
        chip->ecc.hwctl(mtd, NAND_ECC_READ);
 
 
                struct nand_chip *chip, const uint8_t *buf, int oob_required,
                int page)
 {
-       chip->write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
        struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
        struct pxa3xx_nand_info *info = host->info_data;
 
-       chip->read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
        if (info->retcode == ERR_CORERR && info->use_ecc) {
 
        u8 *data_buf, *oob_buf = NULL;
        int ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
        data_buf = buf;
        oob_buf = oob_required ? chip->oob_poi : NULL;
 
        int i, ret;
        int read_loc;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
        data_buf = buf;
        oob_buf = chip->oob_poi;
 
        u8 *data_buf, *oob_buf;
        int i, ret;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        clear_read_regs(nandc);
        clear_bam_transaction(nandc);
 
 
        free_descs(nandc);
 
+       if (!ret)
+               ret = nand_prog_page_end_op(chip);
+
        return ret;
 }
 
        u8 *data_buf, *oob_buf;
        int i, ret;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
        clear_read_regs(nandc);
        clear_bam_transaction(nandc);
 
 
        free_descs(nandc);
 
+       if (!ret)
+               ret = nand_prog_page_end_op(chip);
+
        return ret;
 }
 
 
 static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int oob_required, int page)
 {
-       chip->read_buf(mtd, buf, mtd->writesize);
+       nand_read_page_op(chip, page, 0, buf, mtd->writesize);
        if (oob_required)
                chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
        return 0;
                                  const uint8_t *buf, int oob_required,
                                  int page)
 {
-       chip->write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
 
        int ret, i, cur_off = 0;
        bool raw_mode = false;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = 0; i < ecc->steps; i++) {
 {
        int ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, oob_required, page,
                                               chip->ecc.steps);
        if (ret >= 0)
                return ret;
 
        /* Fallback to PIO mode */
-       nand_change_read_column_op(chip, 0, NULL, 0, false);
-
        return sunxi_nfc_hw_ecc_read_page(mtd, chip, buf, oob_required, page);
 }
 
        int ret, i, cur_off = 0;
        unsigned int max_bitflips = 0;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = data_offs / ecc->size;
        int nchunks = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size);
        int ret;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        ret = sunxi_nfc_hw_ecc_read_chunks_dma(mtd, buf, false, page, nchunks);
        if (ret >= 0)
                return ret;
 
        /* Fallback to PIO mode */
-       nand_change_read_column_op(chip, 0, NULL, 0, false);
-
        return sunxi_nfc_hw_ecc_read_subpage(mtd, chip, data_offs, readlen,
                                             buf, page);
 }
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int ret, i, cur_off = 0;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = 0; i < ecc->steps; i++) {
 
        sunxi_nfc_hw_ecc_disable(mtd);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int sunxi_nfc_hw_ecc_write_subpage(struct mtd_info *mtd,
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int ret, i, cur_off = 0;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = data_offs / ecc->size;
 
        sunxi_nfc_hw_ecc_disable(mtd);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int sunxi_nfc_hw_ecc_write_page_dma(struct mtd_info *mtd,
                sunxi_nfc_hw_ecc_set_prot_oob_bytes(mtd, oob, i, !i, page);
        }
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
        sunxi_nfc_randomizer_config(mtd, page, false);
        sunxi_nfc_randomizer_enable(mtd);
                sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
                                                 NULL, page);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 
 pio_fallback:
        return sunxi_nfc_hw_ecc_write_page(mtd, chip, buf, oob_required, page);
        int ret, i, cur_off = 0;
        bool raw_mode = false;
 
+       nand_read_page_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = 0; i < ecc->steps; i++) {
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int ret, i, cur_off = 0;
 
+       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
        sunxi_nfc_hw_ecc_enable(mtd);
 
        for (i = 0; i < ecc->steps; i++) {
 
        sunxi_nfc_hw_ecc_disable(mtd);
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
                                            struct nand_chip *chip,
                                            int page)
 {
-       nand_read_page_op(chip, page, 0, NULL, 0);
-
        chip->pagebuf = -1;
 
        return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page);
 {
        int ret;
 
-       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-
        chip->pagebuf = -1;
 
        memset(chip->buffers->databuf, 0xff, mtd->writesize);
 
        ecc->write_page = tango_write_page;
        ecc->read_oob = tango_read_oob;
        ecc->write_oob = tango_write_oob;
-       ecc->options = NAND_ECC_CUSTOM_PAGE_ACCESS;
 
        err = nand_scan_tail(mtd);
        if (err)
 
        int eccsize = chip->ecc.size;
        int stat;
 
-       vf610_nfc_read_buf(mtd, buf, eccsize);
+       nand_read_page_op(chip, page, 0, buf, eccsize);
        if (oob_required)
                vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 {
        struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 
-       vf610_nfc_write_buf(mtd, buf, mtd->writesize);
+       nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
        if (oob_required)
                vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
        nfc->use_hw_ecc = true;
        nfc->write_sz = mtd->writesize + mtd->oobsize;
 
-       return 0;
+       return nand_prog_page_end_op(chip);
 }
 
 static const struct of_device_id vf610_nfc_dt_ids[] = {
 
        int eccsteps = chip->ecc.steps;
 
        enable_hw_ecc = 1;
-       chip->write_buf(mtd, p, eccsize * eccsteps);
-       return 0;
+       return nand_prog_page_op(chip, page, 0, p, eccsize * eccsteps);
 }
 
 static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 
        enable_read_hw_ecc = 1;
 
-       chip->read_buf(mtd, p, eccsize * eccsteps);
+       nand_read_page_op(chip, page, 0, p, eccsize * eccsteps);
        if (oob_required)
                chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 
  */
 #define NAND_ECC_GENERIC_ERASED_CHECK  BIT(0)
 #define NAND_ECC_MAXIMIZE              BIT(1)
-/*
- * If your controller already sends the required NAND commands when
- * reading or writing a page, then the framework is not supposed to
- * send READ0 and SEQIN/PAGEPROG respectively.
- */
-#define NAND_ECC_CUSTOM_PAGE_ACCESS    BIT(2)
 
 /* Bit mask for flags passed to do_nand_read_ecc */
 #define NAND_GET_DEVICE                0x80
                        int page);
 };
 
-static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc)
-{
-       return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS);
-}
-
 /**
  * struct nand_buffers - buffer structure for read/write
  * @ecccalc:   buffer pointer for calculated ECC, size is oobsize.