Commit a7ab085d authored by Boris Brezillon's avatar Boris Brezillon Committed by Miquel Raynal

mtd: rawnand: Initialize the nand_device object

In order to use some of the nanddev_xxx() helpers, we need to
initialize the nand_device object embedded in nand_chip using
nanddev_init(). This requires implementing nand_ops.

We also drop useless mtd->xxx initialization when they're already taken
case of by nanddev_init().
Signed-off-by: default avatarBoris Brezillon <bbrezillon@kernel.org>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarFrieder Schrempf <frieder.schrempf@kontron.de>
parent 629a442c
...@@ -14,6 +14,7 @@ menuconfig MTD_NAND ...@@ -14,6 +14,7 @@ menuconfig MTD_NAND
tristate "Raw/Parallel NAND Device Support" tristate "Raw/Parallel NAND Device Support"
depends on MTD depends on MTD
select MTD_NAND_ECC select MTD_NAND_ECC
select MTD_NAND_CORE
help help
This enables support for accessing all type of raw/parallel This enables support for accessing all type of raw/parallel
NAND flash devices. For further information see NAND flash devices. For further information see
......
...@@ -5484,6 +5484,50 @@ static bool nand_ecc_strength_good(struct nand_chip *chip) ...@@ -5484,6 +5484,50 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
} }
static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos)
{
struct nand_chip *chip = container_of(nand, struct nand_chip,
base);
unsigned int eb = nanddev_pos_to_row(nand, pos);
int ret;
eb >>= nand->rowconv.eraseblock_addr_shift;
nand_select_target(chip, pos->target);
ret = nand_erase_op(chip, eb);
nand_deselect_target(chip);
return ret;
}
static int rawnand_markbad(struct nand_device *nand,
const struct nand_pos *pos)
{
struct nand_chip *chip = container_of(nand, struct nand_chip,
base);
return nand_markbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
}
static bool rawnand_isbad(struct nand_device *nand, const struct nand_pos *pos)
{
struct nand_chip *chip = container_of(nand, struct nand_chip,
base);
int ret;
nand_select_target(chip, pos->target);
ret = nand_isbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
nand_deselect_target(chip);
return ret;
}
static const struct nand_ops rawnand_ops = {
.erase = rawnand_erase,
.markbad = rawnand_markbad,
.isbad = rawnand_isbad,
};
/** /**
* nand_scan_tail - Scan for the NAND device * nand_scan_tail - Scan for the NAND device
* @chip: NAND chip object * @chip: NAND chip object
...@@ -5752,10 +5796,15 @@ static int nand_scan_tail(struct nand_chip *chip) ...@@ -5752,10 +5796,15 @@ static int nand_scan_tail(struct nand_chip *chip)
break; break;
} }
ret = nanddev_init(&chip->base, &rawnand_ops, mtd->owner);
if (ret)
goto err_nand_manuf_cleanup;
/* Adjust the MTD_CAP_ flags when NAND_ROM is set. */
if (chip->options & NAND_ROM)
mtd->flags = MTD_CAP_ROM;
/* Fill in remaining MTD driver data */ /* Fill in remaining MTD driver data */
mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
MTD_CAP_NANDFLASH;
mtd->_erase = nand_erase; mtd->_erase = nand_erase;
mtd->_point = NULL; mtd->_point = NULL;
mtd->_unpoint = NULL; mtd->_unpoint = NULL;
...@@ -5772,7 +5821,6 @@ static int nand_scan_tail(struct nand_chip *chip) ...@@ -5772,7 +5821,6 @@ static int nand_scan_tail(struct nand_chip *chip)
mtd->_block_isbad = nand_block_isbad; mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad; mtd->_block_markbad = nand_block_markbad;
mtd->_max_bad_blocks = nand_max_bad_blocks; mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
/* /*
* Initialize bitflip_threshold to its default prior scan_bbt() call. * Initialize bitflip_threshold to its default prior scan_bbt() call.
...@@ -5785,13 +5833,13 @@ static int nand_scan_tail(struct nand_chip *chip) ...@@ -5785,13 +5833,13 @@ static int nand_scan_tail(struct nand_chip *chip)
/* Initialize the ->data_interface field. */ /* Initialize the ->data_interface field. */
ret = nand_init_data_interface(chip); ret = nand_init_data_interface(chip);
if (ret) if (ret)
goto err_nand_manuf_cleanup; goto err_nanddev_cleanup;
/* Enter fastest possible mode on all dies. */ /* Enter fastest possible mode on all dies. */
for (i = 0; i < chip->numchips; i++) { for (i = 0; i < chip->numchips; i++) {
ret = nand_setup_data_interface(chip, i); ret = nand_setup_data_interface(chip, i);
if (ret) if (ret)
goto err_nand_manuf_cleanup; goto err_nanddev_cleanup;
} }
/* Check, if we should skip the bad block table scan */ /* Check, if we should skip the bad block table scan */
...@@ -5801,11 +5849,14 @@ static int nand_scan_tail(struct nand_chip *chip) ...@@ -5801,11 +5849,14 @@ static int nand_scan_tail(struct nand_chip *chip)
/* Build bad block table */ /* Build bad block table */
ret = nand_create_bbt(chip); ret = nand_create_bbt(chip);
if (ret) if (ret)
goto err_nand_manuf_cleanup; goto err_nanddev_cleanup;
return 0; return 0;
err_nanddev_cleanup:
nanddev_cleanup(&chip->base);
err_nand_manuf_cleanup: err_nand_manuf_cleanup:
nand_manufacturer_cleanup(chip); nand_manufacturer_cleanup(chip);
......
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