diff options
Diffstat (limited to 'drivers/mtd/nand/raw/marvell_nand.c')
-rw-r--r-- | drivers/mtd/nand/raw/marvell_nand.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 179f0ca585f8..260a0430313e 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -707,7 +707,7 @@ static int marvell_nfc_wait_op(struct nand_chip *chip, unsigned int timeout_ms) * In case the interrupt was not served in the required time frame, * check if the ISR was not served or if something went actually wrong. */ - if (ret && !pending) { + if (!ret && !pending) { dev_err(nfc->dev, "Timeout waiting for RB signal\n"); return -ETIMEDOUT; } @@ -932,14 +932,14 @@ static void marvell_nfc_check_empty_chunk(struct nand_chip *chip, } /* - * Check a chunk is correct or not according to hardware ECC engine. + * Check if a chunk is correct or not according to the hardware ECC engine. * mtd->ecc_stats.corrected is updated, as well as max_bitflips, however * mtd->ecc_stats.failure is not, the function will instead return a non-zero * value indicating that a check on the emptyness of the subpage must be - * performed before declaring the subpage corrupted. + * performed before actually declaring the subpage as "corrupted". */ -static int marvell_nfc_hw_ecc_correct(struct nand_chip *chip, - unsigned int *max_bitflips) +static int marvell_nfc_hw_ecc_check_bitflips(struct nand_chip *chip, + unsigned int *max_bitflips) { struct mtd_info *mtd = nand_to_mtd(chip); struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); @@ -1053,7 +1053,7 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf, marvell_nfc_enable_hw_ecc(chip); marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, false, page); - ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips); + ret = marvell_nfc_hw_ecc_check_bitflips(chip, &max_bitflips); marvell_nfc_disable_hw_ecc(chip); if (!ret) @@ -1224,12 +1224,12 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf, /* Read spare bytes */ nand_read_data_op(chip, oob + (lt->spare_bytes * chunk), - spare_len, false); + spare_len, false, false); /* Read ECC bytes */ nand_read_data_op(chip, oob + ecc_offset + (ALIGN(lt->ecc_bytes, 32) * chunk), - ecc_len, false); + ecc_len, false, false); } return 0; @@ -1336,7 +1336,7 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip, /* Read the chunk and detect number of bitflips */ marvell_nfc_hw_ecc_bch_read_chunk(chip, chunk, data, data_len, spare, spare_len, page); - ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips); + ret = marvell_nfc_hw_ecc_check_bitflips(chip, &max_bitflips); if (ret) failure_mask |= BIT(chunk); @@ -1358,10 +1358,9 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip, */ /* - * In case there is any subpage read error reported by ->correct(), we - * usually re-read only ECC bytes in raw mode and check if the whole - * page is empty. In this case, it is normal that the ECC check failed - * and we just ignore the error. + * In case there is any subpage read error, we usually re-read only ECC + * bytes in raw mode and check if the whole page is empty. In this case, + * it is normal that the ECC check failed and we just ignore the error. * * However, it has been empirically observed that for some layouts (e.g * 2k page, 8b strength per 512B chunk), the controller tries to correct @@ -2107,7 +2106,8 @@ static int marvell_nfc_exec_op(struct nand_chip *chip, { struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); - marvell_nfc_select_target(chip, op->cs); + if (!check_only) + marvell_nfc_select_target(chip, op->cs); if (nfc->caps->is_nfcv2) return nand_op_parser_exec_op(chip, &marvell_nfcv2_op_parser, @@ -2166,8 +2166,8 @@ static const struct mtd_ooblayout_ops marvell_nand_ooblayout_ops = { .free = marvell_nand_ooblayout_free, }; -static int marvell_nand_hw_ecc_ctrl_init(struct mtd_info *mtd, - struct nand_ecc_ctrl *ecc) +static int marvell_nand_hw_ecc_controller_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc) { struct nand_chip *chip = mtd_to_nand(mtd); struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); @@ -2261,7 +2261,7 @@ static int marvell_nand_ecc_init(struct mtd_info *mtd, switch (ecc->mode) { case NAND_ECC_HW: - ret = marvell_nand_hw_ecc_ctrl_init(mtd, ecc); + ret = marvell_nand_hw_ecc_controller_init(mtd, ecc); if (ret) return ret; break; @@ -2664,7 +2664,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "failed to register mtd device: %d\n", ret); - nand_release(chip); + nand_cleanup(chip); return ret; } @@ -2673,6 +2673,21 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, return 0; } +static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc) +{ + struct marvell_nand_chip *entry, *temp; + struct nand_chip *chip; + int ret; + + list_for_each_entry_safe(entry, temp, &nfc->chips, node) { + chip = &entry->chip; + ret = mtd_device_unregister(nand_to_mtd(chip)); + WARN_ON(ret); + nand_cleanup(chip); + list_del(&entry->node); + } +} + static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc) { struct device_node *np = dev->of_node; @@ -2707,21 +2722,16 @@ static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc) ret = marvell_nand_chip_init(dev, nfc, nand_np); if (ret) { of_node_put(nand_np); - return ret; + goto cleanup_chips; } } return 0; -} -static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc) -{ - struct marvell_nand_chip *entry, *temp; +cleanup_chips: + marvell_nand_chips_cleanup(nfc); - list_for_each_entry_safe(entry, temp, &nfc->chips, node) { - nand_release(&entry->chip); - list_del(&entry->node); - } + return ret; } static int marvell_nfc_init_dma(struct marvell_nfc *nfc) @@ -2854,7 +2864,6 @@ static int marvell_nfc_init(struct marvell_nfc *nfc) static int marvell_nfc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *r; struct marvell_nfc *nfc; int ret; int irq; @@ -2869,8 +2878,7 @@ static int marvell_nfc_probe(struct platform_device *pdev) nfc->controller.ops = &marvell_nand_controller_ops; INIT_LIST_HEAD(&nfc->chips); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - nfc->regs = devm_ioremap_resource(dev, r); + nfc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(nfc->regs)) return PTR_ERR(nfc->regs); |