Skip to content

Commit 76dc2bf

Browse files
committed
Merge tag 'mtd/fixes-for-5.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd fixes from Miquel Raynal: "Because of a recent change in the core, NAND controller drivers initializing the ECC engine too early in the probe path are broken. Drivers should wait for the NAND device to be discovered and its memory layout known before doing any ECC related initialization, so instead of reverting the faulty change which is actually moving in the right direction, let's fix the drivers directly: socrates, sharpsl, r852, plat_nand, pasemi, tmio, txx9ndfmc, orion, mpc5121, lpc32xx_slc, lpc32xx_mlc, fsmc, diskonchip, davinci, cs553x, au1550, ams-delta, xway and gpio" * tag 'mtd/fixes-for-5.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: rawnand: socrates: Move the ECC initialization to ->attach_chip() mtd: rawnand: sharpsl: Move the ECC initialization to ->attach_chip() mtd: rawnand: r852: Move the ECC initialization to ->attach_chip() mtd: rawnand: plat_nand: Move the ECC initialization to ->attach_chip() mtd: rawnand: pasemi: Move the ECC initialization to ->attach_chip() mtd: rawnand: tmio: Move the ECC initialization to ->attach_chip() mtd: rawnand: txx9ndfmc: Move the ECC initialization to ->attach_chip() mtd: rawnand: orion: Move the ECC initialization to ->attach_chip() mtd: rawnand: mpc5121: Move the ECC initialization to ->attach_chip() mtd: rawnand: lpc32xx_slc: Move the ECC initialization to ->attach_chip() mtd: rawnand: lpc32xx_mlc: Move the ECC initialization to ->attach_chip() mtd: rawnand: fsmc: Move the ECC initialization to ->attach_chip() mtd: rawnand: diskonchip: Move the ECC initialization to ->attach_chip() mtd: rawnand: davinci: Move the ECC initialization to ->attach_chip() mtd: rawnand: cs553x: Move the ECC initialization to ->attach_chip() mtd: rawnand: au1550: Move the ECC initialization to ->attach_chip() mtd: rawnand: ams-delta: Move the ECC initialization to ->attach_chip() mtd: rawnand: xway: Move the ECC initialization to ->attach_chip() mtd: rawnand: gpio: Move the ECC initialization to ->attach_chip()
2 parents 87c301c + b36bf0a commit 76dc2bf

20 files changed

Lines changed: 294 additions & 116 deletions

drivers/mtd/nand/raw/ams-delta.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,17 @@ static int gpio_nand_setup_interface(struct nand_chip *this, int csline,
215215
return 0;
216216
}
217217

218+
static int gpio_nand_attach_chip(struct nand_chip *chip)
219+
{
220+
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
221+
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
222+
223+
return 0;
224+
}
225+
218226
static const struct nand_controller_ops gpio_nand_ops = {
219227
.exec_op = gpio_nand_exec_op,
228+
.attach_chip = gpio_nand_attach_chip,
220229
.setup_interface = gpio_nand_setup_interface,
221230
};
222231

@@ -260,9 +269,6 @@ static int gpio_nand_probe(struct platform_device *pdev)
260269
return err;
261270
}
262271

263-
this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
264-
this->ecc.algo = NAND_ECC_ALGO_HAMMING;
265-
266272
platform_set_drvdata(pdev, priv);
267273

268274
/* Set chip enabled but write protected */

drivers/mtd/nand/raw/au1550nd.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,17 @@ static int au1550nd_exec_op(struct nand_chip *this,
236236
return ret;
237237
}
238238

239+
static int au1550nd_attach_chip(struct nand_chip *chip)
240+
{
241+
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
242+
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
243+
244+
return 0;
245+
}
246+
239247
static const struct nand_controller_ops au1550nd_ops = {
240248
.exec_op = au1550nd_exec_op,
249+
.attach_chip = au1550nd_attach_chip,
241250
};
242251

243252
static int au1550nd_probe(struct platform_device *pdev)
@@ -294,8 +303,6 @@ static int au1550nd_probe(struct platform_device *pdev)
294303
nand_controller_init(&ctx->controller);
295304
ctx->controller.ops = &au1550nd_ops;
296305
this->controller = &ctx->controller;
297-
this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
298-
this->ecc.algo = NAND_ECC_ALGO_HAMMING;
299306

300307
if (pd->devwidth)
301308
this->options |= NAND_BUSWIDTH_16;

