--- zzzz-none-000/linux-3.10.107/drivers/mtd/nand/davinci_nand.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mtd/nand/davinci_nand.c 2021-02-04 17:41:59.000000000 +0000 @@ -24,7 +24,6 @@ */ #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include #include @@ -490,7 +490,7 @@ * ten ECC bytes plus the manufacturer's bad block marker byte, and * and not overlapping the default BBT markers. */ -static struct nand_ecclayout hwecc4_small __initconst = { +static struct nand_ecclayout hwecc4_small = { .eccbytes = 10, .eccpos = { 0, 1, 2, 3, 4, /* offset 5 holds the badblock marker */ @@ -506,7 +506,7 @@ * storing ten ECC bytes plus the manufacturer's bad block marker byte, * and not overlapping the default BBT markers. */ -static struct nand_ecclayout hwecc4_2048 __initconst = { +static struct nand_ecclayout hwecc4_2048 = { .eccbytes = 40, .eccpos = { /* at the end of spare sector */ @@ -523,9 +523,36 @@ }, }; +/* + * An ECC layout for using 4-bit ECC with large-page (4096bytes) flash, + * storing ten ECC bytes plus the manufacturer's bad block marker byte, + * and not overlapping the default BBT markers. + */ +static struct nand_ecclayout hwecc4_4096 = { + .eccbytes = 80, + .eccpos = { + /* at the end of spare sector */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + }, + .oobfree = { + /* 2 bytes at offset 0 hold manufacturer badblock markers */ + {.offset = 2, .length = 46, }, + /* 5 bytes at offset 8 hold BBT markers */ + /* 8 bytes at offset 16 hold JFFS2 clean markers */ + }, +}; + #if defined(CONFIG_OF) static const struct of_device_id davinci_nand_of_match[] = { {.compatible = "ti,davinci-nand", }, + {.compatible = "ti,keystone-nand", }, {}, }; MODULE_DEVICE_TABLE(of, davinci_nand_of_match); @@ -533,21 +560,23 @@ static struct davinci_nand_pdata *nand_davinci_get_pdata(struct platform_device *pdev) { - if (!pdev->dev.platform_data && pdev->dev.of_node) { + if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { struct davinci_nand_pdata *pdata; const char *mode; u32 prop; - int len; pdata = devm_kzalloc(&pdev->dev, sizeof(struct davinci_nand_pdata), GFP_KERNEL); pdev->dev.platform_data = pdata; if (!pdata) - return NULL; + return ERR_PTR(-ENOMEM); if (!of_property_read_u32(pdev->dev.of_node, "ti,davinci-chipselect", &prop)) pdev->id = prop; + else + return ERR_PTR(-EINVAL); + if (!of_property_read_u32(pdev->dev.of_node, "ti,davinci-mask-ale", &prop)) pdata->mask_ale = prop; @@ -558,6 +587,8 @@ "ti,davinci-mask-chipsel", &prop)) pdata->mask_chipsel = prop; if (!of_property_read_string(pdev->dev.of_node, + "nand-ecc-mode", &mode) || + !of_property_read_string(pdev->dev.of_node, "ti,davinci-ecc-mode", &mode)) { if (!strncmp("none", mode, 4)) pdata->ecc_mode = NAND_ECC_NONE; @@ -569,26 +600,35 @@ if (!of_property_read_u32(pdev->dev.of_node, "ti,davinci-ecc-bits", &prop)) pdata->ecc_bits = prop; - if (!of_property_read_u32(pdev->dev.of_node, + + prop = of_get_nand_bus_width(pdev->dev.of_node); + if (0 < prop || !of_property_read_u32(pdev->dev.of_node, "ti,davinci-nand-buswidth", &prop)) if (prop == 16) pdata->options |= NAND_BUSWIDTH_16; - if (of_find_property(pdev->dev.of_node, - "ti,davinci-nand-use-bbt", &len)) + if (of_property_read_bool(pdev->dev.of_node, + "nand-on-flash-bbt") || + of_property_read_bool(pdev->dev.of_node, + "ti,davinci-nand-use-bbt")) pdata->bbt_options = NAND_BBT_USE_FLASH; + + if (of_device_is_compatible(pdev->dev.of_node, + "ti,keystone-nand")) { + pdata->options |= NAND_NO_SUBPAGE_WRITE; + } } - return pdev->dev.platform_data; + return dev_get_platdata(&pdev->dev); } #else static struct davinci_nand_pdata *nand_davinci_get_pdata(struct platform_device *pdev) { - return pdev->dev.platform_data; + return dev_get_platdata(&pdev->dev); } #endif -static int __init nand_davinci_probe(struct platform_device *pdev) +static int nand_davinci_probe(struct platform_device *pdev) { struct davinci_nand_pdata *pdata; struct davinci_nand_info *info; @@ -601,6 +641,9 @@ nand_ecc_modes_t ecc_mode; pdata = nand_davinci_get_pdata(pdev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + /* insist on board-specific configuration */ if (!pdata) return -ENODEV; @@ -610,11 +653,8 @@ return -ENODEV; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) { - dev_err(&pdev->dev, "unable to allocate memory\n"); - ret = -ENOMEM; - goto err_nomem; - } + if (!info) + return -ENOMEM; platform_set_drvdata(pdev, info); @@ -622,16 +662,23 @@ res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res1 || !res2) { dev_err(&pdev->dev, "resource missing\n"); - ret = -EINVAL; - goto err_nomem; + return -EINVAL; } - vaddr = devm_request_and_ioremap(&pdev->dev, res1); - base = devm_request_and_ioremap(&pdev->dev, res2); - if (!vaddr || !base) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -EADDRNOTAVAIL; - goto err_ioremap; + vaddr = devm_ioremap_resource(&pdev->dev, res1); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + /* + * This registers range is used to setup NAND settings. In case with + * TI AEMIF driver, the same memory address range is requested already + * by AEMIF, so we cannot request it twice, just ioremap. + * The AEMIF and NAND drivers not use the same registers in this range. + */ + base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); + if (!base) { + dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); + return -EADDRNOTAVAIL; } info->dev = &pdev->dev; @@ -639,9 +686,6 @@ info->vaddr = vaddr; info->mtd.priv = &info->chip; - info->mtd.name = dev_name(&pdev->dev); - info->mtd.owner = THIS_MODULE; - info->mtd.dev.parent = &pdev->dev; info->chip.IO_ADDR_R = vaddr; @@ -699,7 +743,7 @@ spin_unlock_irq(&davinci_nand_lock); if (ret == -EBUSY) - goto err_ecc; + return ret; info->chip.ecc.calculate = nand_davinci_calculate_4bit; info->chip.ecc.correct = nand_davinci_correct_4bit; @@ -715,8 +759,7 @@ info->chip.ecc.strength = pdata->ecc_bits; break; default: - ret = -EINVAL; - goto err_ecc; + return -EINVAL; } info->chip.ecc.mode = ecc_mode; @@ -724,7 +767,7 @@ if (IS_ERR(info->clk)) { ret = PTR_ERR(info->clk); dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); - goto err_clk; + return ret; } ret = clk_prepare_enable(info->clk); @@ -734,28 +777,6 @@ goto err_clk_enable; } - /* - * Setup Async configuration register in case we did not boot from - * NAND and so bootloader did not bother to set it up. - */ - val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4); - - /* Extended Wait is not valid and Select Strobe mode is not used */ - val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK); - if (info->chip.options & NAND_BUSWIDTH_16) - val |= 0x1; - - davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val); - - ret = 0; - if (info->timing) - ret = davinci_aemif_setup_timing(info->timing, info->base, - info->core_chipsel); - if (ret < 0) { - dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); - goto err_timing; - } - spin_lock_irq(&davinci_nand_lock); /* put CSxNAND into NAND mode */ @@ -769,7 +790,7 @@ ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL); if (ret < 0) { dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); - goto err_scan; + goto err; } /* Update ECC layout if needed ... for 1-bit HW ECC, the default @@ -783,7 +804,7 @@ if (!chunks || info->mtd.oobsize < 16) { dev_dbg(&pdev->dev, "too small\n"); ret = -EINVAL; - goto err_scan; + goto err; } /* For small page chips, preserve the manufacturer's @@ -801,20 +822,14 @@ info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; goto syndrome_done; } + if (chunks == 8) { + info->ecclayout = hwecc4_4096; + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; + goto syndrome_done; + } - /* 4KiB page chips are not yet supported. The eccpos from - * nand_ecclayout cannot hold 80 bytes and change to eccpos[] - * breaks userspace ioctl interface with mtd-utils. Once we - * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used - * for the 4KiB page chips. - * - * TODO: Note that nand_ecclayout has now been expanded and can - * hold plenty of OOB entries. - */ - dev_warn(&pdev->dev, "no 4-bit ECC support yet " - "for 4KiB-page NAND\n"); ret = -EIO; - goto err_scan; + goto err; syndrome_done: info->chip.ecc.layout = &info->ecclayout; @@ -822,7 +837,7 @@ ret = nand_scan_tail(&info->mtd); if (ret < 0) - goto err_scan; + goto err; if (pdata->parts) ret = mtd_device_parse_register(&info->mtd, NULL, NULL, @@ -835,7 +850,7 @@ NULL, 0); } if (ret < 0) - goto err_scan; + goto err; val = davinci_nand_readl(info, NRCSR_OFFSET); dev_info(&pdev->dev, "controller rev. %d.%d\n", @@ -843,8 +858,7 @@ return 0; -err_scan: -err_timing: +err: clk_disable_unprepare(info->clk); err_clk_enable: @@ -852,15 +866,10 @@ if (ecc_mode == NAND_ECC_HW_SYNDROME) ecc4_busy = false; spin_unlock_irq(&davinci_nand_lock); - -err_ecc: -err_clk: -err_ioremap: -err_nomem: return ret; } -static int __exit nand_davinci_remove(struct platform_device *pdev) +static int nand_davinci_remove(struct platform_device *pdev) { struct davinci_nand_info *info = platform_get_drvdata(pdev); @@ -877,16 +886,16 @@ } static struct platform_driver nand_davinci_driver = { - .remove = __exit_p(nand_davinci_remove), + .probe = nand_davinci_probe, + .remove = nand_davinci_remove, .driver = { .name = "davinci_nand", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(davinci_nand_of_match), }, }; MODULE_ALIAS("platform:davinci_nand"); -module_platform_driver_probe(nand_davinci_driver, nand_davinci_probe); +module_platform_driver(nand_davinci_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Texas Instruments");