diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 13:17:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 13:17:30 -0400 |
commit | c29aa153ef0469cddf0146d41ce6494bd76be78b (patch) | |
tree | b49af4e6cf54e9988dd45640a86c4de7f49ddf6d /drivers/mtd/nand | |
parent | 2b3a8fd735f86ebeb2b9d061054003000c36b654 (diff) | |
parent | 4a4163caccae97a23d97c29032664ee7b7a498d0 (diff) |
Merge tag 'for-linus-20140405' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris:
- A few SPI NOR ID definitions
- Kill the NAND "max pagesize" restriction
- Fix some x16 bus-width NAND support
- Add NAND JEDEC parameter page support
- DT bindings for NAND ECC
- GPMI NAND updates (subpage reads)
- More OMAP NAND refactoring
- New STMicro SPI NOR driver (now in 40 patches!)
- A few other random bugfixes
* tag 'for-linus-20140405' of git://git.infradead.org/linux-mtd: (120 commits)
Fix index regression in nand_read_subpage
mtd: diskonchip: mem resource name is not optional
mtd: nand: fix mention to CONFIG_MTD_NAND_ECC_BCH
mtd: nand: fix GET/SET_FEATURES address on 16-bit devices
mtd: omap2: Use devm_ioremap_resource()
mtd: denali_dt: Use devm_ioremap_resource()
mtd: devices: elm: update DRIVER_NAME as "omap-elm"
mtd: devices: elm: configure parallel channels based on ecc_steps
mtd: devices: elm: clean elm_load_syndrome
mtd: devices: elm: check for hardware engine's design constraints
mtd: st_spi_fsm: Succinctly reorganise .remove()
mtd: st_spi_fsm: Allow loop to run at least once before giving up CPU
mtd: st_spi_fsm: Correct vendor name spelling issue - missing "M"
mtd: st_spi_fsm: Avoid duplicating MTD core code
mtd: st_spi_fsm: Remove useless consts from function arguments
mtd: st_spi_fsm: Convert ST SPI FSM (NOR) Flash driver to new DT partitions
mtd: st_spi_fsm: Move runtime configurable msg sequences into device's struct
mtd: st_spi_fsm: Supply the W25Qxxx chip specific configuration call-back
mtd: st_spi_fsm: Supply the S25FLxxx chip specific configuration call-back
mtd: st_spi_fsm: Supply the MX25xxx chip specific configuration call-back
...
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/ams-delta.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 14 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/bf5xx_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 68 | ||||
-rw-r--r-- | drivers/mtd/nand/davinci_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/denali_dt.c | 39 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/gpio.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 102 | ||||
-rw-r--r-- | drivers/mtd/nand/mpc5121_nfc.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 165 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_ids.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/nuc900_nand.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/omap2.c | 512 | ||||
-rw-r--r-- | drivers/mtd/nand/pasemi_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410.c | 1 |
22 files changed, 527 insertions, 407 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index a4bee41ad5cb..f1cf503517fd 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -460,6 +460,8 @@ config MTD_NAND_MXC | |||
460 | config MTD_NAND_SH_FLCTL | 460 | config MTD_NAND_SH_FLCTL |
461 | tristate "Support for NAND on Renesas SuperH FLCTL" | 461 | tristate "Support for NAND on Renesas SuperH FLCTL" |
462 | depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST | 462 | depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST |
463 | depends on HAS_IOMEM | ||
464 | depends on HAS_DMA | ||
463 | help | 465 | help |
464 | Several Renesas SuperH CPU has FLCTL. This option enables support | 466 | Several Renesas SuperH CPU has FLCTL. This option enables support |
465 | for NAND Flash using FLCTL. | 467 | for NAND Flash using FLCTL. |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 8611eb4b45fc..4936e9e0002f 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -17,7 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <linux/mtd/mtd.h> | 22 | #include <linux/mtd/mtd.h> |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index c36e9b84487c..4ce181a35bcd 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -430,7 +430,7 @@ err_dma: | |||
430 | dma_unmap_single(dma_dev->dev, phys_addr, len, dir); | 430 | dma_unmap_single(dma_dev->dev, phys_addr, len, dir); |
431 | err_buf: | 431 | err_buf: |
432 | if (err != 0) | 432 | if (err != 0) |
433 | dev_warn(host->dev, "Fall back to CPU I/O\n"); | 433 | dev_dbg(host->dev, "Fall back to CPU I/O\n"); |
434 | return err; | 434 | return err; |
435 | } | 435 | } |
436 | 436 | ||
@@ -1220,6 +1220,7 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, | |||
1220 | goto err; | 1220 | goto err; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | nand_chip->options |= NAND_NO_SUBPAGE_WRITE; | ||
1223 | nand_chip->ecc.read_page = atmel_nand_pmecc_read_page; | 1224 | nand_chip->ecc.read_page = atmel_nand_pmecc_read_page; |
1224 | nand_chip->ecc.write_page = atmel_nand_pmecc_write_page; | 1225 | nand_chip->ecc.write_page = atmel_nand_pmecc_write_page; |
1225 | 1226 | ||
@@ -1659,8 +1660,8 @@ static void nfc_select_chip(struct mtd_info *mtd, int chip) | |||
1659 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_ENABLE); | 1660 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_ENABLE); |
1660 | } | 1661 | } |
1661 | 1662 | ||
1662 | static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr, | 1663 | static int nfc_make_addr(struct mtd_info *mtd, int command, int column, |
1663 | unsigned int *addr1234, unsigned int *cycle0) | 1664 | int page_addr, unsigned int *addr1234, unsigned int *cycle0) |
1664 | { | 1665 | { |
1665 | struct nand_chip *chip = mtd->priv; | 1666 | struct nand_chip *chip = mtd->priv; |
1666 | 1667 | ||
@@ -1674,7 +1675,8 @@ static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr, | |||
1674 | *addr1234 = 0; | 1675 | *addr1234 = 0; |
1675 | 1676 | ||
1676 | if (column != -1) { | 1677 | if (column != -1) { |
1677 | if (chip->options & NAND_BUSWIDTH_16) | 1678 | if (chip->options & NAND_BUSWIDTH_16 && |
1679 | !nand_opcode_8bits(command)) | ||
1678 | column >>= 1; | 1680 | column >>= 1; |
1679 | addr_bytes[acycle++] = column & 0xff; | 1681 | addr_bytes[acycle++] = column & 0xff; |
1680 | if (mtd->writesize > 512) | 1682 | if (mtd->writesize > 512) |
@@ -1787,8 +1789,8 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, | |||
1787 | } | 1789 | } |
1788 | 1790 | ||
1789 | if (do_addr) | 1791 | if (do_addr) |
1790 | acycle = nfc_make_addr(mtd, column, page_addr, &addr1234, | 1792 | acycle = nfc_make_addr(mtd, command, column, page_addr, |
1791 | &cycle0); | 1793 | &addr1234, &cycle0); |
1792 | 1794 | ||
1793 | nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; | 1795 | nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; |
1794 | nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); | 1796 | nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 2880d888cfc5..bc5c518828d2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
16 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
17 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
@@ -308,7 +307,8 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
308 | /* Serially input address */ | 307 | /* Serially input address */ |
309 | if (column != -1) { | 308 | if (column != -1) { |
310 | /* Adjust columns for 16 bit buswidth */ | 309 | /* Adjust columns for 16 bit buswidth */ |
311 | if (this->options & NAND_BUSWIDTH_16) | 310 | if (this->options & NAND_BUSWIDTH_16 && |
311 | !nand_opcode_8bits(command)) | ||
312 | column >>= 1; | 312 | column >>= 1; |
313 | ctx->write_byte(mtd, column); | 313 | ctx->write_byte(mtd, column); |
314 | } | 314 | } |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 94f55dbde995..b7a24946ca26 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/init.h> | ||
41 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
42 | #include <linux/string.h> | 41 | #include <linux/string.h> |
43 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index f2f64addb5e8..4e66726da9aa 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -627,6 +627,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
627 | struct cafe_priv *cafe; | 627 | struct cafe_priv *cafe; |
628 | uint32_t ctrl; | 628 | uint32_t ctrl; |
629 | int err = 0; | 629 | int err = 0; |
630 | int old_dma; | ||
631 | struct nand_buffers *nbuf; | ||
630 | 632 | ||
631 | /* Very old versions shared the same PCI ident for all three | 633 | /* Very old versions shared the same PCI ident for all three |
632 | functions on the chip. Verify the class too... */ | 634 | functions on the chip. Verify the class too... */ |
@@ -655,13 +657,6 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
655 | err = -ENOMEM; | 657 | err = -ENOMEM; |
656 | goto out_free_mtd; | 658 | goto out_free_mtd; |
657 | } | 659 | } |
658 | cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, 2112 + sizeof(struct nand_buffers), | ||
659 | &cafe->dmaaddr, GFP_KERNEL); | ||
660 | if (!cafe->dmabuf) { | ||
661 | err = -ENOMEM; | ||
662 | goto out_ior; | ||
663 | } | ||
664 | cafe->nand.buffers = (void *)cafe->dmabuf + 2112; | ||
665 | 660 | ||
666 | cafe->rs = init_rs_non_canonical(12, &cafe_mul, 0, 1, 8); | 661 | cafe->rs = init_rs_non_canonical(12, &cafe_mul, 0, 1, 8); |
667 | if (!cafe->rs) { | 662 | if (!cafe->rs) { |
@@ -721,7 +716,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
721 | "CAFE NAND", mtd); | 716 | "CAFE NAND", mtd); |
722 | if (err) { | 717 | if (err) { |
723 | dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); | 718 | dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); |
724 | goto out_free_dma; | 719 | goto out_ior; |
725 | } | 720 | } |
726 | 721 | ||
727 | /* Disable master reset, enable NAND clock */ | 722 | /* Disable master reset, enable NAND clock */ |
@@ -735,6 +730,32 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
735 | cafe_writel(cafe, 0x7006, GLOBAL_CTRL); | 730 | cafe_writel(cafe, 0x7006, GLOBAL_CTRL); |
736 | cafe_writel(cafe, 0x700a, GLOBAL_CTRL); | 731 | cafe_writel(cafe, 0x700a, GLOBAL_CTRL); |
737 | 732 | ||
733 | /* Enable NAND IRQ in global IRQ mask register */ | ||
734 | cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); | ||
735 | cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", | ||
736 | cafe_readl(cafe, GLOBAL_CTRL), | ||
737 | cafe_readl(cafe, GLOBAL_IRQ_MASK)); | ||
738 | |||
739 | /* Do not use the DMA for the nand_scan_ident() */ | ||
740 | old_dma = usedma; | ||
741 | usedma = 0; | ||
742 | |||
743 | /* Scan to find existence of the device */ | ||
744 | if (nand_scan_ident(mtd, 2, NULL)) { | ||
745 | err = -ENXIO; | ||
746 | goto out_irq; | ||
747 | } | ||
748 | |||
749 | cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, | ||
750 | 2112 + sizeof(struct nand_buffers) + | ||
751 | mtd->writesize + mtd->oobsize, | ||
752 | &cafe->dmaaddr, GFP_KERNEL); | ||
753 | if (!cafe->dmabuf) { | ||
754 | err = -ENOMEM; | ||
755 | goto out_irq; | ||
756 | } | ||
757 | cafe->nand.buffers = nbuf = (void *)cafe->dmabuf + 2112; | ||
758 | |||
738 | /* Set up DMA address */ | 759 | /* Set up DMA address */ |
739 | cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0); | 760 | cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0); |
740 | if (sizeof(cafe->dmaaddr) > 4) | 761 | if (sizeof(cafe->dmaaddr) > 4) |
@@ -746,16 +767,13 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
746 | cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n", | 767 | cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n", |
747 | cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf); | 768 | cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf); |
748 | 769 | ||
749 | /* Enable NAND IRQ in global IRQ mask register */ | 770 | /* this driver does not need the @ecccalc and @ecccode */ |
750 | cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); | 771 | nbuf->ecccalc = NULL; |
751 | cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", | 772 | nbuf->ecccode = NULL; |
752 | cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); | 773 | nbuf->databuf = (uint8_t *)(nbuf + 1); |
753 | 774 | ||
754 | /* Scan to find existence of the device */ | 775 | /* Restore the DMA flag */ |
755 | if (nand_scan_ident(mtd, 2, NULL)) { | 776 | usedma = old_dma; |
756 | err = -ENXIO; | ||
757 | goto out_irq; | ||
758 | } | ||
759 | 777 | ||
760 | cafe->ctl2 = 1<<27; /* Reed-Solomon ECC */ | 778 | cafe->ctl2 = 1<<27; /* Reed-Solomon ECC */ |
761 | if (mtd->writesize == 2048) | 779 | if (mtd->writesize == 2048) |
@@ -773,7 +791,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
773 | } else { | 791 | } else { |
774 | printk(KERN_WARNING "Unexpected NAND flash writesize %d. Aborting\n", | 792 | printk(KERN_WARNING "Unexpected NAND flash writesize %d. Aborting\n", |
775 | mtd->writesize); | 793 | mtd->writesize); |
776 | goto out_irq; | 794 | goto out_free_dma; |
777 | } | 795 | } |
778 | cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; | 796 | cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; |
779 | cafe->nand.ecc.size = mtd->writesize; | 797 | cafe->nand.ecc.size = mtd->writesize; |
@@ -790,7 +808,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
790 | 808 | ||
791 | err = nand_scan_tail(mtd); | 809 | err = nand_scan_tail(mtd); |
792 | if (err) | 810 | if (err) |
793 | goto out_irq; | 811 | goto out_free_dma; |
794 | 812 | ||
795 | pci_set_drvdata(pdev, mtd); | 813 | pci_set_drvdata(pdev, mtd); |
796 | 814 | ||
@@ -799,12 +817,15 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
799 | 817 | ||
800 | goto out; | 818 | goto out; |
801 | 819 | ||
820 | out_free_dma: | ||
821 | dma_free_coherent(&cafe->pdev->dev, | ||
822 | 2112 + sizeof(struct nand_buffers) + | ||
823 | mtd->writesize + mtd->oobsize, | ||
824 | cafe->dmabuf, cafe->dmaaddr); | ||
802 | out_irq: | 825 | out_irq: |
803 | /* Disable NAND IRQ in global IRQ mask register */ | 826 | /* Disable NAND IRQ in global IRQ mask register */ |
804 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); | 827 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); |
805 | free_irq(pdev->irq, mtd); | 828 | free_irq(pdev->irq, mtd); |
806 | out_free_dma: | ||
807 | dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr); | ||
808 | out_ior: | 829 | out_ior: |
809 | pci_iounmap(pdev, cafe->mmio); | 830 | pci_iounmap(pdev, cafe->mmio); |
810 | out_free_mtd: | 831 | out_free_mtd: |
@@ -824,7 +845,10 @@ static void cafe_nand_remove(struct pci_dev *pdev) | |||
824 | nand_release(mtd); | 845 | nand_release(mtd); |
825 | free_rs(cafe->rs); | 846 | free_rs(cafe->rs); |
826 | pci_iounmap(pdev, cafe->mmio); | 847 | pci_iounmap(pdev, cafe->mmio); |
827 | dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr); | 848 | dma_free_coherent(&cafe->pdev->dev, |
849 | 2112 + sizeof(struct nand_buffers) + | ||
850 | mtd->writesize + mtd->oobsize, | ||
851 | cafe->dmabuf, cafe->dmaaddr); | ||
828 | kfree(mtd); | 852 | kfree(mtd); |
829 | } | 853 | } |
830 | 854 | ||
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 8eb6a36f125a..4615d79fc93f 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
30 | #include <linux/err.h> | 29 | #include <linux/err.h> |
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index babb02c4b220..35cb17f57800 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c | |||
@@ -30,24 +30,6 @@ struct denali_dt { | |||
30 | struct clk *clk; | 30 | struct clk *clk; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static void __iomem *request_and_map(struct device *dev, | ||
34 | const struct resource *res) | ||
35 | { | ||
36 | void __iomem *ptr; | ||
37 | |||
38 | if (!devm_request_mem_region(dev, res->start, resource_size(res), | ||
39 | "denali-dt")) { | ||
40 | dev_err(dev, "unable to request %s\n", res->name); | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); | ||
45 | if (!ptr) | ||
46 | dev_err(dev, "ioremap_nocache of %s failed!", res->name); | ||
47 | |||
48 | return ptr; | ||
49 | } | ||
50 | |||
51 | static const struct of_device_id denali_nand_dt_ids[] = { | 33 | static const struct of_device_id denali_nand_dt_ids[] = { |
52 | { .compatible = "denali,denali-nand-dt" }, | 34 | { .compatible = "denali,denali-nand-dt" }, |
53 | { /* sentinel */ } | 35 | { /* sentinel */ } |
@@ -78,13 +60,6 @@ static int denali_dt_probe(struct platform_device *ofdev) | |||
78 | return -ENOMEM; | 60 | return -ENOMEM; |
79 | denali = &dt->denali; | 61 | denali = &dt->denali; |
80 | 62 | ||
81 | denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg"); | ||
82 | nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data"); | ||
83 | if (!denali_reg || !nand_data) { | ||
84 | dev_err(&ofdev->dev, "resources not completely defined\n"); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | |||
88 | denali->platform = DT; | 63 | denali->platform = DT; |
89 | denali->dev = &ofdev->dev; | 64 | denali->dev = &ofdev->dev; |
90 | denali->irq = platform_get_irq(ofdev, 0); | 65 | denali->irq = platform_get_irq(ofdev, 0); |
@@ -93,13 +68,15 @@ static int denali_dt_probe(struct platform_device *ofdev) | |||
93 | return denali->irq; | 68 | return denali->irq; |
94 | } | 69 | } |
95 | 70 | ||
96 | denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); | 71 | denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg"); |
97 | if (!denali->flash_reg) | 72 | denali->flash_reg = devm_ioremap_resource(&ofdev->dev, denali_reg); |
98 | return -ENOMEM; | 73 | if (IS_ERR(denali->flash_reg)) |
74 | return PTR_ERR(denali->flash_reg); | ||
99 | 75 | ||
100 | denali->flash_mem = request_and_map(&ofdev->dev, nand_data); | 76 | nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data"); |
101 | if (!denali->flash_mem) | 77 | denali->flash_mem = devm_ioremap_resource(&ofdev->dev, nand_data); |
102 | return -ENOMEM; | 78 | if (IS_ERR(denali->flash_mem)) |
79 | return PTR_ERR(denali->flash_mem); | ||
103 | 80 | ||
104 | if (!of_property_read_u32(ofdev->dev.of_node, | 81 | if (!of_property_read_u32(ofdev->dev.of_node, |
105 | "dma-mask", (u32 *)&denali_dma_mask)) { | 82 | "dma-mask", (u32 *)&denali_dma_mask)) { |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fec31d71b84e..f68a7bccecdc 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -698,7 +698,8 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu | |||
698 | /* Serially input address */ | 698 | /* Serially input address */ |
699 | if (column != -1) { | 699 | if (column != -1) { |
700 | /* Adjust columns for 16 bit buswidth */ | 700 | /* Adjust columns for 16 bit buswidth */ |
701 | if (this->options & NAND_BUSWIDTH_16) | 701 | if (this->options & NAND_BUSWIDTH_16 && |
702 | !nand_opcode_8bits(command)) | ||
702 | column >>= 1; | 703 | column >>= 1; |
703 | WriteDOC(column, docptr, Mplus_FlashAddress); | 704 | WriteDOC(column, docptr, Mplus_FlashAddress); |
704 | } | 705 | } |
@@ -1438,7 +1439,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1438 | int reg, len, numchips; | 1439 | int reg, len, numchips; |
1439 | int ret = 0; | 1440 | int ret = 0; |
1440 | 1441 | ||
1441 | if (!request_mem_region(physadr, DOC_IOREMAP_LEN, NULL)) | 1442 | if (!request_mem_region(physadr, DOC_IOREMAP_LEN, "DiskOnChip")) |
1442 | return -EBUSY; | 1443 | return -EBUSY; |
1443 | virtadr = ioremap(physadr, DOC_IOREMAP_LEN); | 1444 | virtadr = ioremap(physadr, DOC_IOREMAP_LEN); |
1444 | if (!virtadr) { | 1445 | if (!virtadr) { |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index bcf60800c3ce..ec549cd9849f 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/string.h> | 28 | #include <linux/string.h> |
30 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 50d9161c4faf..cb45d2f8e208 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/init.h> | ||
26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
27 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 8e6148aa4539..117ce333fdd4 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index ca6369fe91ff..bb77f750e75a 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
28 | #include <linux/of_mtd.h> | 28 | #include <linux/of_mtd.h> |
29 | #include "gpmi-nand.h" | 29 | #include "gpmi-nand.h" |
30 | #include "bch-regs.h" | ||
30 | 31 | ||
31 | /* Resource names for the GPMI NAND driver. */ | 32 | /* Resource names for the GPMI NAND driver. */ |
32 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" | 33 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" |
@@ -985,7 +986,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
985 | int ret; | 986 | int ret; |
986 | 987 | ||
987 | dev_dbg(this->dev, "page number is : %d\n", page); | 988 | dev_dbg(this->dev, "page number is : %d\n", page); |
988 | ret = read_page_prepare(this, buf, mtd->writesize, | 989 | ret = read_page_prepare(this, buf, nfc_geo->payload_size, |
989 | this->payload_virt, this->payload_phys, | 990 | this->payload_virt, this->payload_phys, |
990 | nfc_geo->payload_size, | 991 | nfc_geo->payload_size, |
991 | &payload_virt, &payload_phys); | 992 | &payload_virt, &payload_phys); |
@@ -999,7 +1000,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
999 | 1000 | ||
1000 | /* go! */ | 1001 | /* go! */ |
1001 | ret = gpmi_read_page(this, payload_phys, auxiliary_phys); | 1002 | ret = gpmi_read_page(this, payload_phys, auxiliary_phys); |
1002 | read_page_end(this, buf, mtd->writesize, | 1003 | read_page_end(this, buf, nfc_geo->payload_size, |
1003 | this->payload_virt, this->payload_phys, | 1004 | this->payload_virt, this->payload_phys, |
1004 | nfc_geo->payload_size, | 1005 | nfc_geo->payload_size, |
1005 | payload_virt, payload_phys); | 1006 | payload_virt, payload_phys); |
@@ -1041,7 +1042,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1041 | chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; | 1042 | chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; |
1042 | } | 1043 | } |
1043 | 1044 | ||
1044 | read_page_swap_end(this, buf, mtd->writesize, | 1045 | read_page_swap_end(this, buf, nfc_geo->payload_size, |
1045 | this->payload_virt, this->payload_phys, | 1046 | this->payload_virt, this->payload_phys, |
1046 | nfc_geo->payload_size, | 1047 | nfc_geo->payload_size, |
1047 | payload_virt, payload_phys); | 1048 | payload_virt, payload_phys); |
@@ -1049,6 +1050,90 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1049 | return max_bitflips; | 1050 | return max_bitflips; |
1050 | } | 1051 | } |
1051 | 1052 | ||
1053 | /* Fake a virtual small page for the subpage read */ | ||
1054 | static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | ||
1055 | uint32_t offs, uint32_t len, uint8_t *buf, int page) | ||
1056 | { | ||
1057 | struct gpmi_nand_data *this = chip->priv; | ||
1058 | void __iomem *bch_regs = this->resources.bch_regs; | ||
1059 | struct bch_geometry old_geo = this->bch_geometry; | ||
1060 | struct bch_geometry *geo = &this->bch_geometry; | ||
1061 | int size = chip->ecc.size; /* ECC chunk size */ | ||
1062 | int meta, n, page_size; | ||
1063 | u32 r1_old, r2_old, r1_new, r2_new; | ||
1064 | unsigned int max_bitflips; | ||
1065 | int first, last, marker_pos; | ||
1066 | int ecc_parity_size; | ||
1067 | int col = 0; | ||
1068 | |||
1069 | /* The size of ECC parity */ | ||
1070 | ecc_parity_size = geo->gf_len * geo->ecc_strength / 8; | ||
1071 | |||
1072 | /* Align it with the chunk size */ | ||
1073 | first = offs / size; | ||
1074 | last = (offs + len - 1) / size; | ||
1075 | |||
1076 | /* | ||
1077 | * Find the chunk which contains the Block Marker. If this chunk is | ||
1078 | * in the range of [first, last], we have to read out the whole page. | ||
1079 | * Why? since we had swapped the data at the position of Block Marker | ||
1080 | * to the metadata which is bound with the chunk 0. | ||
1081 | */ | ||
1082 | marker_pos = geo->block_mark_byte_offset / size; | ||
1083 | if (last >= marker_pos && first <= marker_pos) { | ||
1084 | dev_dbg(this->dev, "page:%d, first:%d, last:%d, marker at:%d\n", | ||
1085 | page, first, last, marker_pos); | ||
1086 | return gpmi_ecc_read_page(mtd, chip, buf, 0, page); | ||
1087 | } | ||
1088 | |||
1089 | meta = geo->metadata_size; | ||
1090 | if (first) { | ||
1091 | col = meta + (size + ecc_parity_size) * first; | ||
1092 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1); | ||
1093 | |||
1094 | meta = 0; | ||
1095 | buf = buf + first * size; | ||
1096 | } | ||
1097 | |||
1098 | /* Save the old environment */ | ||
1099 | r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0); | ||
1100 | r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1); | ||
1101 | |||
1102 | /* change the BCH registers and bch_geometry{} */ | ||
1103 | n = last - first + 1; | ||
1104 | page_size = meta + (size + ecc_parity_size) * n; | ||
1105 | |||
1106 | r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS | | ||
1107 | BM_BCH_FLASH0LAYOUT0_META_SIZE); | ||
1108 | r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1) | ||
1109 | | BF_BCH_FLASH0LAYOUT0_META_SIZE(meta); | ||
1110 | writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0); | ||
1111 | |||
1112 | r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE; | ||
1113 | r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size); | ||
1114 | writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1); | ||
1115 | |||
1116 | geo->ecc_chunk_count = n; | ||
1117 | geo->payload_size = n * size; | ||
1118 | geo->page_size = page_size; | ||
1119 | geo->auxiliary_status_offset = ALIGN(meta, 4); | ||
1120 | |||
1121 | dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n", | ||
1122 | page, offs, len, col, first, n, page_size); | ||
1123 | |||
1124 | /* Read the subpage now */ | ||
1125 | this->swap_block_mark = false; | ||
1126 | max_bitflips = gpmi_ecc_read_page(mtd, chip, buf, 0, page); | ||
1127 | |||
1128 | /* Restore */ | ||
1129 | writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0); | ||
1130 | writel(r2_old, bch_regs + HW_BCH_FLASH0LAYOUT1); | ||
1131 | this->bch_geometry = old_geo; | ||
1132 | this->swap_block_mark = true; | ||
1133 | |||
1134 | return max_bitflips; | ||
1135 | } | ||
1136 | |||
1052 | static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1137 | static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1053 | const uint8_t *buf, int oob_required) | 1138 | const uint8_t *buf, int oob_required) |
1054 | { | 1139 | { |
@@ -1566,6 +1651,17 @@ static int gpmi_init_last(struct gpmi_nand_data *this) | |||
1566 | ecc->layout = &gpmi_hw_ecclayout; | 1651 | ecc->layout = &gpmi_hw_ecclayout; |
1567 | 1652 | ||
1568 | /* | 1653 | /* |
1654 | * We only enable the subpage read when: | ||
1655 | * (1) the chip is imx6, and | ||
1656 | * (2) the size of the ECC parity is byte aligned. | ||
1657 | */ | ||
1658 | if (GPMI_IS_MX6Q(this) && | ||
1659 | ((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) { | ||
1660 | ecc->read_subpage = gpmi_ecc_read_subpage; | ||
1661 | chip->options |= NAND_SUBPAGE_READ; | ||
1662 | } | ||
1663 | |||
1664 | /* | ||
1569 | * Can we enable the extra features? such as EDO or Sync mode. | 1665 | * Can we enable the extra features? such as EDO or Sync mode. |
1570 | * | 1666 | * |
1571 | * We do not check the return value now. That's means if we fail in | 1667 | * We do not check the return value now. That's means if we fail in |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 31ee7cfbc12b..e78841a2dcc3 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/gfp.h> | 30 | #include <linux/gfp.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | #include <linux/init.h> | ||
34 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
35 | #include <linux/io.h> | 34 | #include <linux/io.h> |
36 | #include <linux/mtd/mtd.h> | 35 | #include <linux/mtd/mtd.h> |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index e9a4835c4dd9..dba262bf766f 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -1501,6 +1501,8 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
1501 | init_completion(&host->op_completion); | 1501 | init_completion(&host->op_completion); |
1502 | 1502 | ||
1503 | host->irq = platform_get_irq(pdev, 0); | 1503 | host->irq = platform_get_irq(pdev, 0); |
1504 | if (host->irq < 0) | ||
1505 | return host->irq; | ||
1504 | 1506 | ||
1505 | /* | 1507 | /* |
1506 | * Use host->devtype_data->irq_control() here instead of irq_control() | 1508 | * Use host->devtype_data->irq_control() here instead of irq_control() |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 9715a7ba164a..9d01c4df838c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -589,7 +589,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
589 | /* Serially input address */ | 589 | /* Serially input address */ |
590 | if (column != -1) { | 590 | if (column != -1) { |
591 | /* Adjust columns for 16 bit buswidth */ | 591 | /* Adjust columns for 16 bit buswidth */ |
592 | if (chip->options & NAND_BUSWIDTH_16) | 592 | if (chip->options & NAND_BUSWIDTH_16 && |
593 | !nand_opcode_8bits(command)) | ||
593 | column >>= 1; | 594 | column >>= 1; |
594 | chip->cmd_ctrl(mtd, column, ctrl); | 595 | chip->cmd_ctrl(mtd, column, ctrl); |
595 | ctrl &= ~NAND_CTRL_CHANGE; | 596 | ctrl &= ~NAND_CTRL_CHANGE; |
@@ -680,7 +681,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
680 | /* Serially input address */ | 681 | /* Serially input address */ |
681 | if (column != -1) { | 682 | if (column != -1) { |
682 | /* Adjust columns for 16 bit buswidth */ | 683 | /* Adjust columns for 16 bit buswidth */ |
683 | if (chip->options & NAND_BUSWIDTH_16) | 684 | if (chip->options & NAND_BUSWIDTH_16 && |
685 | !nand_opcode_8bits(command)) | ||
684 | column >>= 1; | 686 | column >>= 1; |
685 | chip->cmd_ctrl(mtd, column, ctrl); | 687 | chip->cmd_ctrl(mtd, column, ctrl); |
686 | ctrl &= ~NAND_CTRL_CHANGE; | 688 | ctrl &= ~NAND_CTRL_CHANGE; |
@@ -1160,9 +1162,11 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1160 | * @data_offs: offset of requested data within the page | 1162 | * @data_offs: offset of requested data within the page |
1161 | * @readlen: data length | 1163 | * @readlen: data length |
1162 | * @bufpoi: buffer to store read data | 1164 | * @bufpoi: buffer to store read data |
1165 | * @page: page number to read | ||
1163 | */ | 1166 | */ |
1164 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | 1167 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, |
1165 | uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) | 1168 | uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, |
1169 | int page) | ||
1166 | { | 1170 | { |
1167 | int start_step, end_step, num_steps; | 1171 | int start_step, end_step, num_steps; |
1168 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1172 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
@@ -1170,13 +1174,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1170 | int data_col_addr, i, gaps = 0; | 1174 | int data_col_addr, i, gaps = 0; |
1171 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; | 1175 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; |
1172 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; | 1176 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; |
1173 | int index = 0; | 1177 | int index; |
1174 | unsigned int max_bitflips = 0; | 1178 | unsigned int max_bitflips = 0; |
1175 | 1179 | ||
1176 | /* Column address within the page aligned to ECC size (256bytes) */ | 1180 | /* Column address within the page aligned to ECC size (256bytes) */ |
1177 | start_step = data_offs / chip->ecc.size; | 1181 | start_step = data_offs / chip->ecc.size; |
1178 | end_step = (data_offs + readlen - 1) / chip->ecc.size; | 1182 | end_step = (data_offs + readlen - 1) / chip->ecc.size; |
1179 | num_steps = end_step - start_step + 1; | 1183 | num_steps = end_step - start_step + 1; |
1184 | index = start_step * chip->ecc.bytes; | ||
1180 | 1185 | ||
1181 | /* Data size aligned to ECC ecc.size */ | 1186 | /* Data size aligned to ECC ecc.size */ |
1182 | datafrag_len = num_steps * chip->ecc.size; | 1187 | datafrag_len = num_steps * chip->ecc.size; |
@@ -1213,8 +1218,6 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1213 | * Send the command to read the particular ECC bytes take care | 1218 | * Send the command to read the particular ECC bytes take care |
1214 | * about buswidth alignment in read_buf. | 1219 | * about buswidth alignment in read_buf. |
1215 | */ | 1220 | */ |
1216 | index = start_step * chip->ecc.bytes; | ||
1217 | |||
1218 | aligned_pos = eccpos[index] & ~(busw - 1); | 1221 | aligned_pos = eccpos[index] & ~(busw - 1); |
1219 | aligned_len = eccfrag_len; | 1222 | aligned_len = eccfrag_len; |
1220 | if (eccpos[index] & (busw - 1)) | 1223 | if (eccpos[index] & (busw - 1)) |
@@ -1538,7 +1541,8 @@ read_retry: | |||
1538 | else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) && | 1541 | else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) && |
1539 | !oob) | 1542 | !oob) |
1540 | ret = chip->ecc.read_subpage(mtd, chip, | 1543 | ret = chip->ecc.read_subpage(mtd, chip, |
1541 | col, bytes, bufpoi); | 1544 | col, bytes, bufpoi, |
1545 | page); | ||
1542 | else | 1546 | else |
1543 | ret = chip->ecc.read_page(mtd, chip, bufpoi, | 1547 | ret = chip->ecc.read_page(mtd, chip, bufpoi, |
1544 | oob_required, page); | 1548 | oob_required, page); |
@@ -2000,7 +2004,7 @@ static int nand_write_page_raw_syndrome(struct mtd_info *mtd, | |||
2000 | oob += chip->ecc.prepad; | 2004 | oob += chip->ecc.prepad; |
2001 | } | 2005 | } |
2002 | 2006 | ||
2003 | chip->read_buf(mtd, oob, eccbytes); | 2007 | chip->write_buf(mtd, oob, eccbytes); |
2004 | oob += eccbytes; | 2008 | oob += eccbytes; |
2005 | 2009 | ||
2006 | if (chip->ecc.postpad) { | 2010 | if (chip->ecc.postpad) { |
@@ -3063,7 +3067,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
3063 | int *busw) | 3067 | int *busw) |
3064 | { | 3068 | { |
3065 | struct nand_onfi_params *p = &chip->onfi_params; | 3069 | struct nand_onfi_params *p = &chip->onfi_params; |
3066 | int i; | 3070 | int i, j; |
3067 | int val; | 3071 | int val; |
3068 | 3072 | ||
3069 | /* Try ONFI for unknown chip or LP */ | 3073 | /* Try ONFI for unknown chip or LP */ |
@@ -3072,18 +3076,10 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
3072 | chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') | 3076 | chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') |
3073 | return 0; | 3077 | return 0; |
3074 | 3078 | ||
3075 | /* | ||
3076 | * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not | ||
3077 | * with NAND_BUSWIDTH_16 | ||
3078 | */ | ||
3079 | if (chip->options & NAND_BUSWIDTH_16) { | ||
3080 | pr_err("ONFI cannot be probed in 16-bit mode; aborting\n"); | ||
3081 | return 0; | ||
3082 | } | ||
3083 | |||
3084 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); | 3079 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); |
3085 | for (i = 0; i < 3; i++) { | 3080 | for (i = 0; i < 3; i++) { |
3086 | chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); | 3081 | for (j = 0; j < sizeof(*p); j++) |
3082 | ((uint8_t *)p)[j] = chip->read_byte(mtd); | ||
3087 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == | 3083 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == |
3088 | le16_to_cpu(p->crc)) { | 3084 | le16_to_cpu(p->crc)) { |
3089 | break; | 3085 | break; |
@@ -3169,6 +3165,87 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
3169 | } | 3165 | } |
3170 | 3166 | ||
3171 | /* | 3167 | /* |
3168 | * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise. | ||
3169 | */ | ||
3170 | static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, | ||
3171 | int *busw) | ||
3172 | { | ||
3173 | struct nand_jedec_params *p = &chip->jedec_params; | ||
3174 | struct jedec_ecc_info *ecc; | ||
3175 | int val; | ||
3176 | int i, j; | ||
3177 | |||
3178 | /* Try JEDEC for unknown chip or LP */ | ||
3179 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1); | ||
3180 | if (chip->read_byte(mtd) != 'J' || chip->read_byte(mtd) != 'E' || | ||
3181 | chip->read_byte(mtd) != 'D' || chip->read_byte(mtd) != 'E' || | ||
3182 | chip->read_byte(mtd) != 'C') | ||
3183 | return 0; | ||
3184 | |||
3185 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0x40, -1); | ||
3186 | for (i = 0; i < 3; i++) { | ||
3187 | for (j = 0; j < sizeof(*p); j++) | ||
3188 | ((uint8_t *)p)[j] = chip->read_byte(mtd); | ||
3189 | |||
3190 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) == | ||
3191 | le16_to_cpu(p->crc)) | ||
3192 | break; | ||
3193 | } | ||
3194 | |||
3195 | if (i == 3) { | ||
3196 | pr_err("Could not find valid JEDEC parameter page; aborting\n"); | ||
3197 | return 0; | ||
3198 | } | ||
3199 | |||
3200 | /* Check version */ | ||
3201 | val = le16_to_cpu(p->revision); | ||
3202 | if (val & (1 << 2)) | ||
3203 | chip->jedec_version = 10; | ||
3204 | else if (val & (1 << 1)) | ||
3205 | chip->jedec_version = 1; /* vendor specific version */ | ||
3206 | |||
3207 | if (!chip->jedec_version) { | ||
3208 | pr_info("unsupported JEDEC version: %d\n", val); | ||
3209 | return 0; | ||
3210 | } | ||
3211 | |||
3212 | sanitize_string(p->manufacturer, sizeof(p->manufacturer)); | ||
3213 | sanitize_string(p->model, sizeof(p->model)); | ||
3214 | if (!mtd->name) | ||
3215 | mtd->name = p->model; | ||
3216 | |||
3217 | mtd->writesize = le32_to_cpu(p->byte_per_page); | ||
3218 | |||
3219 | /* Please reference to the comment for nand_flash_detect_onfi. */ | ||
3220 | mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); | ||
3221 | mtd->erasesize *= mtd->writesize; | ||
3222 | |||
3223 | mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); | ||
3224 | |||
3225 | /* Please reference to the comment for nand_flash_detect_onfi. */ | ||
3226 | chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); | ||
3227 | chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; | ||
3228 | chip->bits_per_cell = p->bits_per_cell; | ||
3229 | |||
3230 | if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS) | ||
3231 | *busw = NAND_BUSWIDTH_16; | ||
3232 | else | ||
3233 | *busw = 0; | ||
3234 | |||
3235 | /* ECC info */ | ||
3236 | ecc = &p->ecc_info[0]; | ||
3237 | |||
3238 | if (ecc->codeword_size >= 9) { | ||
3239 | chip->ecc_strength_ds = ecc->ecc_bits; | ||
3240 | chip->ecc_step_ds = 1 << ecc->codeword_size; | ||
3241 | } else { | ||
3242 | pr_warn("Invalid codeword size\n"); | ||
3243 | } | ||
3244 | |||
3245 | return 1; | ||
3246 | } | ||
3247 | |||
3248 | /* | ||
3172 | * nand_id_has_period - Check if an ID string has a given wraparound period | 3249 | * nand_id_has_period - Check if an ID string has a given wraparound period |
3173 | * @id_data: the ID string | 3250 | * @id_data: the ID string |
3174 | * @arrlen: the length of the @id_data array | 3251 | * @arrlen: the length of the @id_data array |
@@ -3474,10 +3551,10 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, | |||
3474 | */ | 3551 | */ |
3475 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | 3552 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, |
3476 | struct nand_chip *chip, | 3553 | struct nand_chip *chip, |
3477 | int busw, | ||
3478 | int *maf_id, int *dev_id, | 3554 | int *maf_id, int *dev_id, |
3479 | struct nand_flash_dev *type) | 3555 | struct nand_flash_dev *type) |
3480 | { | 3556 | { |
3557 | int busw; | ||
3481 | int i, maf_idx; | 3558 | int i, maf_idx; |
3482 | u8 id_data[8]; | 3559 | u8 id_data[8]; |
3483 | 3560 | ||
@@ -3533,6 +3610,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3533 | /* Check is chip is ONFI compliant */ | 3610 | /* Check is chip is ONFI compliant */ |
3534 | if (nand_flash_detect_onfi(mtd, chip, &busw)) | 3611 | if (nand_flash_detect_onfi(mtd, chip, &busw)) |
3535 | goto ident_done; | 3612 | goto ident_done; |
3613 | |||
3614 | /* Check if the chip is JEDEC compliant */ | ||
3615 | if (nand_flash_detect_jedec(mtd, chip, &busw)) | ||
3616 | goto ident_done; | ||
3536 | } | 3617 | } |
3537 | 3618 | ||
3538 | if (!type->name) | 3619 | if (!type->name) |
@@ -3612,8 +3693,17 @@ ident_done: | |||
3612 | 3693 | ||
3613 | pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", | 3694 | pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", |
3614 | *maf_id, *dev_id); | 3695 | *maf_id, *dev_id); |
3615 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, | 3696 | |
3616 | chip->onfi_version ? chip->onfi_params.model : type->name); | 3697 | if (chip->onfi_version) |
3698 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, | ||
3699 | chip->onfi_params.model); | ||
3700 | else if (chip->jedec_version) | ||
3701 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, | ||
3702 | chip->jedec_params.model); | ||
3703 | else | ||
3704 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, | ||
3705 | type->name); | ||
3706 | |||
3617 | pr_info("%dMiB, %s, page size: %d, OOB size: %d\n", | 3707 | pr_info("%dMiB, %s, page size: %d, OOB size: %d\n", |
3618 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", | 3708 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", |
3619 | mtd->writesize, mtd->oobsize); | 3709 | mtd->writesize, mtd->oobsize); |
@@ -3634,18 +3724,16 @@ ident_done: | |||
3634 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, | 3724 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, |
3635 | struct nand_flash_dev *table) | 3725 | struct nand_flash_dev *table) |
3636 | { | 3726 | { |
3637 | int i, busw, nand_maf_id, nand_dev_id; | 3727 | int i, nand_maf_id, nand_dev_id; |
3638 | struct nand_chip *chip = mtd->priv; | 3728 | struct nand_chip *chip = mtd->priv; |
3639 | struct nand_flash_dev *type; | 3729 | struct nand_flash_dev *type; |
3640 | 3730 | ||
3641 | /* Get buswidth to select the correct functions */ | ||
3642 | busw = chip->options & NAND_BUSWIDTH_16; | ||
3643 | /* Set the default functions */ | 3731 | /* Set the default functions */ |
3644 | nand_set_defaults(chip, busw); | 3732 | nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); |
3645 | 3733 | ||
3646 | /* Read the flash type */ | 3734 | /* Read the flash type */ |
3647 | type = nand_get_flash_type(mtd, chip, busw, | 3735 | type = nand_get_flash_type(mtd, chip, &nand_maf_id, |
3648 | &nand_maf_id, &nand_dev_id, table); | 3736 | &nand_dev_id, table); |
3649 | 3737 | ||
3650 | if (IS_ERR(type)) { | 3738 | if (IS_ERR(type)) { |
3651 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) | 3739 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) |
@@ -3696,15 +3784,26 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3696 | int i; | 3784 | int i; |
3697 | struct nand_chip *chip = mtd->priv; | 3785 | struct nand_chip *chip = mtd->priv; |
3698 | struct nand_ecc_ctrl *ecc = &chip->ecc; | 3786 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
3787 | struct nand_buffers *nbuf; | ||
3699 | 3788 | ||
3700 | /* New bad blocks should be marked in OOB, flash-based BBT, or both */ | 3789 | /* New bad blocks should be marked in OOB, flash-based BBT, or both */ |
3701 | BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && | 3790 | BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && |
3702 | !(chip->bbt_options & NAND_BBT_USE_FLASH)); | 3791 | !(chip->bbt_options & NAND_BBT_USE_FLASH)); |
3703 | 3792 | ||
3704 | if (!(chip->options & NAND_OWN_BUFFERS)) | 3793 | if (!(chip->options & NAND_OWN_BUFFERS)) { |
3705 | chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); | 3794 | nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize |
3706 | if (!chip->buffers) | 3795 | + mtd->oobsize * 3, GFP_KERNEL); |
3707 | return -ENOMEM; | 3796 | if (!nbuf) |
3797 | return -ENOMEM; | ||
3798 | nbuf->ecccalc = (uint8_t *)(nbuf + 1); | ||
3799 | nbuf->ecccode = nbuf->ecccalc + mtd->oobsize; | ||
3800 | nbuf->databuf = nbuf->ecccode + mtd->oobsize; | ||
3801 | |||
3802 | chip->buffers = nbuf; | ||
3803 | } else { | ||
3804 | if (!chip->buffers) | ||
3805 | return -ENOMEM; | ||
3806 | } | ||
3708 | 3807 | ||
3709 | /* Set the internal oob buffer location, just after the page data */ | 3808 | /* Set the internal oob buffer location, just after the page data */ |
3710 | chip->oob_poi = chip->buffers->databuf + mtd->writesize; | 3809 | chip->oob_poi = chip->buffers->databuf + mtd->writesize; |
@@ -3825,7 +3924,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3825 | 3924 | ||
3826 | case NAND_ECC_SOFT_BCH: | 3925 | case NAND_ECC_SOFT_BCH: |
3827 | if (!mtd_nand_has_bch()) { | 3926 | if (!mtd_nand_has_bch()) { |
3828 | pr_warn("CONFIG_MTD_ECC_BCH not enabled\n"); | 3927 | pr_warn("CONFIG_MTD_NAND_ECC_BCH not enabled\n"); |
3829 | BUG(); | 3928 | BUG(); |
3830 | } | 3929 | } |
3831 | ecc->calculate = nand_bch_calculate_ecc; | 3930 | ecc->calculate = nand_bch_calculate_ecc; |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index daa2faacd7d0..3d7c89fc1031 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
@@ -43,6 +43,9 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
43 | {"TC58NVG6D2 64G 3.3V 8-bit", | 43 | {"TC58NVG6D2 64G 3.3V 8-bit", |
44 | { .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} }, | 44 | { .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} }, |
45 | SZ_8K, SZ_8K, SZ_2M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) }, | 45 | SZ_8K, SZ_8K, SZ_2M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) }, |
46 | {"SDTNRGAMA 64G 3.3V 8-bit", | ||
47 | { .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x50} }, | ||
48 | SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) }, | ||
46 | 49 | ||
47 | LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), | 50 | LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), |
48 | LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), | 51 | LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), |
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 9ee09a8177c6..e8a5fffd6ab2 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
15 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
16 | #include <linux/io.h> | 15 | #include <linux/io.h> |
@@ -152,7 +151,8 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
152 | if (column != -1 || page_addr != -1) { | 151 | if (column != -1 || page_addr != -1) { |
153 | 152 | ||
154 | if (column != -1) { | 153 | if (column != -1) { |
155 | if (chip->options & NAND_BUSWIDTH_16) | 154 | if (chip->options & NAND_BUSWIDTH_16 && |
155 | !nand_opcode_8bits(command)) | ||
156 | column >>= 1; | 156 | column >>= 1; |
157 | write_addr_reg(nand, column); | 157 | write_addr_reg(nand, column); |
158 | write_addr_reg(nand, column >> 8 | ENDADDR); | 158 | write_addr_reg(nand, column >> 8 | ENDADDR); |
@@ -225,7 +225,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand) | |||
225 | val = __raw_readl(nand->reg + REG_FMICSR); | 225 | val = __raw_readl(nand->reg + REG_FMICSR); |
226 | 226 | ||
227 | if (!(val & NAND_EN)) | 227 | if (!(val & NAND_EN)) |
228 | __raw_writel(val | NAND_EN, REG_FMICSR); | 228 | __raw_writel(val | NAND_EN, nand->reg + REG_FMICSR); |
229 | 229 | ||
230 | val = __raw_readl(nand->reg + REG_SMCSR); | 230 | val = __raw_readl(nand->reg + REG_SMCSR); |
231 | 231 | ||
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index bf642ceef681..1ff49b80bdaf 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -118,14 +118,9 @@ | |||
118 | 118 | ||
119 | #define OMAP24XX_DMA_GPMC 4 | 119 | #define OMAP24XX_DMA_GPMC 4 |
120 | 120 | ||
121 | #define BCH8_MAX_ERROR 8 /* upto 8 bit correctable */ | ||
122 | #define BCH4_MAX_ERROR 4 /* upto 4 bit correctable */ | ||
123 | |||
124 | #define SECTOR_BYTES 512 | 121 | #define SECTOR_BYTES 512 |
125 | /* 4 bit padding to make byte aligned, 56 = 52 + 4 */ | 122 | /* 4 bit padding to make byte aligned, 56 = 52 + 4 */ |
126 | #define BCH4_BIT_PAD 4 | 123 | #define BCH4_BIT_PAD 4 |
127 | #define BCH8_ECC_MAX ((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8) | ||
128 | #define BCH4_ECC_MAX ((SECTOR_BYTES + BCH4_ECC_OOB_BYTES) * 8) | ||
129 | 124 | ||
130 | /* GPMC ecc engine settings for read */ | 125 | /* GPMC ecc engine settings for read */ |
131 | #define BCH_WRAPMODE_1 1 /* BCH wrap mode 1 */ | 126 | #define BCH_WRAPMODE_1 1 /* BCH wrap mode 1 */ |
@@ -159,7 +154,7 @@ struct omap_nand_info { | |||
159 | 154 | ||
160 | int gpmc_cs; | 155 | int gpmc_cs; |
161 | unsigned long phys_base; | 156 | unsigned long phys_base; |
162 | unsigned long mem_size; | 157 | enum omap_ecc ecc_opt; |
163 | struct completion comp; | 158 | struct completion comp; |
164 | struct dma_chan *dma; | 159 | struct dma_chan *dma; |
165 | int gpmc_irq_fifo; | 160 | int gpmc_irq_fifo; |
@@ -172,7 +167,6 @@ struct omap_nand_info { | |||
172 | int buf_len; | 167 | int buf_len; |
173 | struct gpmc_nand_regs reg; | 168 | struct gpmc_nand_regs reg; |
174 | /* fields specific for BCHx_HW ECC scheme */ | 169 | /* fields specific for BCHx_HW ECC scheme */ |
175 | bool is_elm_used; | ||
176 | struct device *elm_dev; | 170 | struct device *elm_dev; |
177 | struct device_node *of_node; | 171 | struct device_node *of_node; |
178 | }; | 172 | }; |
@@ -1043,9 +1037,8 @@ static int omap_dev_ready(struct mtd_info *mtd) | |||
1043 | } | 1037 | } |
1044 | } | 1038 | } |
1045 | 1039 | ||
1046 | #if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH) | ||
1047 | /** | 1040 | /** |
1048 | * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction | 1041 | * omap_enable_hwecc_bch - Program GPMC to perform BCH ECC calculation |
1049 | * @mtd: MTD device structure | 1042 | * @mtd: MTD device structure |
1050 | * @mode: Read/Write mode | 1043 | * @mode: Read/Write mode |
1051 | * | 1044 | * |
@@ -1056,50 +1049,73 @@ static int omap_dev_ready(struct mtd_info *mtd) | |||
1056 | * eccsize0 = 0 (no additional protected byte in spare area) | 1049 | * eccsize0 = 0 (no additional protected byte in spare area) |
1057 | * eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) | 1050 | * eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) |
1058 | */ | 1051 | */ |
1059 | static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode) | 1052 | static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) |
1060 | { | 1053 | { |
1061 | int nerrors; | 1054 | unsigned int bch_type; |
1062 | unsigned int dev_width, nsectors; | 1055 | unsigned int dev_width, nsectors; |
1063 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1056 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
1064 | mtd); | 1057 | mtd); |
1058 | enum omap_ecc ecc_opt = info->ecc_opt; | ||
1065 | struct nand_chip *chip = mtd->priv; | 1059 | struct nand_chip *chip = mtd->priv; |
1066 | u32 val, wr_mode; | 1060 | u32 val, wr_mode; |
1067 | unsigned int ecc_size1, ecc_size0; | 1061 | unsigned int ecc_size1, ecc_size0; |
1068 | 1062 | ||
1069 | /* Using wrapping mode 6 for writing */ | 1063 | /* GPMC configurations for calculating ECC */ |
1070 | wr_mode = BCH_WRAPMODE_6; | 1064 | switch (ecc_opt) { |
1071 | 1065 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | |
1072 | /* | 1066 | bch_type = 0; |
1073 | * ECC engine enabled for valid ecc_size0 nibbles | 1067 | nsectors = 1; |
1074 | * and disabled for ecc_size1 nibbles. | 1068 | if (mode == NAND_ECC_READ) { |
1075 | */ | 1069 | wr_mode = BCH_WRAPMODE_6; |
1076 | ecc_size0 = BCH_ECC_SIZE0; | 1070 | ecc_size0 = BCH_ECC_SIZE0; |
1077 | ecc_size1 = BCH_ECC_SIZE1; | 1071 | ecc_size1 = BCH_ECC_SIZE1; |
1078 | 1072 | } else { | |
1079 | /* Perform ecc calculation on 512-byte sector */ | 1073 | wr_mode = BCH_WRAPMODE_6; |
1080 | nsectors = 1; | 1074 | ecc_size0 = BCH_ECC_SIZE0; |
1081 | 1075 | ecc_size1 = BCH_ECC_SIZE1; | |
1082 | /* Update number of error correction */ | 1076 | } |
1083 | nerrors = info->nand.ecc.strength; | 1077 | break; |
1084 | 1078 | case OMAP_ECC_BCH4_CODE_HW: | |
1085 | /* Multi sector reading/writing for NAND flash with page size < 4096 */ | 1079 | bch_type = 0; |
1086 | if (info->is_elm_used && (mtd->writesize <= 4096)) { | 1080 | nsectors = chip->ecc.steps; |
1087 | if (mode == NAND_ECC_READ) { | 1081 | if (mode == NAND_ECC_READ) { |
1088 | /* Using wrapping mode 1 for reading */ | 1082 | wr_mode = BCH_WRAPMODE_1; |
1089 | wr_mode = BCH_WRAPMODE_1; | 1083 | ecc_size0 = BCH4R_ECC_SIZE0; |
1090 | 1084 | ecc_size1 = BCH4R_ECC_SIZE1; | |
1091 | /* | 1085 | } else { |
1092 | * ECC engine enabled for ecc_size0 nibbles | 1086 | wr_mode = BCH_WRAPMODE_6; |
1093 | * and disabled for ecc_size1 nibbles. | 1087 | ecc_size0 = BCH_ECC_SIZE0; |
1094 | */ | 1088 | ecc_size1 = BCH_ECC_SIZE1; |
1095 | ecc_size0 = (nerrors == 8) ? | ||
1096 | BCH8R_ECC_SIZE0 : BCH4R_ECC_SIZE0; | ||
1097 | ecc_size1 = (nerrors == 8) ? | ||
1098 | BCH8R_ECC_SIZE1 : BCH4R_ECC_SIZE1; | ||
1099 | } | 1089 | } |
1100 | 1090 | break; | |
1101 | /* Perform ecc calculation for one page (< 4096) */ | 1091 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: |
1102 | nsectors = info->nand.ecc.steps; | 1092 | bch_type = 1; |
1093 | nsectors = 1; | ||
1094 | if (mode == NAND_ECC_READ) { | ||
1095 | wr_mode = BCH_WRAPMODE_6; | ||
1096 | ecc_size0 = BCH_ECC_SIZE0; | ||
1097 | ecc_size1 = BCH_ECC_SIZE1; | ||
1098 | } else { | ||
1099 | wr_mode = BCH_WRAPMODE_6; | ||
1100 | ecc_size0 = BCH_ECC_SIZE0; | ||
1101 | ecc_size1 = BCH_ECC_SIZE1; | ||
1102 | } | ||
1103 | break; | ||
1104 | case OMAP_ECC_BCH8_CODE_HW: | ||
1105 | bch_type = 1; | ||
1106 | nsectors = chip->ecc.steps; | ||
1107 | if (mode == NAND_ECC_READ) { | ||
1108 | wr_mode = BCH_WRAPMODE_1; | ||
1109 | ecc_size0 = BCH8R_ECC_SIZE0; | ||
1110 | ecc_size1 = BCH8R_ECC_SIZE1; | ||
1111 | } else { | ||
1112 | wr_mode = BCH_WRAPMODE_6; | ||
1113 | ecc_size0 = BCH_ECC_SIZE0; | ||
1114 | ecc_size1 = BCH_ECC_SIZE1; | ||
1115 | } | ||
1116 | break; | ||
1117 | default: | ||
1118 | return; | ||
1103 | } | 1119 | } |
1104 | 1120 | ||
1105 | writel(ECC1, info->reg.gpmc_ecc_control); | 1121 | writel(ECC1, info->reg.gpmc_ecc_control); |
@@ -1112,7 +1128,7 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode) | |||
1112 | 1128 | ||
1113 | /* BCH configuration */ | 1129 | /* BCH configuration */ |
1114 | val = ((1 << 16) | /* enable BCH */ | 1130 | val = ((1 << 16) | /* enable BCH */ |
1115 | (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */ | 1131 | (bch_type << 12) | /* BCH4/BCH8/BCH16 */ |
1116 | (wr_mode << 8) | /* wrap mode */ | 1132 | (wr_mode << 8) | /* wrap mode */ |
1117 | (dev_width << 7) | /* bus width */ | 1133 | (dev_width << 7) | /* bus width */ |
1118 | (((nsectors-1) & 0x7) << 4) | /* number of sectors */ | 1134 | (((nsectors-1) & 0x7) << 4) | /* number of sectors */ |
@@ -1124,132 +1140,40 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode) | |||
1124 | /* Clear ecc and enable bits */ | 1140 | /* Clear ecc and enable bits */ |
1125 | writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); | 1141 | writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); |
1126 | } | 1142 | } |
1127 | #endif | ||
1128 | |||
1129 | #ifdef CONFIG_MTD_NAND_ECC_BCH | ||
1130 | /** | ||
1131 | * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes | ||
1132 | * @mtd: MTD device structure | ||
1133 | * @dat: The pointer to data on which ecc is computed | ||
1134 | * @ecc_code: The ecc_code buffer | ||
1135 | */ | ||
1136 | static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat, | ||
1137 | u_char *ecc_code) | ||
1138 | { | ||
1139 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | ||
1140 | mtd); | ||
1141 | unsigned long nsectors, val1, val2; | ||
1142 | int i; | ||
1143 | |||
1144 | nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; | ||
1145 | |||
1146 | for (i = 0; i < nsectors; i++) { | ||
1147 | 1143 | ||
1148 | /* Read hw-computed remainder */ | 1144 | static u8 bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f}; |
1149 | val1 = readl(info->reg.gpmc_bch_result0[i]); | 1145 | static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2, |
1150 | val2 = readl(info->reg.gpmc_bch_result1[i]); | 1146 | 0x97, 0x79, 0xe5, 0x24, 0xb5}; |
1151 | |||
1152 | /* | ||
1153 | * Add constant polynomial to remainder, in order to get an ecc | ||
1154 | * sequence of 0xFFs for a buffer filled with 0xFFs; and | ||
1155 | * left-justify the resulting polynomial. | ||
1156 | */ | ||
1157 | *ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF); | ||
1158 | *ecc_code++ = 0x13 ^ ((val2 >> 4) & 0xFF); | ||
1159 | *ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF)); | ||
1160 | *ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF); | ||
1161 | *ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF); | ||
1162 | *ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF); | ||
1163 | *ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4); | ||
1164 | } | ||
1165 | |||
1166 | return 0; | ||
1167 | } | ||
1168 | 1147 | ||
1169 | /** | 1148 | /** |
1170 | * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes | 1149 | * omap_calculate_ecc_bch - Generate bytes of ECC bytes |
1171 | * @mtd: MTD device structure | ||
1172 | * @dat: The pointer to data on which ecc is computed | ||
1173 | * @ecc_code: The ecc_code buffer | ||
1174 | */ | ||
1175 | static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat, | ||
1176 | u_char *ecc_code) | ||
1177 | { | ||
1178 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | ||
1179 | mtd); | ||
1180 | unsigned long nsectors, val1, val2, val3, val4; | ||
1181 | int i; | ||
1182 | |||
1183 | nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; | ||
1184 | |||
1185 | for (i = 0; i < nsectors; i++) { | ||
1186 | |||
1187 | /* Read hw-computed remainder */ | ||
1188 | val1 = readl(info->reg.gpmc_bch_result0[i]); | ||
1189 | val2 = readl(info->reg.gpmc_bch_result1[i]); | ||
1190 | val3 = readl(info->reg.gpmc_bch_result2[i]); | ||
1191 | val4 = readl(info->reg.gpmc_bch_result3[i]); | ||
1192 | |||
1193 | /* | ||
1194 | * Add constant polynomial to remainder, in order to get an ecc | ||
1195 | * sequence of 0xFFs for a buffer filled with 0xFFs. | ||
1196 | */ | ||
1197 | *ecc_code++ = 0xef ^ (val4 & 0xFF); | ||
1198 | *ecc_code++ = 0x51 ^ ((val3 >> 24) & 0xFF); | ||
1199 | *ecc_code++ = 0x2e ^ ((val3 >> 16) & 0xFF); | ||
1200 | *ecc_code++ = 0x09 ^ ((val3 >> 8) & 0xFF); | ||
1201 | *ecc_code++ = 0xed ^ (val3 & 0xFF); | ||
1202 | *ecc_code++ = 0x93 ^ ((val2 >> 24) & 0xFF); | ||
1203 | *ecc_code++ = 0x9a ^ ((val2 >> 16) & 0xFF); | ||
1204 | *ecc_code++ = 0xc2 ^ ((val2 >> 8) & 0xFF); | ||
1205 | *ecc_code++ = 0x97 ^ (val2 & 0xFF); | ||
1206 | *ecc_code++ = 0x79 ^ ((val1 >> 24) & 0xFF); | ||
1207 | *ecc_code++ = 0xe5 ^ ((val1 >> 16) & 0xFF); | ||
1208 | *ecc_code++ = 0x24 ^ ((val1 >> 8) & 0xFF); | ||
1209 | *ecc_code++ = 0xb5 ^ (val1 & 0xFF); | ||
1210 | } | ||
1211 | |||
1212 | return 0; | ||
1213 | } | ||
1214 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | ||
1215 | |||
1216 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
1217 | /** | ||
1218 | * omap3_calculate_ecc_bch - Generate bytes of ECC bytes | ||
1219 | * @mtd: MTD device structure | 1150 | * @mtd: MTD device structure |
1220 | * @dat: The pointer to data on which ecc is computed | 1151 | * @dat: The pointer to data on which ecc is computed |
1221 | * @ecc_code: The ecc_code buffer | 1152 | * @ecc_code: The ecc_code buffer |
1222 | * | 1153 | * |
1223 | * Support calculating of BCH4/8 ecc vectors for the page | 1154 | * Support calculating of BCH4/8 ecc vectors for the page |
1224 | */ | 1155 | */ |
1225 | static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, | 1156 | static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, |
1226 | u_char *ecc_code) | 1157 | const u_char *dat, u_char *ecc_calc) |
1227 | { | 1158 | { |
1228 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1159 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
1229 | mtd); | 1160 | mtd); |
1161 | int eccbytes = info->nand.ecc.bytes; | ||
1162 | struct gpmc_nand_regs *gpmc_regs = &info->reg; | ||
1163 | u8 *ecc_code; | ||
1230 | unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; | 1164 | unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; |
1231 | int i, eccbchtsel; | 1165 | int i; |
1232 | 1166 | ||
1233 | nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; | 1167 | nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; |
1234 | /* | ||
1235 | * find BCH scheme used | ||
1236 | * 0 -> BCH4 | ||
1237 | * 1 -> BCH8 | ||
1238 | */ | ||
1239 | eccbchtsel = ((readl(info->reg.gpmc_ecc_config) >> 12) & 0x3); | ||
1240 | |||
1241 | for (i = 0; i < nsectors; i++) { | 1168 | for (i = 0; i < nsectors; i++) { |
1242 | 1169 | ecc_code = ecc_calc; | |
1243 | /* Read hw-computed remainder */ | 1170 | switch (info->ecc_opt) { |
1244 | bch_val1 = readl(info->reg.gpmc_bch_result0[i]); | 1171 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: |
1245 | bch_val2 = readl(info->reg.gpmc_bch_result1[i]); | 1172 | case OMAP_ECC_BCH8_CODE_HW: |
1246 | if (eccbchtsel) { | 1173 | bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); |
1247 | bch_val3 = readl(info->reg.gpmc_bch_result2[i]); | 1174 | bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); |
1248 | bch_val4 = readl(info->reg.gpmc_bch_result3[i]); | 1175 | bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]); |
1249 | } | 1176 | bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]); |
1250 | |||
1251 | if (eccbchtsel) { | ||
1252 | /* BCH8 ecc scheme */ | ||
1253 | *ecc_code++ = (bch_val4 & 0xFF); | 1177 | *ecc_code++ = (bch_val4 & 0xFF); |
1254 | *ecc_code++ = ((bch_val3 >> 24) & 0xFF); | 1178 | *ecc_code++ = ((bch_val3 >> 24) & 0xFF); |
1255 | *ecc_code++ = ((bch_val3 >> 16) & 0xFF); | 1179 | *ecc_code++ = ((bch_val3 >> 16) & 0xFF); |
@@ -1263,14 +1187,11 @@ static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, | |||
1263 | *ecc_code++ = ((bch_val1 >> 16) & 0xFF); | 1187 | *ecc_code++ = ((bch_val1 >> 16) & 0xFF); |
1264 | *ecc_code++ = ((bch_val1 >> 8) & 0xFF); | 1188 | *ecc_code++ = ((bch_val1 >> 8) & 0xFF); |
1265 | *ecc_code++ = (bch_val1 & 0xFF); | 1189 | *ecc_code++ = (bch_val1 & 0xFF); |
1266 | /* | 1190 | break; |
1267 | * Setting 14th byte to zero to handle | 1191 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: |
1268 | * erased page & maintain compatibility | 1192 | case OMAP_ECC_BCH4_CODE_HW: |
1269 | * with RBL | 1193 | bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); |
1270 | */ | 1194 | bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); |
1271 | *ecc_code++ = 0x0; | ||
1272 | } else { | ||
1273 | /* BCH4 ecc scheme */ | ||
1274 | *ecc_code++ = ((bch_val2 >> 12) & 0xFF); | 1195 | *ecc_code++ = ((bch_val2 >> 12) & 0xFF); |
1275 | *ecc_code++ = ((bch_val2 >> 4) & 0xFF); | 1196 | *ecc_code++ = ((bch_val2 >> 4) & 0xFF); |
1276 | *ecc_code++ = ((bch_val2 & 0xF) << 4) | | 1197 | *ecc_code++ = ((bch_val2 & 0xF) << 4) | |
@@ -1279,12 +1200,38 @@ static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, | |||
1279 | *ecc_code++ = ((bch_val1 >> 12) & 0xFF); | 1200 | *ecc_code++ = ((bch_val1 >> 12) & 0xFF); |
1280 | *ecc_code++ = ((bch_val1 >> 4) & 0xFF); | 1201 | *ecc_code++ = ((bch_val1 >> 4) & 0xFF); |
1281 | *ecc_code++ = ((bch_val1 & 0xF) << 4); | 1202 | *ecc_code++ = ((bch_val1 & 0xF) << 4); |
1282 | /* | 1203 | break; |
1283 | * Setting 8th byte to zero to handle | 1204 | default: |
1284 | * erased page | 1205 | return -EINVAL; |
1285 | */ | ||
1286 | *ecc_code++ = 0x0; | ||
1287 | } | 1206 | } |
1207 | |||
1208 | /* ECC scheme specific syndrome customizations */ | ||
1209 | switch (info->ecc_opt) { | ||
1210 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | ||
1211 | /* Add constant polynomial to remainder, so that | ||
1212 | * ECC of blank pages results in 0x0 on reading back */ | ||
1213 | for (i = 0; i < eccbytes; i++) | ||
1214 | ecc_calc[i] ^= bch4_polynomial[i]; | ||
1215 | break; | ||
1216 | case OMAP_ECC_BCH4_CODE_HW: | ||
1217 | /* Set 8th ECC byte as 0x0 for ROM compatibility */ | ||
1218 | ecc_calc[eccbytes - 1] = 0x0; | ||
1219 | break; | ||
1220 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: | ||
1221 | /* Add constant polynomial to remainder, so that | ||
1222 | * ECC of blank pages results in 0x0 on reading back */ | ||
1223 | for (i = 0; i < eccbytes; i++) | ||
1224 | ecc_calc[i] ^= bch8_polynomial[i]; | ||
1225 | break; | ||
1226 | case OMAP_ECC_BCH8_CODE_HW: | ||
1227 | /* Set 14th ECC byte as 0x0 for ROM compatibility */ | ||
1228 | ecc_calc[eccbytes - 1] = 0x0; | ||
1229 | break; | ||
1230 | default: | ||
1231 | return -EINVAL; | ||
1232 | } | ||
1233 | |||
1234 | ecc_calc += eccbytes; | ||
1288 | } | 1235 | } |
1289 | 1236 | ||
1290 | return 0; | 1237 | return 0; |
@@ -1329,6 +1276,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob, | |||
1329 | return flip_bits; | 1276 | return flip_bits; |
1330 | } | 1277 | } |
1331 | 1278 | ||
1279 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
1332 | /** | 1280 | /** |
1333 | * omap_elm_correct_data - corrects page data area in case error reported | 1281 | * omap_elm_correct_data - corrects page data area in case error reported |
1334 | * @mtd: MTD device structure | 1282 | * @mtd: MTD device structure |
@@ -1337,55 +1285,46 @@ static int erased_sector_bitflips(u_char *data, u_char *oob, | |||
1337 | * @calc_ecc: ecc read from HW ECC registers | 1285 | * @calc_ecc: ecc read from HW ECC registers |
1338 | * | 1286 | * |
1339 | * Calculated ecc vector reported as zero in case of non-error pages. | 1287 | * Calculated ecc vector reported as zero in case of non-error pages. |
1340 | * In case of error/erased pages non-zero error vector is reported. | 1288 | * In case of non-zero ecc vector, first filter out erased-pages, and |
1341 | * In case of non-zero ecc vector, check read_ecc at fixed offset | 1289 | * then process data via ELM to detect bit-flips. |
1342 | * (x = 13/7 in case of BCH8/4 == 0) to find page programmed or not. | ||
1343 | * To handle bit flips in this data, count the number of 0's in | ||
1344 | * read_ecc[x] and check if it greater than 4. If it is less, it is | ||
1345 | * programmed page, else erased page. | ||
1346 | * | ||
1347 | * 1. If page is erased, check with standard ecc vector (ecc vector | ||
1348 | * for erased page to find any bit flip). If check fails, bit flip | ||
1349 | * is present in erased page. Count the bit flips in erased page and | ||
1350 | * if it falls under correctable level, report page with 0xFF and | ||
1351 | * update the correctable bit information. | ||
1352 | * 2. If error is reported on programmed page, update elm error | ||
1353 | * vector and correct the page with ELM error correction routine. | ||
1354 | * | ||
1355 | */ | 1290 | */ |
1356 | static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | 1291 | static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, |
1357 | u_char *read_ecc, u_char *calc_ecc) | 1292 | u_char *read_ecc, u_char *calc_ecc) |
1358 | { | 1293 | { |
1359 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1294 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
1360 | mtd); | 1295 | mtd); |
1296 | struct nand_ecc_ctrl *ecc = &info->nand.ecc; | ||
1361 | int eccsteps = info->nand.ecc.steps; | 1297 | int eccsteps = info->nand.ecc.steps; |
1362 | int i , j, stat = 0; | 1298 | int i , j, stat = 0; |
1363 | int eccsize, eccflag, ecc_vector_size; | 1299 | int eccflag, actual_eccbytes; |
1364 | struct elm_errorvec err_vec[ERROR_VECTOR_MAX]; | 1300 | struct elm_errorvec err_vec[ERROR_VECTOR_MAX]; |
1365 | u_char *ecc_vec = calc_ecc; | 1301 | u_char *ecc_vec = calc_ecc; |
1366 | u_char *spare_ecc = read_ecc; | 1302 | u_char *spare_ecc = read_ecc; |
1367 | u_char *erased_ecc_vec; | 1303 | u_char *erased_ecc_vec; |
1368 | enum bch_ecc type; | 1304 | u_char *buf; |
1305 | int bitflip_count; | ||
1369 | bool is_error_reported = false; | 1306 | bool is_error_reported = false; |
1307 | u32 bit_pos, byte_pos, error_max, pos; | ||
1308 | int err; | ||
1370 | 1309 | ||
1371 | /* Initialize elm error vector to zero */ | 1310 | switch (info->ecc_opt) { |
1372 | memset(err_vec, 0, sizeof(err_vec)); | 1311 | case OMAP_ECC_BCH4_CODE_HW: |
1373 | 1312 | /* omit 7th ECC byte reserved for ROM code compatibility */ | |
1374 | if (info->nand.ecc.strength == BCH8_MAX_ERROR) { | 1313 | actual_eccbytes = ecc->bytes - 1; |
1375 | type = BCH8_ECC; | ||
1376 | erased_ecc_vec = bch8_vector; | ||
1377 | } else { | ||
1378 | type = BCH4_ECC; | ||
1379 | erased_ecc_vec = bch4_vector; | 1314 | erased_ecc_vec = bch4_vector; |
1315 | break; | ||
1316 | case OMAP_ECC_BCH8_CODE_HW: | ||
1317 | /* omit 14th ECC byte reserved for ROM code compatibility */ | ||
1318 | actual_eccbytes = ecc->bytes - 1; | ||
1319 | erased_ecc_vec = bch8_vector; | ||
1320 | break; | ||
1321 | default: | ||
1322 | pr_err("invalid driver configuration\n"); | ||
1323 | return -EINVAL; | ||
1380 | } | 1324 | } |
1381 | 1325 | ||
1382 | ecc_vector_size = info->nand.ecc.bytes; | 1326 | /* Initialize elm error vector to zero */ |
1383 | 1327 | memset(err_vec, 0, sizeof(err_vec)); | |
1384 | /* | ||
1385 | * Remove extra byte padding for BCH8 RBL | ||
1386 | * compatibility and erased page handling | ||
1387 | */ | ||
1388 | eccsize = ecc_vector_size - 1; | ||
1389 | 1328 | ||
1390 | for (i = 0; i < eccsteps ; i++) { | 1329 | for (i = 0; i < eccsteps ; i++) { |
1391 | eccflag = 0; /* initialize eccflag */ | 1330 | eccflag = 0; /* initialize eccflag */ |
@@ -1394,8 +1333,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | |||
1394 | * Check any error reported, | 1333 | * Check any error reported, |
1395 | * In case of error, non zero ecc reported. | 1334 | * In case of error, non zero ecc reported. |
1396 | */ | 1335 | */ |
1397 | 1336 | for (j = 0; j < actual_eccbytes; j++) { | |
1398 | for (j = 0; (j < eccsize); j++) { | ||
1399 | if (calc_ecc[j] != 0) { | 1337 | if (calc_ecc[j] != 0) { |
1400 | eccflag = 1; /* non zero ecc, error present */ | 1338 | eccflag = 1; /* non zero ecc, error present */ |
1401 | break; | 1339 | break; |
@@ -1403,50 +1341,43 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | |||
1403 | } | 1341 | } |
1404 | 1342 | ||
1405 | if (eccflag == 1) { | 1343 | if (eccflag == 1) { |
1406 | /* | 1344 | if (memcmp(calc_ecc, erased_ecc_vec, |
1407 | * Set threshold to minimum of 4, half of ecc.strength/2 | 1345 | actual_eccbytes) == 0) { |
1408 | * to allow max bit flip in byte to 4 | ||
1409 | */ | ||
1410 | unsigned int threshold = min_t(unsigned int, 4, | ||
1411 | info->nand.ecc.strength / 2); | ||
1412 | |||
1413 | /* | ||
1414 | * Check data area is programmed by counting | ||
1415 | * number of 0's at fixed offset in spare area. | ||
1416 | * Checking count of 0's against threshold. | ||
1417 | * In case programmed page expects at least threshold | ||
1418 | * zeros in byte. | ||
1419 | * If zeros are less than threshold for programmed page/ | ||
1420 | * zeros are more than threshold erased page, either | ||
1421 | * case page reported as uncorrectable. | ||
1422 | */ | ||
1423 | if (hweight8(~read_ecc[eccsize]) >= threshold) { | ||
1424 | /* | 1346 | /* |
1425 | * Update elm error vector as | 1347 | * calc_ecc[] matches pattern for ECC(all 0xff) |
1426 | * data area is programmed | 1348 | * so this is definitely an erased-page |
1427 | */ | 1349 | */ |
1428 | err_vec[i].error_reported = true; | ||
1429 | is_error_reported = true; | ||
1430 | } else { | 1350 | } else { |
1431 | /* Error reported in erased page */ | 1351 | buf = &data[info->nand.ecc.size * i]; |
1432 | int bitflip_count; | 1352 | /* |
1433 | u_char *buf = &data[info->nand.ecc.size * i]; | 1353 | * count number of 0-bits in read_buf. |
1434 | 1354 | * This check can be removed once a similar | |
1435 | if (memcmp(calc_ecc, erased_ecc_vec, eccsize)) { | 1355 | * check is introduced in generic NAND driver |
1436 | bitflip_count = erased_sector_bitflips( | 1356 | */ |
1437 | buf, read_ecc, info); | 1357 | bitflip_count = erased_sector_bitflips( |
1438 | 1358 | buf, read_ecc, info); | |
1439 | if (bitflip_count) | 1359 | if (bitflip_count) { |
1440 | stat += bitflip_count; | 1360 | /* |
1441 | else | 1361 | * number of 0-bits within ECC limits |
1442 | return -EINVAL; | 1362 | * So this may be an erased-page |
1363 | */ | ||
1364 | stat += bitflip_count; | ||
1365 | } else { | ||
1366 | /* | ||
1367 | * Too many 0-bits. It may be a | ||
1368 | * - programmed-page, OR | ||
1369 | * - erased-page with many bit-flips | ||
1370 | * So this page requires check by ELM | ||
1371 | */ | ||
1372 | err_vec[i].error_reported = true; | ||
1373 | is_error_reported = true; | ||
1443 | } | 1374 | } |
1444 | } | 1375 | } |
1445 | } | 1376 | } |
1446 | 1377 | ||
1447 | /* Update the ecc vector */ | 1378 | /* Update the ecc vector */ |
1448 | calc_ecc += ecc_vector_size; | 1379 | calc_ecc += ecc->bytes; |
1449 | read_ecc += ecc_vector_size; | 1380 | read_ecc += ecc->bytes; |
1450 | } | 1381 | } |
1451 | 1382 | ||
1452 | /* Check if any error reported */ | 1383 | /* Check if any error reported */ |
@@ -1456,23 +1387,26 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | |||
1456 | /* Decode BCH error using ELM module */ | 1387 | /* Decode BCH error using ELM module */ |
1457 | elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec); | 1388 | elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec); |
1458 | 1389 | ||
1390 | err = 0; | ||
1459 | for (i = 0; i < eccsteps; i++) { | 1391 | for (i = 0; i < eccsteps; i++) { |
1460 | if (err_vec[i].error_reported) { | 1392 | if (err_vec[i].error_uncorrectable) { |
1393 | pr_err("nand: uncorrectable bit-flips found\n"); | ||
1394 | err = -EBADMSG; | ||
1395 | } else if (err_vec[i].error_reported) { | ||
1461 | for (j = 0; j < err_vec[i].error_count; j++) { | 1396 | for (j = 0; j < err_vec[i].error_count; j++) { |
1462 | u32 bit_pos, byte_pos, error_max, pos; | 1397 | switch (info->ecc_opt) { |
1463 | 1398 | case OMAP_ECC_BCH4_CODE_HW: | |
1464 | if (type == BCH8_ECC) | 1399 | /* Add 4 bits to take care of padding */ |
1465 | error_max = BCH8_ECC_MAX; | ||
1466 | else | ||
1467 | error_max = BCH4_ECC_MAX; | ||
1468 | |||
1469 | if (info->nand.ecc.strength == BCH8_MAX_ERROR) | ||
1470 | pos = err_vec[i].error_loc[j]; | ||
1471 | else | ||
1472 | /* Add 4 to take care 4 bit padding */ | ||
1473 | pos = err_vec[i].error_loc[j] + | 1400 | pos = err_vec[i].error_loc[j] + |
1474 | BCH4_BIT_PAD; | 1401 | BCH4_BIT_PAD; |
1475 | 1402 | break; | |
1403 | case OMAP_ECC_BCH8_CODE_HW: | ||
1404 | pos = err_vec[i].error_loc[j]; | ||
1405 | break; | ||
1406 | default: | ||
1407 | return -EINVAL; | ||
1408 | } | ||
1409 | error_max = (ecc->size + actual_eccbytes) * 8; | ||
1476 | /* Calculate bit position of error */ | 1410 | /* Calculate bit position of error */ |
1477 | bit_pos = pos % 8; | 1411 | bit_pos = pos % 8; |
1478 | 1412 | ||
@@ -1480,13 +1414,22 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | |||
1480 | byte_pos = (error_max - pos - 1) / 8; | 1414 | byte_pos = (error_max - pos - 1) / 8; |
1481 | 1415 | ||
1482 | if (pos < error_max) { | 1416 | if (pos < error_max) { |
1483 | if (byte_pos < 512) | 1417 | if (byte_pos < 512) { |
1418 | pr_debug("bitflip@dat[%d]=%x\n", | ||
1419 | byte_pos, data[byte_pos]); | ||
1484 | data[byte_pos] ^= 1 << bit_pos; | 1420 | data[byte_pos] ^= 1 << bit_pos; |
1485 | else | 1421 | } else { |
1422 | pr_debug("bitflip@oob[%d]=%x\n", | ||
1423 | (byte_pos - 512), | ||
1424 | spare_ecc[byte_pos - 512]); | ||
1486 | spare_ecc[byte_pos - 512] ^= | 1425 | spare_ecc[byte_pos - 512] ^= |
1487 | 1 << bit_pos; | 1426 | 1 << bit_pos; |
1427 | } | ||
1428 | } else { | ||
1429 | pr_err("invalid bit-flip @ %d:%d\n", | ||
1430 | byte_pos, bit_pos); | ||
1431 | err = -EBADMSG; | ||
1488 | } | 1432 | } |
1489 | /* else, not interested to correct ecc */ | ||
1490 | } | 1433 | } |
1491 | } | 1434 | } |
1492 | 1435 | ||
@@ -1494,16 +1437,11 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | |||
1494 | stat += err_vec[i].error_count; | 1437 | stat += err_vec[i].error_count; |
1495 | 1438 | ||
1496 | /* Update page data with sector size */ | 1439 | /* Update page data with sector size */ |
1497 | data += info->nand.ecc.size; | 1440 | data += ecc->size; |
1498 | spare_ecc += ecc_vector_size; | 1441 | spare_ecc += ecc->bytes; |
1499 | } | 1442 | } |
1500 | 1443 | ||
1501 | for (i = 0; i < eccsteps; i++) | 1444 | return (err) ? err : stat; |
1502 | /* Return error if uncorrectable error present */ | ||
1503 | if (err_vec[i].error_uncorrectable) | ||
1504 | return -EINVAL; | ||
1505 | |||
1506 | return stat; | ||
1507 | } | 1445 | } |
1508 | 1446 | ||
1509 | /** | 1447 | /** |
@@ -1601,7 +1539,8 @@ static int is_elm_present(struct omap_nand_info *info, | |||
1601 | struct device_node *elm_node, enum bch_ecc bch_type) | 1539 | struct device_node *elm_node, enum bch_ecc bch_type) |
1602 | { | 1540 | { |
1603 | struct platform_device *pdev; | 1541 | struct platform_device *pdev; |
1604 | info->is_elm_used = false; | 1542 | struct nand_ecc_ctrl *ecc = &info->nand.ecc; |
1543 | int err; | ||
1605 | /* check whether elm-id is passed via DT */ | 1544 | /* check whether elm-id is passed via DT */ |
1606 | if (!elm_node) { | 1545 | if (!elm_node) { |
1607 | pr_err("nand: error: ELM DT node not found\n"); | 1546 | pr_err("nand: error: ELM DT node not found\n"); |
@@ -1615,10 +1554,10 @@ static int is_elm_present(struct omap_nand_info *info, | |||
1615 | } | 1554 | } |
1616 | /* ELM module available, now configure it */ | 1555 | /* ELM module available, now configure it */ |
1617 | info->elm_dev = &pdev->dev; | 1556 | info->elm_dev = &pdev->dev; |
1618 | if (elm_config(info->elm_dev, bch_type)) | 1557 | err = elm_config(info->elm_dev, bch_type, |
1619 | return -ENODEV; | 1558 | (info->mtd.writesize / ecc->size), ecc->size, ecc->bytes); |
1620 | info->is_elm_used = true; | 1559 | |
1621 | return 0; | 1560 | return err; |
1622 | } | 1561 | } |
1623 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | 1562 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ |
1624 | 1563 | ||
@@ -1657,6 +1596,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1657 | info->gpmc_cs = pdata->cs; | 1596 | info->gpmc_cs = pdata->cs; |
1658 | info->reg = pdata->reg; | 1597 | info->reg = pdata->reg; |
1659 | info->of_node = pdata->of_node; | 1598 | info->of_node = pdata->of_node; |
1599 | info->ecc_opt = pdata->ecc_opt; | ||
1660 | mtd = &info->mtd; | 1600 | mtd = &info->mtd; |
1661 | mtd->priv = &info->nand; | 1601 | mtd->priv = &info->nand; |
1662 | mtd->name = dev_name(&pdev->dev); | 1602 | mtd->name = dev_name(&pdev->dev); |
@@ -1666,27 +1606,11 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1666 | nand_chip->options |= NAND_SKIP_BBTSCAN; | 1606 | nand_chip->options |= NAND_SKIP_BBTSCAN; |
1667 | 1607 | ||
1668 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1608 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1669 | if (res == NULL) { | 1609 | nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); |
1670 | err = -EINVAL; | 1610 | if (IS_ERR(nand_chip->IO_ADDR_R)) |
1671 | dev_err(&pdev->dev, "error getting memory resource\n"); | 1611 | return PTR_ERR(nand_chip->IO_ADDR_R); |
1672 | goto return_error; | ||
1673 | } | ||
1674 | 1612 | ||
1675 | info->phys_base = res->start; | 1613 | info->phys_base = res->start; |
1676 | info->mem_size = resource_size(res); | ||
1677 | |||
1678 | if (!devm_request_mem_region(&pdev->dev, info->phys_base, | ||
1679 | info->mem_size, pdev->dev.driver->name)) { | ||
1680 | err = -EBUSY; | ||
1681 | goto return_error; | ||
1682 | } | ||
1683 | |||
1684 | nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base, | ||
1685 | info->mem_size); | ||
1686 | if (!nand_chip->IO_ADDR_R) { | ||
1687 | err = -ENOMEM; | ||
1688 | goto return_error; | ||
1689 | } | ||
1690 | 1614 | ||
1691 | nand_chip->controller = &info->controller; | 1615 | nand_chip->controller = &info->controller; |
1692 | 1616 | ||
@@ -1812,7 +1736,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1812 | /* populate MTD interface based on ECC scheme */ | 1736 | /* populate MTD interface based on ECC scheme */ |
1813 | nand_chip->ecc.layout = &omap_oobinfo; | 1737 | nand_chip->ecc.layout = &omap_oobinfo; |
1814 | ecclayout = &omap_oobinfo; | 1738 | ecclayout = &omap_oobinfo; |
1815 | switch (pdata->ecc_opt) { | 1739 | switch (info->ecc_opt) { |
1816 | case OMAP_ECC_HAM1_CODE_HW: | 1740 | case OMAP_ECC_HAM1_CODE_HW: |
1817 | pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n"); | 1741 | pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n"); |
1818 | nand_chip->ecc.mode = NAND_ECC_HW; | 1742 | nand_chip->ecc.mode = NAND_ECC_HW; |
@@ -1844,9 +1768,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1844 | nand_chip->ecc.size = 512; | 1768 | nand_chip->ecc.size = 512; |
1845 | nand_chip->ecc.bytes = 7; | 1769 | nand_chip->ecc.bytes = 7; |
1846 | nand_chip->ecc.strength = 4; | 1770 | nand_chip->ecc.strength = 4; |
1847 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; | 1771 | nand_chip->ecc.hwctl = omap_enable_hwecc_bch; |
1848 | nand_chip->ecc.correct = nand_bch_correct_data; | 1772 | nand_chip->ecc.correct = nand_bch_correct_data; |
1849 | nand_chip->ecc.calculate = omap3_calculate_ecc_bch4; | 1773 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
1850 | /* define ECC layout */ | 1774 | /* define ECC layout */ |
1851 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1775 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1852 | (mtd->writesize / | 1776 | (mtd->writesize / |
@@ -1884,9 +1808,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1884 | /* 14th bit is kept reserved for ROM-code compatibility */ | 1808 | /* 14th bit is kept reserved for ROM-code compatibility */ |
1885 | nand_chip->ecc.bytes = 7 + 1; | 1809 | nand_chip->ecc.bytes = 7 + 1; |
1886 | nand_chip->ecc.strength = 4; | 1810 | nand_chip->ecc.strength = 4; |
1887 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; | 1811 | nand_chip->ecc.hwctl = omap_enable_hwecc_bch; |
1888 | nand_chip->ecc.correct = omap_elm_correct_data; | 1812 | nand_chip->ecc.correct = omap_elm_correct_data; |
1889 | nand_chip->ecc.calculate = omap3_calculate_ecc_bch; | 1813 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
1890 | nand_chip->ecc.read_page = omap_read_page_bch; | 1814 | nand_chip->ecc.read_page = omap_read_page_bch; |
1891 | nand_chip->ecc.write_page = omap_write_page_bch; | 1815 | nand_chip->ecc.write_page = omap_write_page_bch; |
1892 | /* define ECC layout */ | 1816 | /* define ECC layout */ |
@@ -1919,9 +1843,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1919 | nand_chip->ecc.size = 512; | 1843 | nand_chip->ecc.size = 512; |
1920 | nand_chip->ecc.bytes = 13; | 1844 | nand_chip->ecc.bytes = 13; |
1921 | nand_chip->ecc.strength = 8; | 1845 | nand_chip->ecc.strength = 8; |
1922 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; | 1846 | nand_chip->ecc.hwctl = omap_enable_hwecc_bch; |
1923 | nand_chip->ecc.correct = nand_bch_correct_data; | 1847 | nand_chip->ecc.correct = nand_bch_correct_data; |
1924 | nand_chip->ecc.calculate = omap3_calculate_ecc_bch8; | 1848 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
1925 | /* define ECC layout */ | 1849 | /* define ECC layout */ |
1926 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1850 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1927 | (mtd->writesize / | 1851 | (mtd->writesize / |
@@ -1960,9 +1884,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1960 | /* 14th bit is kept reserved for ROM-code compatibility */ | 1884 | /* 14th bit is kept reserved for ROM-code compatibility */ |
1961 | nand_chip->ecc.bytes = 13 + 1; | 1885 | nand_chip->ecc.bytes = 13 + 1; |
1962 | nand_chip->ecc.strength = 8; | 1886 | nand_chip->ecc.strength = 8; |
1963 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; | 1887 | nand_chip->ecc.hwctl = omap_enable_hwecc_bch; |
1964 | nand_chip->ecc.correct = omap_elm_correct_data; | 1888 | nand_chip->ecc.correct = omap_elm_correct_data; |
1965 | nand_chip->ecc.calculate = omap3_calculate_ecc_bch; | 1889 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
1966 | nand_chip->ecc.read_page = omap_read_page_bch; | 1890 | nand_chip->ecc.read_page = omap_read_page_bch; |
1967 | nand_chip->ecc.write_page = omap_write_page_bch; | 1891 | nand_chip->ecc.write_page = omap_write_page_bch; |
1968 | /* This ECC scheme requires ELM H/W block */ | 1892 | /* This ECC scheme requires ELM H/W block */ |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 90f871acb0ef..2c98f9da7471 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #undef DEBUG | 23 | #undef DEBUG |
24 | 24 | ||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/init.h> | ||
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | #include <linux/mtd/mtd.h> | 27 | #include <linux/mtd/mtd.h> |
29 | #include <linux/mtd/nand.h> | 28 | #include <linux/mtd/nand.h> |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 2a7a0b27ac38..7588fe2c127f 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #include <linux/platform_data/mtd-nand-pxa3xx.h> | 39 | #include <linux/platform_data/mtd-nand-pxa3xx.h> |
40 | 40 | ||
41 | #define NAND_DEV_READY_TIMEOUT 50 | ||
42 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) | 41 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) |
43 | #define NAND_STOP_DELAY (2 * HZ/50) | 42 | #define NAND_STOP_DELAY (2 * HZ/50) |
44 | #define PAGE_CHUNK_SIZE (2048) | 43 | #define PAGE_CHUNK_SIZE (2048) |
@@ -1531,7 +1530,7 @@ KEEP_CONFIG: | |||
1531 | if (!ret) { | 1530 | if (!ret) { |
1532 | dev_err(&info->pdev->dev, | 1531 | dev_err(&info->pdev->dev, |
1533 | "ECC strength %d at page size %d is not supported\n", | 1532 | "ECC strength %d at page size %d is not supported\n", |
1534 | chip->ecc_strength_ds, mtd->writesize); | 1533 | ecc_strength, mtd->writesize); |
1535 | return -ENODEV; | 1534 | return -ENODEV; |
1536 | } | 1535 | } |
1537 | 1536 | ||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index f0918e7411d9..79acbb8691b5 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
34 | #include <linux/string.h> | 33 | #include <linux/string.h> |
35 | #include <linux/io.h> | 34 | #include <linux/io.h> |