drivers/mtd/nand/raw/cs553x_nand.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,24 @@ static int cs_calculate_ecc(struct nand_chip *this, const u_char *dat,
243243

244244
static struct cs553x_nand_controller *controllers[4];
245245

246+
static int cs553x_attach_chip(struct nand_chip *chip)
247+
{
248+
if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
249+
return 0;
250+
251+
chip->ecc.size = 256;
252+
chip->ecc.bytes = 3;
253+
chip->ecc.hwctl = cs_enable_hwecc;
254+
chip->ecc.calculate = cs_calculate_ecc;
255+
chip->ecc.correct = nand_correct_data;
256+
chip->ecc.strength = 1;
257+
258+
return 0;
259+
}
260+
246261
static const struct nand_controller_ops cs553x_nand_controller_ops = {
247262
.exec_op = cs553x_exec_op,
263+
.attach_chip = cs553x_attach_chip,
248264
};
249265

250266
static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
@@ -286,14 +302,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
286302
goto out_mtd;
287303
}
288304

289-
this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
290-
this->ecc.size = 256;
291-
this->ecc.bytes = 3;
292-
this->ecc.hwctl = cs_enable_hwecc;
293-
this->ecc.calculate = cs_calculate_ecc;
294-
this->ecc.correct = nand_correct_data;
295-
this->ecc.strength = 1;
296-
297305
/* Enable the following for a flash based bad block table */
298306
this->bbt_options = NAND_BBT_USE_FLASH;
299307

drivers/mtd/nand/raw/davinci_nand.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,10 @@ static int davinci_nand_attach_chip(struct nand_chip *chip)
585585
if (IS_ERR(pdata))
586586
return PTR_ERR(pdata);
587587

588+
/* Use board-specific ECC config */
589+
info->chip.ecc.engine_type = pdata->engine_type;
590+
info->chip.ecc.placement = pdata->ecc_placement;
591+
588592
switch (info->chip.ecc.engine_type) {
589593
case NAND_ECC_ENGINE_TYPE_NONE:
590594
pdata->ecc_bits = 0;
@@ -850,10 +854,6 @@ static int nand_davinci_probe(struct platform_device *pdev)
850854
info->mask_ale = pdata->mask_ale ? : MASK_ALE;
851855
info->mask_cle = pdata->mask_cle ? : MASK_CLE;
852856

853-
/* Use board-specific ECC config */
854-
info->chip.ecc.engine_type = pdata->engine_type;
855-
info->chip.ecc.placement = pdata->ecc_placement;
856-
857857
spin_lock_irq(&davinci_nand_lock);
858858

859859
/* put CSxNAND into NAND mode */

drivers/mtd/nand/raw/diskonchip.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,12 +1269,31 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
12691269
return 1;
12701270
}
12711271

1272+
static int doc200x_attach_chip(struct nand_chip *chip)
1273+
{
1274+
if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
1275+
return 0;
1276+
1277+
chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
1278+
chip->ecc.size = 512;
1279+
chip->ecc.bytes = 6;
1280+
chip->ecc.strength = 2;
1281+
chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
1282+
chip->ecc.hwctl = doc200x_enable_hwecc;
1283+
chip->ecc.calculate = doc200x_calculate_ecc;
1284+
chip->ecc.correct = doc200x_correct_data;
1285+
1286+
return 0;
1287+
}
1288+
12721289
static const struct nand_controller_ops doc200x_ops = {
12731290
.exec_op = doc200x_exec_op,
1291+
.attach_chip = doc200x_attach_chip,
12741292
};
12751293

12761294
static const struct nand_controller_ops doc2001plus_ops = {
12771295
.exec_op = doc2001plus_exec_op,
1296+
.attach_chip = doc200x_attach_chip,
12781297
};
12791298

12801299
static int __init doc_probe(unsigned long physadr)
@@ -1452,16 +1471,6 @@ static int __init doc_probe(unsigned long physadr)
14521471

14531472
nand->controller = &doc->base;
14541473
nand_set_controller_data(nand, doc);
1455-
nand->ecc.hwctl = doc200x_enable_hwecc;
1456-
nand->ecc.calculate = doc200x_calculate_ecc;
1457-
nand->ecc.correct = doc200x_correct_data;
1458-
1459-
nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
1460-
nand->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
1461-
nand->ecc.size = 512;
1462-
nand->ecc.bytes = 6;
1463-
nand->ecc.strength = 2;
1464-
nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
14651474
nand->bbt_options = NAND_BBT_USE_FLASH;
14661475
/* Skip the automatic BBT scan so we can run it manually */
14671476
nand->options |= NAND_SKIP_BBTSCAN | NAND_NO_BBM_QUIRK;

drivers/mtd/nand/raw/fsmc_nand.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,20 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand)
880880
struct mtd_info *mtd = nand_to_mtd(nand);
881881
struct fsmc_nand_data *host = nand_to_fsmc(nand);
882882

