From 29a198a1592d83f2bc1be3b2631b3bcf3d5b380f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 24 May 2016 20:17:48 +0200 Subject: [PATCH] mtd: nand: Get rid of busw parameter Auto-detection functions are passed a busw parameter to retrieve the actual NAND bus width and eventually set the correct value in chip->options. Rework the nand_get_flash_type() function to get rid of this extra parameter and let detection code directly set the NAND_BUSWIDTH_16 flag in chip->options if needed. Signed-off-by: Boris Brezillon Acked-by: Richard Weinberger Reviewed-by: Marek Vasut --- drivers/mtd/nand/nand_base.c | 68 ++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6f3ae626cabc..16b082fb89f4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3385,8 +3385,10 @@ static void nand_shutdown(struct mtd_info *mtd) } /* Set default functions */ -static void nand_set_defaults(struct nand_chip *chip, int busw) +static void nand_set_defaults(struct nand_chip *chip) { + unsigned int busw = chip->options & NAND_BUSWIDTH_16; + /* check for proper chip_delay setup, set 20us if not */ if (!chip->chip_delay) chip->chip_delay = 20; @@ -3562,7 +3564,7 @@ static void nand_onfi_detect_micron(struct nand_chip *chip, /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_onfi(struct nand_chip *chip, int *busw) +static int nand_flash_detect_onfi(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); struct nand_onfi_params *p = &chip->onfi_params; @@ -3634,9 +3636,7 @@ static int nand_flash_detect_onfi(struct nand_chip *chip, int *busw) chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun); if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; if (p->ecc_bits != 0xff) { chip->ecc_strength_ds = p->ecc_bits; @@ -3669,7 +3669,7 @@ static int nand_flash_detect_onfi(struct nand_chip *chip, int *busw) /* * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_jedec(struct nand_chip *chip, int *busw) +static int nand_flash_detect_jedec(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); struct nand_jedec_params *p = &chip->jedec_params; @@ -3730,9 +3730,7 @@ static int nand_flash_detect_jedec(struct nand_chip *chip, int *busw) chip->bits_per_cell = p->bits_per_cell; if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; /* ECC info */ ecc = &p->ecc_info[0]; @@ -3821,7 +3819,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct nand_chip *chip, int *busw) +static void nand_decode_ext_id(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); int extid, id_len = chip->id.len; @@ -3874,7 +3872,6 @@ static void nand_decode_ext_id(struct nand_chip *chip, int *busw) /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - *busw = 0; } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -3915,7 +3912,6 @@ static void nand_decode_ext_id(struct nand_chip *chip, int *busw) mtd->erasesize = 768 * 1024; else mtd->erasesize = (64 * 1024) << tmp; - *busw = 0; } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -3928,7 +3924,8 @@ static void nand_decode_ext_id(struct nand_chip *chip, int *busw) mtd->erasesize = (64 * 1024) << (extid & 0x03); extid >>= 2; /* Get buswidth information */ - *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; /* * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per @@ -3953,8 +3950,7 @@ static void nand_decode_ext_id(struct nand_chip *chip, int *busw) * decodes a matching ID table entry and assigns the MTD size parameters for * the chip. */ -static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type, - int *busw) +static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { struct mtd_info *mtd = nand_to_mtd(chip); u8 *id_data = chip->id.data; @@ -3963,7 +3959,6 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type, mtd->erasesize = type->erasesize; mtd->writesize = type->pagesize; mtd->oobsize = mtd->writesize / 32; - *busw = type->options & NAND_BUSWIDTH_16; /* All legacy ID NAND are small-page, SLC */ chip->bits_per_cell = 1; @@ -4026,7 +4021,7 @@ static inline bool is_full_id_nand(struct nand_flash_dev *type) } static bool find_full_id_nand(struct nand_chip *chip, - struct nand_flash_dev *type, int *busw) + struct nand_flash_dev *type) { struct mtd_info *mtd = nand_to_mtd(chip); u8 *id_data = chip->id.data; @@ -4044,8 +4039,6 @@ static bool find_full_id_nand(struct nand_chip *chip, chip->onfi_timing_mode_default = type->onfi_timing_mode_default; - *busw = type->options & NAND_BUSWIDTH_16; - if (!mtd->name) mtd->name = type->name; @@ -4106,9 +4099,24 @@ static int nand_get_flash_type(struct nand_chip *chip, if (!type) type = nand_flash_ids; + /* + * Save the NAND_BUSWIDTH_16 flag before letting auto-detection logic + * override it. + * This is required to make sure initial NAND bus width set by the + * NAND controller driver is coherent with the real NAND bus width + * (extracted by auto-detection code). + */ + busw = chip->options & NAND_BUSWIDTH_16; + + /* + * The flag is only set (never cleared), reset it to its default value + * before starting auto-detection. + */ + chip->options &= ~NAND_BUSWIDTH_16; + for (; type->name != NULL; type++) { if (is_full_id_nand(type)) { - if (find_full_id_nand(chip, type, &busw)) + if (find_full_id_nand(chip, type)) goto ident_done; } else if (dev_id == type->dev_id) { break; @@ -4118,11 +4126,11 @@ static int nand_get_flash_type(struct nand_chip *chip, chip->onfi_version = 0; if (!type->name || !type->pagesize) { /* Check if the chip is ONFI compliant */ - if (nand_flash_detect_onfi(chip, &busw)) + if (nand_flash_detect_onfi(chip)) goto ident_done; /* Check if the chip is JEDEC compliant */ - if (nand_flash_detect_jedec(chip, &busw)) + if (nand_flash_detect_jedec(chip)) goto ident_done; } @@ -4136,9 +4144,9 @@ static int nand_get_flash_type(struct nand_chip *chip, if (!type->pagesize) { /* Decode parameters from extended ID */ - nand_decode_ext_id(chip, &busw); + nand_decode_ext_id(chip); } else { - nand_decode_id(chip, type, &busw); + nand_decode_id(chip, type); } /* Get chip options */ chip->options |= type->options; @@ -4158,9 +4166,8 @@ ident_done: } if (chip->options & NAND_BUSWIDTH_AUTO) { - WARN_ON(chip->options & NAND_BUSWIDTH_16); - chip->options |= busw; - nand_set_defaults(chip, busw); + WARN_ON(busw & NAND_BUSWIDTH_16); + nand_set_defaults(chip); } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { /* * Check, if buswidth is correct. Hardware drivers should set @@ -4169,9 +4176,8 @@ ident_done: pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", maf_id, dev_id); pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, mtd->name); - pr_warn("bus width %d instead %d bit\n", - (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, - busw ? 16 : 8); + pr_warn("bus width %d instead of %d bits\n", busw ? 16 : 8, + (chip->options & NAND_BUSWIDTH_16) ? 16 : 8); return -EINVAL; } @@ -4399,7 +4405,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, return -EINVAL; } /* Set the default functions */ - nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); + nand_set_defaults(chip); /* Read the flash type */ ret = nand_get_flash_type(chip, table); -- 2.11.0