mtd: rawnand: Initialize the nand_device object
authorBoris Brezillon <bbrezillon@kernel.org>
Thu, 25 Oct 2018 20:10:36 +0000 (22:10 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Mon, 8 Apr 2019 08:21:12 +0000 (10:21 +0200)
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: Boris Brezillon <bbrezillon@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
drivers/mtd/nand/raw/Kconfig
drivers/mtd/nand/raw/nand_base.c

index 705863c6709a4fe9799bc162eaacba49aa5470f4..80b5fec1f75ab72254d4a91b278957e605502acc 100644 (file)
@@ -14,6 +14,7 @@ menuconfig MTD_NAND
        tristate "Raw/Parallel NAND Device Support"
        depends on MTD
        select MTD_NAND_ECC
+       select MTD_NAND_CORE
        help
          This enables support for accessing all type of raw/parallel
          NAND flash devices. For further information see
index dbe3d96b74da9425b8cdf9895bc1897f25f3b8b0..071a0c658bfe656fbfaccd211a6580e593added1 100644 (file)
@@ -5484,6 +5484,50 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
        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
  * @chip: NAND chip object
@@ -5752,10 +5796,15 @@ static int nand_scan_tail(struct nand_chip *chip)
                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 */
-       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->_point = NULL;
        mtd->_unpoint = NULL;
@@ -5772,7 +5821,6 @@ static int nand_scan_tail(struct nand_chip *chip)
        mtd->_block_isbad = nand_block_isbad;
        mtd->_block_markbad = nand_block_markbad;
        mtd->_max_bad_blocks = nand_max_bad_blocks;
-       mtd->writebufsize = mtd->writesize;
 
        /*
         * Initialize bitflip_threshold to its default prior scan_bbt() call.
@@ -5785,13 +5833,13 @@ static int nand_scan_tail(struct nand_chip *chip)
        /* Initialize the ->data_interface field. */
        ret = nand_init_data_interface(chip);
        if (ret)
-               goto err_nand_manuf_cleanup;
+               goto err_nanddev_cleanup;
 
        /* Enter fastest possible mode on all dies. */
        for (i = 0; i < chip->numchips; i++) {
                ret = nand_setup_data_interface(chip, i);
                if (ret)
-                       goto err_nand_manuf_cleanup;
+                       goto err_nanddev_cleanup;
        }
 
        /* Check, if we should skip the bad block table scan */
@@ -5801,11 +5849,14 @@ static int nand_scan_tail(struct nand_chip *chip)
        /* Build bad block table */
        ret = nand_create_bbt(chip);
        if (ret)
-               goto err_nand_manuf_cleanup;
+               goto err_nanddev_cleanup;
 
        return 0;
 
 
+err_nanddev_cleanup:
+       nanddev_cleanup(&chip->base);
+
 err_nand_manuf_cleanup:
        nand_manufacturer_cleanup(chip);