883+
if (nand->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID)
884+
nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
885+
886+
if (!nand->ecc.size)
887+
nand->ecc.size = 512;
888+
889+
if (AMBA_REV_BITS(host->pid) >= 8) {
890+
nand->ecc.read_page = fsmc_read_page_hwecc;
891+
nand->ecc.calculate = fsmc_read_hwecc_ecc4;
892+
nand->ecc.correct = fsmc_bch8_correct_data;
893+
nand->ecc.bytes = 13;
894+
nand->ecc.strength = 8;
895+
}
896+
883897
if (AMBA_REV_BITS(host->pid) >= 8) {
884898
switch (mtd->oobsize) {
885899
case 16:
@@ -905,6 +919,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand)
905919
dev_info(host->dev, "Using 1-bit HW ECC scheme\n");
906920
nand->ecc.calculate = fsmc_read_hwecc_ecc1;
907921
nand->ecc.correct = nand_correct_data;
922+
nand->ecc.hwctl = fsmc_enable_hwecc;
908923
nand->ecc.bytes = 3;
909924
nand->ecc.strength = 1;
910925
nand->ecc.options |= NAND_ECC_SOFT_HAMMING_SM_ORDER;
@@ -1055,13 +1070,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
10551070

10561071
mtd->dev.parent = &pdev->dev;
10571072

1058-
/*
1059-
* Setup default ECC mode. nand_dt_init() called from nand_scan_ident()
1060-
* can overwrite this value if the DT provides a different value.
1061-
*/
1062-
nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
1063-
nand->ecc.hwctl = fsmc_enable_hwecc;
1064-
nand->ecc.size = 512;
10651073
nand->badblockbits = 7;
10661074

10671075
if (host->mode == USE_DMA_ACCESS) {
@@ -1084,14 +1092,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
10841092
nand->options |= NAND_KEEP_TIMINGS;
10851093
}
10861094

1087-
if (AMBA_REV_BITS(host->pid) >= 8) {
1088-
nand->ecc.read_page = fsmc_read_page_hwecc;
1089-
nand->ecc.calculate = fsmc_read_hwecc_ecc4;
1090-
nand->ecc.correct = fsmc_bch8_correct_data;
1091-
nand->ecc.bytes = 13;
1092-
nand->ecc.strength = 8;
1093-
}
1094-
10951095
nand_controller_init(&host->base);
10961096
host->base.ops = &fsmc_nand_controller_ops;
10971097
nand->controller = &host->base;

drivers/mtd/nand/raw/gpio.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,17 @@ static int gpio_nand_exec_op(struct nand_chip *chip,
161161
return ret;
162162
}
163163

164+
static int gpio_nand_attach_chip(struct nand_chip *chip)
165+
{
166+
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
167+
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
168+
169+
return 0;
170+
}
171+
164172
static const struct nand_controller_ops gpio_nand_ops = {
165173
.exec_op = gpio_nand_exec_op,
174+
.attach_chip = gpio_nand_attach_chip,
166175
};
167176

168177
#ifdef CONFIG_OF
@@ -342,8 +351,6 @@ static int gpio_nand_probe(struct platform_device *pdev)
342351
gpiomtd->base.ops = &gpio_nand_ops;
343352

344353
nand_set_flash_node(chip, pdev->dev.of_node);
345-
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
346-
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
347354
chip->options = gpiomtd->plat.options;
348355
chip->controller = &gpiomtd->base;
349356

drivers/mtd/nand/raw/lpc32xx_mlc.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,9 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
648648
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
649649
struct device *dev = &host->pdev->dev;
650650

651+
if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
652+
return 0;
653+
651654
host->dma_buf = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL);
652655
if (!host->dma_buf)
653656
return -ENOMEM;
@@ -656,8 +659,17 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
656659
if (!host->dummy_buf)
657660
return -ENOMEM;
658661

659-
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
660662
chip->ecc.size = 512;
663+
chip->ecc.hwctl = lpc32xx_ecc_enable;
664+
chip->ecc.read_page_raw = lpc32xx_read_page;
665+
chip->ecc.read_page = lpc32xx_read_page;
666+
chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel;
667+
chip->ecc.write_page = lpc32xx_write_page_lowlevel;
668+
chip->ecc.write_oob = lpc32xx_write_oob;
669+
chip->ecc.read_oob = lpc32xx_read_oob;
670+
chip->ecc.strength = 4;
671+
chip->ecc.bytes = 10;
672+
661673
mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
662674
host->mlcsubpages = mtd->writesize / 512;
663675

@@ -741,15 +753,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
741753
platform_set_drvdata(pdev, host);
742754

