* [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree @ 2019-08-05 12:20 Sascha Hauer 2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer ` (7 more replies) 0 siblings, 8 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List This series makes the ecc strength used by the mxs-nand controller configurable via device tree. This feature can be used to reuse NAND images on devices with different OOB sizes. Sascha Hauer (8): mtd: nand-mxs: consistently rename struct nand_chip * to "chip" mtd: nand-mxs: calculate ecc_strength only once mtd: nand-mxs: Make locally used variable static mtd: nand-mxs: change API between NAND driver and fcb code mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() mtd: nand-mxs: inline only once used function mtd: nand: Add function to parse device tree properties mtd: nand-mxs: Make ecc strength configurable via device tree common/imx-bbu-nand-fcb.c | 15 +- drivers/mtd/nand/nand_base.c | 27 ++++ drivers/mtd/nand/nand_mxs.c | 273 ++++++++++++++++++++--------------- include/linux/mtd/nand.h | 2 + include/linux/mtd/nand_mxs.h | 7 +- 5 files changed, 196 insertions(+), 128 deletions(-) -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer ` (6 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List The struct nand_chip * is sometimes named "nand" and sometimes "chip". For consistency name it "chip" throughout the driver. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 148 ++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index c3b07aa3f6..f753874956 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -396,8 +396,8 @@ static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info) */ static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; struct mxs_dma_desc *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -496,12 +496,12 @@ static int mxs_nand_device_ready(struct mtd_info *mtd) /* * Select the NAND chip. */ -static void mxs_nand_select_chip(struct mtd_info *mtd, int chip) +static void mxs_nand_select_chip(struct mtd_info *mtd, int chipnum) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; - nand_info->cur_chip = chip; + nand_info->cur_chip = chipnum; } /* @@ -555,8 +555,8 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd, */ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; struct mxs_dma_desc *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -633,8 +633,8 @@ rtn: static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int length) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; struct mxs_dma_desc *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -690,8 +690,8 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd) static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; int chunk_size; void __iomem *bch_regs = nand_info->bch_base; @@ -718,11 +718,11 @@ static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen) /* * Read a page from NAND. */ -static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, +static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page, int readlen) { - struct mxs_nand_info *nand_info = nand->priv; + struct mxs_nand_info *nand_info = chip->priv; struct mxs_dma_desc *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; uint32_t corrected = 0, failed = 0; @@ -899,9 +899,9 @@ static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand * necessary, it has already been done, so we can rely on the first * byte of the auxiliary buffer to contain the block mark. */ - memset(nand->oob_poi, 0xff, mtd->oobsize); + memset(chip->oob_poi, 0xff, mtd->oobsize); - nand->oob_poi[0] = nand_info->oob_buf[0]; + chip->oob_poi[0] = nand_info->oob_buf[0]; ret = 0; rtn: @@ -912,10 +912,10 @@ rtn: return ret ? ret : max_bitflips; } -static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, +static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - return __mxs_nand_ecc_read_page(mtd, nand, buf, oob_required, page, + return __mxs_nand_ecc_read_page(mtd, chip, buf, oob_required, page, mtd->writesize); } @@ -939,16 +939,16 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, * Write a page to NAND. */ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, - struct nand_chip *nand, const uint8_t *buf, + struct nand_chip *chip, const uint8_t *buf, int oob_required) { - struct mxs_nand_info *nand_info = nand->priv; + struct mxs_nand_info *nand_info = chip->priv; struct mxs_dma_desc *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret = 0; memcpy(nand_info->data_buf, buf, mtd->writesize); - memcpy(nand_info->oob_buf, nand->oob_poi, mtd->oobsize); + memcpy(nand_info->oob_buf, chip->oob_poi, mtd->oobsize); /* Handle block mark swapping. */ mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf); @@ -1112,10 +1112,10 @@ static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs) * raw_oob_mode field so that, when control finally arrives here, we'll know * what to do. */ -static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand, +static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct mxs_nand_info *nand_info = nand->priv; + struct mxs_nand_info *nand_info = chip->priv; int column; /* @@ -1128,18 +1128,18 @@ static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand, * If control arrives here, we're doing a "raw" read. Send the * command to read the conventional OOB and read it. */ - nand->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page); - nand->read_buf(mtd, nand->oob_poi, mtd->oobsize); + chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page); + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); } else { /* * If control arrives here, we're not doing a "raw" read. Fill * the OOB buffer with set bits and correct the block mark. */ - memset(nand->oob_poi, 0xff, mtd->oobsize); + memset(chip->oob_poi, 0xff, mtd->oobsize); column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize; - nand->cmdfunc(mtd, NAND_CMD_READ0, column, page); - mxs_nand_read_buf(mtd, nand->oob_poi, 1); + chip->cmdfunc(mtd, NAND_CMD_READ0, column, page); + mxs_nand_read_buf(mtd, chip->oob_poi, 1); } return 0; @@ -1149,10 +1149,10 @@ static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand, /* * Write OOB data to NAND. */ -static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *nand, +static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) { - struct mxs_nand_info *nand_info = nand->priv; + struct mxs_nand_info *nand_info = chip->priv; int column; uint8_t block_mark = 0; @@ -1172,12 +1172,12 @@ static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *nand, column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize; /* Write the block mark. */ - nand->cmdfunc(mtd, NAND_CMD_SEQIN, column, page); - nand->write_buf(mtd, &block_mark, 1); - nand->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + chip->cmdfunc(mtd, NAND_CMD_SEQIN, column, page); + chip->write_buf(mtd, &block_mark, 1); + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); /* Check if it worked. */ - if (nand->waitfunc(mtd, nand) & NAND_STATUS_FAIL) + if (chip->waitfunc(mtd, chip) & NAND_STATUS_FAIL) return -EIO; return 0; @@ -1217,8 +1217,8 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) */ static int mxs_nand_scan_bbt(struct mtd_info *mtd) { - struct nand_chip *nand = mtd->priv; - struct mxs_nand_info *nand_info = nand->priv; + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; void __iomem *bch_regs = nand_info->bch_base; int ret; @@ -1346,13 +1346,13 @@ err1: static void mxs_nand_probe_dt(struct device_d *dev, struct mxs_nand_info *nand_info) { - struct nand_chip *nand = &nand_info->nand_chip; + struct nand_chip *chip = &nand_info->nand_chip; if (!IS_ENABLED(CONFIG_OFTREE)) return; if (of_get_nand_on_flash_bbt(dev->device_node)) - nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; + chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; } /** @@ -1433,7 +1433,7 @@ static int mxs_nand_compute_hardware_timing(struct mxs_nand_info *info, struct gpmi_nfc_hardware_timing *hw) { struct timing_threshold *nfc = &timing_default_threshold; - struct nand_chip *nand = &info->nand_chip; + struct nand_chip *chip = &info->nand_chip; struct nand_timing target = info->timing; unsigned long clock_frequency_in_hz; unsigned int clock_period_in_ns; @@ -1454,11 +1454,11 @@ static int mxs_nand_compute_hardware_timing(struct mxs_nand_info *info, * If there are multiple chips, we need to relax the timings to allow * for signal distortion due to higher capacitance. */ - if (nand->numchips > 2) { + if (chip->numchips > 2) { target.data_setup_in_ns += 10; target.data_hold_in_ns += 10; target.address_setup_in_ns += 10; - } else if (nand->numchips > 1) { + } else if (chip->numchips > 1) { target.data_setup_in_ns += 5; target.data_hold_in_ns += 5; target.address_setup_in_ns += 5; @@ -2004,7 +2004,7 @@ static void mxs_nand_compute_edo_timing(struct mxs_nand_info *info, static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info) { - struct nand_chip *nand = &info->nand_chip; + struct nand_chip *chip = &info->nand_chip; struct mtd_info *mtd = &info->mtd; uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {}; int ret, mode; @@ -2012,10 +2012,10 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info) if (!mxs_nand_is_imx6(info)) return -ENODEV; - if (!nand->onfi_version) + if (!chip->onfi_version) return -ENOENT; - mode = onfi_get_async_timing_mode(nand); + mode = onfi_get_async_timing_mode(chip); /* We only support the timing mode 4 and mode 5. */ if (mode & ONFI_TIMING_MODE_5) @@ -2025,27 +2025,27 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info) else return -EINVAL; - nand->select_chip(mtd, 0); + chip->select_chip(mtd, 0); - if (le16_to_cpu(nand->onfi_params.opt_cmd) + if (le16_to_cpu(chip->onfi_params.opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES) { /* [1] send SET FEATURE commond to NAND */ feature[0] = mode; - ret = nand->onfi_set_features(mtd, nand, + ret = chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_TIMING_MODE, feature); if (ret) goto err_out; /* [2] send GET FEATURE command to double-check the timing mode */ - ret = nand->onfi_get_features(mtd, nand, + ret = chip->onfi_get_features(mtd, chip, ONFI_FEATURE_ADDR_TIMING_MODE, feature); if (ret || feature[0] != mode) goto err_out; } - nand->select_chip(mtd, -1); + chip->select_chip(mtd, -1); /* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */ clk_disable(info->clk); @@ -2057,7 +2057,7 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info) return mode; err_out: - nand->select_chip(mtd, -1); + chip->select_chip(mtd, -1); return -EINVAL; } @@ -2112,7 +2112,7 @@ static int mxs_nand_probe(struct device_d *dev) { struct resource *iores; struct mxs_nand_info *nand_info; - struct nand_chip *nand; + struct nand_chip *chip; struct mtd_info *mtd; enum gpmi_type type; int err; @@ -2168,35 +2168,35 @@ static int mxs_nand_probe(struct device_d *dev) memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout)); /* structures must be linked */ - nand = &nand_info->nand_chip; + chip = &nand_info->nand_chip; mtd = &nand_info->mtd; - mtd->priv = nand; + mtd->priv = chip; mtd->parent = dev; - nand->priv = nand_info; + chip->priv = nand_info; - nand->cmd_ctrl = mxs_nand_cmd_ctrl; + chip->cmd_ctrl = mxs_nand_cmd_ctrl; - nand->dev_ready = mxs_nand_device_ready; - nand->select_chip = mxs_nand_select_chip; - nand->block_bad = mxs_nand_block_bad; - nand->scan_bbt = mxs_nand_scan_bbt; + chip->dev_ready = mxs_nand_device_ready; + chip->select_chip = mxs_nand_select_chip; + chip->block_bad = mxs_nand_block_bad; + chip->scan_bbt = mxs_nand_scan_bbt; - nand->read_byte = mxs_nand_read_byte; + chip->read_byte = mxs_nand_read_byte; - nand->read_buf = mxs_nand_read_buf; - nand->write_buf = mxs_nand_write_buf; + chip->read_buf = mxs_nand_read_buf; + chip->write_buf = mxs_nand_write_buf; - nand->ecc.read_page = mxs_nand_ecc_read_page; - nand->ecc.write_page = mxs_nand_ecc_write_page; - nand->ecc.read_oob = mxs_nand_ecc_read_oob; - nand->ecc.write_oob = mxs_nand_ecc_write_oob; + chip->ecc.read_page = mxs_nand_ecc_read_page; + chip->ecc.write_page = mxs_nand_ecc_write_page; + chip->ecc.read_oob = mxs_nand_ecc_read_oob; + chip->ecc.write_oob = mxs_nand_ecc_write_oob; - nand->ecc.layout = &fake_ecc_layout; - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.bytes = 9; - nand->ecc.size = 512; - nand->ecc.strength = 8; + chip->ecc.layout = &fake_ecc_layout; + chip->ecc.mode = NAND_ECC_HW; + chip->ecc.bytes = 9; + chip->ecc.size = 512; + chip->ecc.strength = 8; /* first scan to find the device and get the page size */ err = nand_scan_ident(mtd, 4, NULL); @@ -2204,11 +2204,11 @@ static int mxs_nand_probe(struct device_d *dev) goto err2; if ((13 * mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) % 8) == 0) { - nand->ecc.read_subpage = gpmi_ecc_read_subpage; - nand->options |= NAND_SUBPAGE_READ; + chip->ecc.read_subpage = gpmi_ecc_read_subpage; + chip->options |= NAND_SUBPAGE_READ; } - nand->options |= NAND_NO_SUBPAGE_WRITE; + chip->options |= NAND_NO_SUBPAGE_WRITE; mxs_nand_setup_timing(nand_info); -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer 2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer ` (5 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List Instead of calculating the ecc strength multiple times with each page read just do it once and store the result in chip->ecc.strength. While at it also store the correct value in chip->ecc.bytes instead of writing a bogus value into it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 48 +++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index f753874956..fb3e2b7958 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -232,6 +232,8 @@ struct mxs_nand_info { #define GPMI_TIMING_INIT_OK (1 << 1) unsigned flags; struct nand_timing timing; + + int bb_mark_bit_offset; }; struct nand_ecclayout fake_ecc_layout; @@ -362,6 +364,29 @@ uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd) return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7; } +static int mxs_nand_calc_geo(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct mxs_nand_info *nand_info = chip->priv; + int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(mtd->writesize); + int ecc_strength; + int gf_len = 13; /* length of Galois Field for non-DDR nand */ + + ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) + / (gf_len * ecc_chunk_count); + + /* We need the minor even number. */ + chip->ecc.strength = rounddown(ecc_strength, 2); + + chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8); + chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; + + nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd->writesize, + chip->ecc.strength); + + return 0; +} + /* * Wait for BCH complete IRQ and clear the IRQ */ @@ -527,8 +552,8 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd, if (nand_info->version == GPMI_VERSION_TYPE_MX23) return; - bit_offset = mxs_nand_mark_bit_offset(mtd); - buf_offset = mxs_nand_mark_byte_offset(mtd); + bit_offset = nand_info->bb_mark_bit_offset & 0x7; + buf_offset = nand_info->bb_mark_bit_offset >> 3; /* * Get the byte from the data area that overlays the block mark. Since @@ -703,13 +728,13 @@ static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen) writel((mxs_nand_ecc_chunk_cnt(readlen) - 1) << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET | MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET | - (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) + (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET | chunk_size, bch_regs + BCH_FLASH0LAYOUT0); writel(readlen << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET | - (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) + (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET | chunk_size, bch_regs + BCH_FLASH0LAYOUT1); @@ -728,15 +753,13 @@ static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip uint32_t corrected = 0, failed = 0; uint8_t *status; unsigned int max_bitflips = 0; - int i, ret, readtotal, nchunks, eccstrength; - - eccstrength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize); + int i, ret, readtotal, nchunks; readlen = roundup(readlen, MXS_NAND_CHUNK_DATA_CHUNK_SIZE); nchunks = mxs_nand_ecc_chunk_cnt(readlen); readtotal = MXS_NAND_METADATA_SIZE; readtotal += MXS_NAND_CHUNK_DATA_CHUNK_SIZE * nchunks; - readtotal += DIV_ROUND_UP(13 * eccstrength * nchunks, 8); + readtotal += DIV_ROUND_UP(13 * chip->ecc.strength * nchunks, 8); mxs_nand_config_bch(mtd, readtotal); @@ -2194,16 +2217,17 @@ static int mxs_nand_probe(struct device_d *dev) chip->ecc.layout = &fake_ecc_layout; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.bytes = 9; - chip->ecc.size = 512; - chip->ecc.strength = 8; /* first scan to find the device and get the page size */ err = nand_scan_ident(mtd, 4, NULL); if (err) goto err2; - if ((13 * mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) % 8) == 0) { + err = mxs_nand_calc_geo(mtd); + if (err) + goto err2; + + if ((13 * chip->ecc.strength % 8) == 0) { chip->ecc.read_subpage = gpmi_ecc_read_subpage; chip->options |= NAND_SUBPAGE_READ; } -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/8] mtd: nand-mxs: Make locally used variable static 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer 2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer 2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer ` (4 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List fake_ecc_layout is only used in the mxs nand driver, so make it static. Also it's not necessary to zero the structure. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index fb3e2b7958..4317c30805 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -236,7 +236,7 @@ struct mxs_nand_info { int bb_mark_bit_offset; }; -struct nand_ecclayout fake_ecc_layout; +static struct nand_ecclayout fake_ecc_layout; static inline int mxs_nand_is_imx6(struct mxs_nand_info *info) { @@ -2188,8 +2188,6 @@ static int mxs_nand_probe(struct device_d *dev) if (err) goto err2; - memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout)); - /* structures must be linked */ chip = &nand_info->nand_chip; mtd = &nand_info->mtd; -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer ` (2 preceding siblings ...) 2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer ` (3 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List The imx-bbu-nand-fcb update handler code calls into the NAND driver to get the ecc strength and bad block marker position. Change the API so that only a single function is necessary and not three functions. Also in future the ecc strength will be configurable via device tree. This means static parameters like page size / oob size are no longer enough to calculate the ecc strength and so we store a pointer to our mtd_info struct in a static global variable. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/imx-bbu-nand-fcb.c | 15 ++++++--- drivers/mtd/nand/nand_mxs.c | 62 +++++++++++++++++++----------------- include/linux/mtd/nand_mxs.h | 7 +--- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c index 6d773b59df..e28ce6b9ea 100644 --- a/common/imx-bbu-nand-fcb.c +++ b/common/imx-bbu-nand-fcb.c @@ -486,15 +486,22 @@ err: static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler, struct fcb_block *fcb, struct mtd_info *mtd) { + int ecc_strength; + int bb_mark_bit_offset; + int ret; + fcb->FingerPrint = 0x20424346; fcb->Version = 0x01000000; fcb->PageDataSize = mtd->writesize; fcb->TotalPageSize = mtd->writesize + mtd->oobsize; fcb->SectorsPerBlock = mtd->erasesize / mtd->writesize; + ret = mxs_nand_get_geo(&ecc_strength, &bb_mark_bit_offset); + if (ret) + return ret; + /* Divide ECC strength by two and save the value into FCB structure. */ - fcb->EccBlock0EccType = - mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1; + fcb->EccBlock0EccType = ecc_strength >> 1; fcb->EccBlockNEccType = fcb->EccBlock0EccType; fcb->EccBlock0Size = 0x00000200; @@ -505,8 +512,8 @@ static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler, /* DBBT search area starts at second page on first block */ fcb->DBBTSearchAreaStartAddress = 1; - fcb->BadBlockMarkerByte = mxs_nand_mark_byte_offset(mtd); - fcb->BadBlockMarkerStartBit = mxs_nand_mark_bit_offset(mtd); + fcb->BadBlockMarkerByte = bb_mark_bit_offset >> 3; + fcb->BadBlockMarkerStartBit = bb_mark_bit_offset & 0x7; fcb->BBMarkerPhysicalOffset = mtd->writesize; diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 4317c30805..92d78db6c9 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -287,20 +287,6 @@ static uint32_t mxs_nand_aux_status_offset(void) return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3; } -uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size, - uint32_t page_oob_size) -{ - int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(page_data_size); - int ecc_strength = 0; - int gf_len = 13; /* length of Galois Field for non-DDR nand */ - - ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8) - / (gf_len * ecc_chunk_count); - - /* We need the minor even number. */ - return rounddown(ecc_strength, 2); -} - static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, uint32_t ecc_strength) { @@ -350,20 +336,6 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, return block_mark_bit_offset; } -uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd) -{ - uint32_t ecc_strength; - ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize); - return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3; -} - -uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd) -{ - uint32_t ecc_strength; - ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize); - return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7; -} - static int mxs_nand_calc_geo(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -387,6 +359,25 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd) return 0; } +static struct mtd_info *mxs_nand_mtd; + +int mxs_nand_get_geo(int *ecc_strength, int *bb_mark_bit_offset) +{ + struct nand_chip *chip; + struct mxs_nand_info *nand_info; + + if (!mxs_nand_mtd) + return -ENODEV; + + chip = mxs_nand_mtd->priv; + nand_info = chip->priv; + + *ecc_strength = chip->ecc.strength; + *bb_mark_bit_offset = nand_info->bb_mark_bit_offset; + + return 0; +} + /* * Wait for BCH complete IRQ and clear the IRQ */ @@ -2140,6 +2131,10 @@ static int mxs_nand_probe(struct device_d *dev) enum gpmi_type type; int err; + /* We expect only one */ + if (mxs_nand_mtd) + return -EBUSY; + err = dev_get_drvdata(dev, (const void **)&type); if (err) type = GPMI_MXS; @@ -2239,12 +2234,21 @@ static int mxs_nand_probe(struct device_d *dev) if (err) goto err2; - return add_mtd_nand_device(mtd, "nand"); + err = add_mtd_nand_device(mtd, "nand"); + if (err) + goto err2; + + mxs_nand_mtd = mtd; + + return 0; err2: free(nand_info->data_buf); free(nand_info->cmd_buf); err1: free(nand_info); + + mxs_nand_mtd = NULL; + return err; } diff --git a/include/linux/mtd/nand_mxs.h b/include/linux/mtd/nand_mxs.h index eca31777f5..7eda0b8e63 100644 --- a/include/linux/mtd/nand_mxs.h +++ b/include/linux/mtd/nand_mxs.h @@ -27,11 +27,6 @@ * update handler code, the generic calculation from the driver code is used. */ -uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size, - uint32_t page_oob_size); - -uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd); - -uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd); +int mxs_nand_get_geo(int *ecc_strength, int *bb_mark_bit_offset); #endif /* __NAND_MXS_H */ -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer ` (3 preceding siblings ...) 2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer ` (2 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List struct mtd_info * contains everything mxs_nand_get_mark_offset() needs, so pass this pointer rather than several integer arguments. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 92d78db6c9..2b2e80d4c5 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -287,9 +287,9 @@ static uint32_t mxs_nand_aux_status_offset(void) return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3; } -static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, - uint32_t ecc_strength) +static uint32_t mxs_nand_get_mark_offset(struct mtd_info *mtd) { + struct nand_chip *chip = mtd->priv; uint32_t chunk_data_size_in_bits; uint32_t chunk_ecc_size_in_bits; uint32_t chunk_total_size_in_bits; @@ -298,13 +298,13 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, uint32_t block_mark_bit_offset; chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8; - chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(ecc_strength); + chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(chip->ecc.strength); chunk_total_size_in_bits = chunk_data_size_in_bits + chunk_ecc_size_in_bits; /* Compute the bit offset of the block mark within the physical page. */ - block_mark_bit_offset = page_data_size * 8; + block_mark_bit_offset = mtd->writesize * 8; /* Subtract the metadata bits. */ block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8; @@ -353,8 +353,7 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd) chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8); chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; - nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd->writesize, - chip->ecc.strength); + nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd); return 0; } -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/8] mtd: nand-mxs: inline only once used function 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer ` (4 preceding siblings ...) 2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer 2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List mxs_nand_ecc_size_in_bits() is used only once and is simple enough to be inlined. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 2b2e80d4c5..7555b1013d 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -277,11 +277,6 @@ static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size) return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; } -static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength) -{ - return ecc_strength * 13; -} - static uint32_t mxs_nand_aux_status_offset(void) { return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3; @@ -298,7 +293,7 @@ static uint32_t mxs_nand_get_mark_offset(struct mtd_info *mtd) uint32_t block_mark_bit_offset; chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8; - chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(chip->ecc.strength); + chunk_ecc_size_in_bits = chip->ecc.strength * 13; chunk_total_size_in_bits = chunk_data_size_in_bits + chunk_ecc_size_in_bits; -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 7/8] mtd: nand: Add function to parse device tree properties 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer ` (5 preceding siblings ...) 2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List This adds nand_of_parse_node() which can be used to parse generic NAND device properties. Not very complete yet, but it's a start. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_base.c | 27 +++++++++++++++++++++++++++ include/linux/mtd/nand.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bf15e6ccee..e103eac596 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -43,6 +43,7 @@ #include <io.h> #include <malloc.h> #include <module.h> +#include <of_mtd.h> /* Define default oob placement schemes for large and small page devices */ static struct nand_ecclayout nand_oob_8 = { @@ -3506,6 +3507,32 @@ ident_done: return type; } +/** + * nand_of_parse_node - parse generic NAND properties + * @mtd: MTD device structure + * @np: Device node to read information from + * + * This parses device tree properties generic to NAND controllers and fills in + * the various fields in struct nand_chip. + */ +void nand_of_parse_node(struct mtd_info *mtd, struct device_node *np) +{ + struct nand_chip *chip = mtd->priv; + int ecc_strength, ecc_size; + + if (!IS_ENABLED(CONFIG_OFDEVICE)) + return; + + ecc_strength = of_get_nand_ecc_strength(np); + ecc_size = of_get_nand_ecc_step_size(np); + + if (ecc_strength >= 0) + chip->ecc.strength = ecc_strength; + + if (ecc_size >= 0) + chip->ecc.size = ecc_size; +} + /** * nand_scan_ident - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 785cb06030..7f17767c69 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -52,6 +52,8 @@ extern int nand_check_erased_ecc_chunk(void *data, int datalen, int bitflips_threshold); int nand_check_erased_buf(void *buf, int len, int bitflips_threshold); +void nand_of_parse_node(struct mtd_info *mtd, struct device_node *np); + /* The maximum number of NAND chips in an array */ #define NAND_MAX_CHIPS 8 -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer ` (6 preceding siblings ...) 2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer @ 2019-08-05 12:20 ` Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw) To: Barebox List According to the binding doc the mxs NAND driver supports the "nand-ecc-strength" and "nand-ecc-step-size" options. This adds support for these options to the driver. The "nand-ecc-step-size" is not really configurable, the only accepted value is 512 so this is merely to sanity check that there's nothing specified that we can't yet support. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/nand/nand_mxs.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 7555b1013d..b016c5bff0 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -336,14 +336,31 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd) struct nand_chip *chip = mtd->priv; struct mxs_nand_info *nand_info = chip->priv; int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(mtd->writesize); - int ecc_strength; int gf_len = 13; /* length of Galois Field for non-DDR nand */ + int max_ecc_strength; - ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) - / (gf_len * ecc_chunk_count); + nand_of_parse_node(mtd, mtd->parent->device_node); + max_ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) + / (gf_len * ecc_chunk_count); /* We need the minor even number. */ - chip->ecc.strength = rounddown(ecc_strength, 2); + max_ecc_strength = rounddown(max_ecc_strength, 2); + + if (chip->ecc.strength) { + if (chip->ecc.strength > max_ecc_strength) { + dev_err(nand_info->dev, "invalid ecc strength %d (maximum %d)\n", + chip->ecc.strength, max_ecc_strength); + return -EINVAL; + } + } else { + chip->ecc.strength = max_ecc_strength; + } + + if (chip->ecc.size && chip->ecc.size != MXS_NAND_CHUNK_DATA_CHUNK_SIZE) { + dev_err(nand_info->dev, "invalid ecc size %d, this driver only supports %d\n", + chip->ecc.size, MXS_NAND_CHUNK_DATA_CHUNK_SIZE); + return -EINVAL; + } chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8); chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-08-05 12:20 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer 2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer 2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer 2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer 2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer 2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer 2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer 2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer 2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox