--- zzzz-none-000/linux-4.1.38/drivers/mtd/nand/nand_base.c 2017-01-18 18:48:06.000000000 +0000 +++ bcm63-7582-715/linux-4.1.38/drivers/mtd/nand/nand_base.c 2020-11-25 10:06:48.000000000 +0000 @@ -48,6 +48,9 @@ #include #include #include +#if defined(CONFIG_BCM_KF_MTD_BCMNAND) +#include +#endif /* Define default oob placement schemes for large and small page devices */ static struct nand_ecclayout nand_oob_8 = { @@ -1889,6 +1892,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { + unsigned int max_bitflips = 0; int page, realpage, chipnr; struct nand_chip *chip = mtd->priv; struct mtd_ecc_stats stats; @@ -1949,6 +1953,8 @@ nand_wait_ready(mtd); } + max_bitflips = max_t(unsigned int, max_bitflips, ret); + readlen -= len; if (!readlen) break; @@ -1974,7 +1980,7 @@ if (mtd->ecc_stats.failed - stats.failed) return -EBADMSG; - return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; + return max_bitflips; } /** @@ -3623,7 +3629,10 @@ chip->ecc_step_ds = NAND_ECC_STEP(type); chip->onfi_timing_mode_default = type->onfi_timing_mode_default; - +#if defined(CONFIG_BCM_KF_MTD_BCMNAND) + chip->timing_1 = type->timing_1; + chip->timing_2 = type->timing_2; +#endif *busw = type->options & NAND_BUSWIDTH_16; if (!mtd->name) @@ -3798,6 +3807,41 @@ return type; } +#if defined(CONFIG_BCM_KF_MTD_BCMNAND) +static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, + struct device_node *dn) +{ + int ecc_mode, ecc_strength, ecc_step; + + if (of_get_nand_bus_width(dn) == 16) + chip->options |= NAND_BUSWIDTH_16; + + if (of_get_nand_on_flash_bbt(dn)) + chip->bbt_options |= NAND_BBT_USE_FLASH; + + ecc_mode = of_get_nand_ecc_mode(dn); + ecc_strength = of_get_nand_ecc_strength(dn); + ecc_step = of_get_nand_ecc_step_size(dn); + + if ((ecc_step >= 0 && !(ecc_strength >= 0)) || + (!(ecc_step >= 0) && ecc_strength >= 0)) { + pr_err("must set both strength and step size in DT\n"); + return -EINVAL; + } + + if (ecc_mode >= 0) + chip->ecc.mode = ecc_mode; + + if (ecc_strength >= 0) + chip->ecc.strength = ecc_strength; + + if (ecc_step > 0) + chip->ecc.size = ecc_step; + + return 0; +} +#endif + /** * nand_scan_ident - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure @@ -3815,7 +3859,15 @@ int i, nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd->priv; struct nand_flash_dev *type; +#if defined(CONFIG_BCM_KF_MTD_BCMNAND) + int ret; + if (chip->dn) { + ret = nand_dt_init(mtd, chip, chip->dn); + if (ret) + return ret; + } +#endif /* Set the default functions */ nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); @@ -4162,6 +4214,10 @@ mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : MTD_CAP_NANDFLASH; +#if defined(CONFIG_BCM_KF_MTD_BCMNAND) + if (chip->options & NAND_PAGE_NOP1) + mtd->flags |= MTD_NAND_NOP1; +#endif mtd->_erase = nand_erase; mtd->_point = NULL; mtd->_unpoint = NULL;