743755
/* Initialize function pointers */
744-
nand_chip->ecc.hwctl = lpc32xx_ecc_enable;
745-
nand_chip->ecc.read_page_raw = lpc32xx_read_page;
746-
nand_chip->ecc.read_page = lpc32xx_read_page;
747-
nand_chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel;
748-
nand_chip->ecc.write_page = lpc32xx_write_page_lowlevel;
749-
nand_chip->ecc.write_oob = lpc32xx_write_oob;
750-
nand_chip->ecc.read_oob = lpc32xx_read_oob;
751-
nand_chip->ecc.strength = 4;
752-
nand_chip->ecc.bytes = 10;
753756
nand_chip->legacy.waitfunc = lpc32xx_waitfunc;
754757

755758
nand_chip->options = NAND_NO_SUBPAGE_WRITE;

drivers/mtd/nand/raw/lpc32xx_slc.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,9 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
775775
struct mtd_info *mtd = nand_to_mtd(chip);
776776
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
777777

778+
if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
779+
return 0;
780+
778781
/* OOB and ECC CPU and DMA work areas */
779782
host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE);
780783

@@ -786,11 +789,22 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
786789
if (mtd->writesize <= 512)
787790
mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
788791

792+
chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
789793
/* These sizes remain the same regardless of page size */
790794
chip->ecc.size = 256;
795+
chip->ecc.strength = 1;
791796
chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES;
792797
chip->ecc.prepad = 0;
793798
chip->ecc.postpad = 0;
799+
chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome;
800+
chip->ecc.read_page = lpc32xx_nand_read_page_syndrome;
801+
chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome;
802+
chip->ecc.write_page = lpc32xx_nand_write_page_syndrome;
803+
chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
804+
chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
805+
chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
806+
chip->ecc.correct = nand_correct_data;
807+
chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
794808

795809
/*
796810
* Use a custom BBT marker setup for small page FLASH that
@@ -881,21 +895,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
881895
platform_set_drvdata(pdev, host);
882896

883897
/* NAND callbacks for LPC32xx SLC hardware */
884-
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
885-
chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
886898
chip->legacy.read_byte = lpc32xx_nand_read_byte;
887899
chip->legacy.read_buf = lpc32xx_nand_read_buf;
888900
chip->legacy.write_buf = lpc32xx_nand_write_buf;
889-
chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome;
890-
chip->ecc.read_page = lpc32xx_nand_read_page_syndrome;
891-
chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome;
892-
chip->ecc.write_page = lpc32xx_nand_write_page_syndrome;
893-
chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
894-
chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
895-
chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
896-
chip->ecc.correct = nand_correct_data;
897-
chip->ecc.strength = 1;
898-
chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
899901

900902
/*
901903
* Allocate a large enough buffer for a single huge page plus

drivers/mtd/nand/raw/mpc5121_nfc.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
#define NFC_TIMEOUT (HZ / 10) /* 1/10 s */
105105

106106
struct mpc5121_nfc_prv {
107+
struct nand_controller controller;
107108
struct nand_chip chip;
108109
int irq;
109110
void __iomem *regs;
@@ -602,6 +603,18 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
602603
iounmap(prv->csreg);
603604
}
604605

606+
static int mpc5121_nfc_attach_chip(struct nand_chip *chip)
607+
{
608+
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
609+
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
610+
611+
return 0;
612+
}
613+
614+
static const struct nand_controller_ops mpc5121_nfc_ops = {
615+
.attach_chip = mpc5121_nfc_attach_chip,
616+
};
617+
605618
static int mpc5121_nfc_probe(struct platform_device *op)
606619
{
607620
struct device_node *dn = op->dev.of_node;
@@ -634,6 +647,10 @@ static int mpc5121_nfc_probe(struct platform_device *op)
634647
chip = &prv->chip;
635648
mtd = nand_to_mtd(chip);
636649

650+
nand_controller_init(&prv->controller);
651+
prv->controller.ops = &mpc5121_nfc_ops;
652+
chip->controller = &prv->controller;
653+
637654
mtd->dev.parent = dev;
638655
nand_set_controller_data(chip, prv);
639656
nand_set_flash_node(chip, dn);
@@ -688,8 +705,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
688705
chip->legacy.set_features = nand_get_set_features_notsupp;
689706
chip->legacy.get_features = nand_get_set_features_notsupp;
690707
chip->bbt_options = NAND_BBT_USE_FLASH;
691-
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
692-
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
693708

694709
/* Support external chip-select logic on ADS5121 board */
695710
if (of_machine_is_compatible("fsl,mpc5121ads")) {

0 commit comments

Comments
 (0)