mtd: rawnand: marvell: convert driver to nand_scan()
Two helpers have been added to the core to do all kind of controller side configuration/initialization between the detection phase and the final NAND scan. Implement these hooks so that we can convert the driver to just use nand_scan() instead of the nand_scan_ident() + nand_scan_tail() pair. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
This commit is contained in:
parent
f4a48d7bf8
commit
8831e48bad
@ -2290,6 +2290,111 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int marvell_nand_attach_chip(struct nand_chip *chip)
|
||||
{
|
||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||
struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
|
||||
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
|
||||
struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(nfc->dev);
|
||||
int ret;
|
||||
|
||||
if (pdata && pdata->flash_bbt)
|
||||
chip->bbt_options |= NAND_BBT_USE_FLASH;
|
||||
|
||||
if (chip->bbt_options & NAND_BBT_USE_FLASH) {
|
||||
/*
|
||||
* We'll use a bad block table stored in-flash and don't
|
||||
* allow writing the bad block marker to the flash.
|
||||
*/
|
||||
chip->bbt_options |= NAND_BBT_NO_OOB_BBM;
|
||||
chip->bbt_td = &bbt_main_descr;
|
||||
chip->bbt_md = &bbt_mirror_descr;
|
||||
}
|
||||
|
||||
/* Save the chip-specific fields of NDCR */
|
||||
marvell_nand->ndcr = NDCR_PAGE_SZ(mtd->writesize);
|
||||
if (chip->options & NAND_BUSWIDTH_16)
|
||||
marvell_nand->ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
|
||||
|
||||
/*
|
||||
* On small page NANDs, only one cycle is needed to pass the
|
||||
* column address.
|
||||
*/
|
||||
if (mtd->writesize <= 512) {
|
||||
marvell_nand->addr_cyc = 1;
|
||||
} else {
|
||||
marvell_nand->addr_cyc = 2;
|
||||
marvell_nand->ndcr |= NDCR_RA_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now add the number of cycles needed to pass the row
|
||||
* address.
|
||||
*
|
||||
* Addressing a chip using CS 2 or 3 should also need the third row
|
||||
* cycle but due to inconsistance in the documentation and lack of
|
||||
* hardware to test this situation, this case is not supported.
|
||||
*/
|
||||
if (chip->options & NAND_ROW_ADDR_3)
|
||||
marvell_nand->addr_cyc += 3;
|
||||
else
|
||||
marvell_nand->addr_cyc += 2;
|
||||
|
||||
if (pdata) {
|
||||
chip->ecc.size = pdata->ecc_step_size;
|
||||
chip->ecc.strength = pdata->ecc_strength;
|
||||
}
|
||||
|
||||
ret = marvell_nand_ecc_init(mtd, &chip->ecc);
|
||||
if (ret) {
|
||||
dev_err(nfc->dev, "ECC init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (chip->ecc.mode == NAND_ECC_HW) {
|
||||
/*
|
||||
* Subpage write not available with hardware ECC, prohibit also
|
||||
* subpage read as in userspace subpage access would still be
|
||||
* allowed and subpage write, if used, would lead to numerous
|
||||
* uncorrectable ECC errors.
|
||||
*/
|
||||
chip->options |= NAND_NO_SUBPAGE_WRITE;
|
||||
}
|
||||
|
||||
if (pdata || nfc->caps->legacy_of_bindings) {
|
||||
/*
|
||||
* We keep the MTD name unchanged to avoid breaking platforms
|
||||
* where the MTD cmdline parser is used and the bootloader
|
||||
* has not been updated to use the new naming scheme.
|
||||
*/
|
||||
mtd->name = "pxa3xx_nand-0";
|
||||
} else if (!mtd->name) {
|
||||
/*
|
||||
* If the new bindings are used and the bootloader has not been
|
||||
* updated to pass a new mtdparts parameter on the cmdline, you
|
||||
* should define the following property in your NAND node, ie:
|
||||
*
|
||||
* label = "main-storage";
|
||||
*
|
||||
* This way, mtd->name will be set by the core when
|
||||
* nand_set_flash_node() is called.
|
||||
*/
|
||||
mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL,
|
||||
"%s:nand.%d", dev_name(nfc->dev),
|
||||
marvell_nand->sels[0].cs);
|
||||
if (!mtd->name) {
|
||||
dev_err(nfc->dev, "Failed to allocate mtd->name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nand_controller_ops marvell_nand_controller_ops = {
|
||||
.attach_chip = marvell_nand_attach_chip,
|
||||
};
|
||||
|
||||
static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
|
||||
struct device_node *np)
|
||||
{
|
||||
@ -2432,105 +2537,10 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
|
||||
marvell_nand->ndtr1 = readl_relaxed(nfc->regs + NDTR1);
|
||||
|
||||
chip->options |= NAND_BUSWIDTH_AUTO;
|
||||
ret = nand_scan_ident(mtd, marvell_nand->nsels, NULL);
|
||||
|
||||
ret = nand_scan(mtd, marvell_nand->nsels);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not identify the nand chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pdata && pdata->flash_bbt)
|
||||
chip->bbt_options |= NAND_BBT_USE_FLASH;
|
||||
|
||||
if (chip->bbt_options & NAND_BBT_USE_FLASH) {
|
||||
/*
|
||||
* We'll use a bad block table stored in-flash and don't
|
||||
* allow writing the bad block marker to the flash.
|
||||
*/
|
||||
chip->bbt_options |= NAND_BBT_NO_OOB_BBM;
|
||||
chip->bbt_td = &bbt_main_descr;
|
||||
chip->bbt_md = &bbt_mirror_descr;
|
||||
}
|
||||
|
||||
/* Save the chip-specific fields of NDCR */
|
||||
marvell_nand->ndcr = NDCR_PAGE_SZ(mtd->writesize);
|
||||
if (chip->options & NAND_BUSWIDTH_16)
|
||||
marvell_nand->ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
|
||||
|
||||
/*
|
||||
* On small page NANDs, only one cycle is needed to pass the
|
||||
* column address.
|
||||
*/
|
||||
if (mtd->writesize <= 512) {
|
||||
marvell_nand->addr_cyc = 1;
|
||||
} else {
|
||||
marvell_nand->addr_cyc = 2;
|
||||
marvell_nand->ndcr |= NDCR_RA_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now add the number of cycles needed to pass the row
|
||||
* address.
|
||||
*
|
||||
* Addressing a chip using CS 2 or 3 should also need the third row
|
||||
* cycle but due to inconsistance in the documentation and lack of
|
||||
* hardware to test this situation, this case is not supported.
|
||||
*/
|
||||
if (chip->options & NAND_ROW_ADDR_3)
|
||||
marvell_nand->addr_cyc += 3;
|
||||
else
|
||||
marvell_nand->addr_cyc += 2;
|
||||
|
||||
if (pdata) {
|
||||
chip->ecc.size = pdata->ecc_step_size;
|
||||
chip->ecc.strength = pdata->ecc_strength;
|
||||
}
|
||||
|
||||
ret = marvell_nand_ecc_init(mtd, &chip->ecc);
|
||||
if (ret) {
|
||||
dev_err(dev, "ECC init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (chip->ecc.mode == NAND_ECC_HW) {
|
||||
/*
|
||||
* Subpage write not available with hardware ECC, prohibit also
|
||||
* subpage read as in userspace subpage access would still be
|
||||
* allowed and subpage write, if used, would lead to numerous
|
||||
* uncorrectable ECC errors.
|
||||
*/
|
||||
chip->options |= NAND_NO_SUBPAGE_WRITE;
|
||||
}
|
||||
|
||||
if (pdata || nfc->caps->legacy_of_bindings) {
|
||||
/*
|
||||
* We keep the MTD name unchanged to avoid breaking platforms
|
||||
* where the MTD cmdline parser is used and the bootloader
|
||||
* has not been updated to use the new naming scheme.
|
||||
*/
|
||||
mtd->name = "pxa3xx_nand-0";
|
||||
} else if (!mtd->name) {
|
||||
/*
|
||||
* If the new bindings are used and the bootloader has not been
|
||||
* updated to pass a new mtdparts parameter on the cmdline, you
|
||||
* should define the following property in your NAND node, ie:
|
||||
*
|
||||
* label = "main-storage";
|
||||
*
|
||||
* This way, mtd->name will be set by the core when
|
||||
* nand_set_flash_node() is called.
|
||||
*/
|
||||
mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL,
|
||||
"%s:nand.%d", dev_name(nfc->dev),
|
||||
marvell_nand->sels[0].cs);
|
||||
if (!mtd->name) {
|
||||
dev_err(nfc->dev, "Failed to allocate mtd->name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
ret = nand_scan_tail(mtd);
|
||||
if (ret) {
|
||||
dev_err(dev, "nand_scan_tail failed: %d\n", ret);
|
||||
dev_err(dev, "could not scan the nand chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2746,6 +2756,7 @@ static int marvell_nfc_probe(struct platform_device *pdev)
|
||||
|
||||
nfc->dev = dev;
|
||||
nand_controller_init(&nfc->controller);
|
||||
nfc->controller.ops = &marvell_nand_controller_ops;
|
||||
INIT_LIST_HEAD(&nfc->chips);
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user