X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fnand%2Ffsl_elbc_nand.c;h=fc3720b3bd110c18cfec3faeb5959b6bf1ac9e41;hb=f7c9e76fb85369aa6a347201b04ad8c676c42665;hp=3372b64212559cf1c9c922ec1a0f22cbea1d3c32;hpb=1454ba8e56d88a8b95ac8050cde2c07c651cd0ae;p=u-boot diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 3372b64212..fc3720b3bd 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -13,11 +13,11 @@ #include #include -#include +#include #include #include -#include +#include #ifdef VERBOSE_DEBUG #define DEBUG_ELBC @@ -154,8 +154,8 @@ static struct nand_bbt_descr bbt_mirror_descr = { */ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; fsl_lbc_t *lbc = ctrl->regs; int buf_num; @@ -194,8 +194,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) */ static int fsl_elbc_run_command(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; fsl_lbc_t *lbc = ctrl->regs; u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; @@ -246,7 +246,7 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) static void fsl_elbc_do_read(struct nand_chip *chip, int oob) { - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; fsl_lbc_t *lbc = ctrl->regs; @@ -279,8 +279,8 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob) static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; fsl_lbc_t *lbc = ctrl->regs; @@ -489,8 +489,8 @@ static void fsl_elbc_select_chip(struct mtd_info *mtd, int chip) */ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; unsigned int bufsize = mtd->writesize + mtd->oobsize; @@ -526,8 +526,8 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) */ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; /* If there are still bytes in the FCM, then use the next byte. */ @@ -543,8 +543,8 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) */ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; int avail; @@ -561,47 +561,12 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) len, avail); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/* - * Verify buffer against the FCM Controller Data Buffer - */ -static int fsl_elbc_verify_buf(struct mtd_info *mtd, - const u_char *buf, int len) -{ - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; - struct fsl_elbc_ctrl *ctrl = priv->ctrl; - int i; - - if (len < 0) { - printf("write_buf of %d bytes", len); - return -EINVAL; - } - - if ((unsigned int)len > ctrl->read_bytes - ctrl->index) { - printf("verify_buf beyond end of buffer " - "(%d requested, %u available)\n", - len, ctrl->read_bytes - ctrl->index); - - ctrl->index = ctrl->read_bytes; - return -EINVAL; - } - - for (i = 0; i < len; i++) - if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i]) - break; - - ctrl->index += len; - return i == len && ctrl->status == LTESR_CC ? 0 : -EIO; -} -#endif - /* This function is called after Program and Erase Operations to * check for success or failure. */ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) { - struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); struct fsl_elbc_ctrl *ctrl = priv->ctrl; fsl_lbc_t *lbc = ctrl->regs; @@ -646,7 +611,8 @@ static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, * waitfunc. */ static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, int oob_required) + const uint8_t *buf, int oob_required, + int page) { fsl_elbc_write_buf(mtd, buf, mtd->writesize); fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -656,6 +622,19 @@ static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip, static struct fsl_elbc_ctrl *elbc_ctrl; +/* ECC will be calculated automatically, and errors will be detected in + * waitfunc. + */ +static int fsl_elbc_write_subpage(struct mtd_info *mtd, struct nand_chip *chip, + uint32_t offset, uint32_t data_len, + const uint8_t *buf, int oob_required, int page) +{ + fsl_elbc_write_buf(mtd, buf, mtd->writesize); + fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); + + return 0; +} + static void fsl_elbc_ctrl_init(void) { elbc_ctrl = kzalloc(sizeof(*elbc_ctrl), GFP_KERNEL); @@ -678,7 +657,7 @@ static void fsl_elbc_ctrl_init(void) static int fsl_elbc_chip_init(int devnum, u8 *addr) { - struct mtd_info *mtd = &nand_info[devnum]; + struct mtd_info *mtd; struct nand_chip *nand; struct fsl_elbc_mtd *priv; uint32_t br = 0, or = 0; @@ -714,11 +693,12 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) if (priv->bank >= MAX_BANKS) { printf("fsl_elbc_nand: address did not match any " "chip selects\n"); + kfree(priv); return -ENODEV; } nand = &priv->chip; - mtd->priv = nand; + mtd = nand_to_mtd(nand); elbc_ctrl->chips[priv->bank] = priv; @@ -727,9 +707,6 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) nand->read_byte = fsl_elbc_read_byte; nand->write_buf = fsl_elbc_write_buf; nand->read_buf = fsl_elbc_read_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - nand->verify_buf = fsl_elbc_verify_buf; -#endif nand->select_chip = fsl_elbc_select_chip; nand->cmdfunc = fsl_elbc_cmdfunc; nand->waitfunc = fsl_elbc_wait; @@ -743,10 +720,11 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) nand->bbt_options = NAND_BBT_USE_FLASH; nand->controller = &elbc_ctrl->controller; - nand->priv = priv; + nand_set_controller_data(nand, priv); nand->ecc.read_page = fsl_elbc_read_page; nand->ecc.write_page = fsl_elbc_write_page; + nand->ecc.write_subpage = fsl_elbc_write_subpage; priv->fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT); @@ -810,7 +788,7 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) if (ret) return ret; - ret = nand_register(devnum); + ret = nand_register(devnum, mtd); if (ret) return ret;