diff options
Diffstat (limited to 'drivers/mtd/nand/omap2.c')
-rw-r--r-- | drivers/mtd/nand/omap2.c | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f77725009907..bf642ceef681 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1633,6 +1633,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1633 | int i; | 1633 | int i; |
1634 | dma_cap_mask_t mask; | 1634 | dma_cap_mask_t mask; |
1635 | unsigned sig; | 1635 | unsigned sig; |
1636 | unsigned oob_index; | ||
1636 | struct resource *res; | 1637 | struct resource *res; |
1637 | struct mtd_part_parser_data ppdata = {}; | 1638 | struct mtd_part_parser_data ppdata = {}; |
1638 | 1639 | ||
@@ -1730,13 +1731,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1730 | break; | 1731 | break; |
1731 | 1732 | ||
1732 | case NAND_OMAP_POLLED: | 1733 | case NAND_OMAP_POLLED: |
1733 | if (nand_chip->options & NAND_BUSWIDTH_16) { | 1734 | /* Use nand_base defaults for {read,write}_buf */ |
1734 | nand_chip->read_buf = omap_read_buf16; | ||
1735 | nand_chip->write_buf = omap_write_buf16; | ||
1736 | } else { | ||
1737 | nand_chip->read_buf = omap_read_buf8; | ||
1738 | nand_chip->write_buf = omap_write_buf8; | ||
1739 | } | ||
1740 | break; | 1735 | break; |
1741 | 1736 | ||
1742 | case NAND_OMAP_PREFETCH_DMA: | 1737 | case NAND_OMAP_PREFETCH_DMA: |
@@ -1832,11 +1827,14 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1832 | (mtd->writesize / | 1827 | (mtd->writesize / |
1833 | nand_chip->ecc.size); | 1828 | nand_chip->ecc.size); |
1834 | if (nand_chip->options & NAND_BUSWIDTH_16) | 1829 | if (nand_chip->options & NAND_BUSWIDTH_16) |
1835 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1830 | oob_index = BADBLOCK_MARKER_LENGTH; |
1836 | else | 1831 | else |
1837 | ecclayout->eccpos[0] = 1; | 1832 | oob_index = 1; |
1838 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1833 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1839 | ecclayout->eccbytes; | 1834 | ecclayout->eccpos[i] = oob_index; |
1835 | /* no reserved-marker in ecclayout for this ecc-scheme */ | ||
1836 | ecclayout->oobfree->offset = | ||
1837 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1840 | break; | 1838 | break; |
1841 | 1839 | ||
1842 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | 1840 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: |
@@ -1853,9 +1851,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1853 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1851 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1854 | (mtd->writesize / | 1852 | (mtd->writesize / |
1855 | nand_chip->ecc.size); | 1853 | nand_chip->ecc.size); |
1856 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1854 | oob_index = BADBLOCK_MARKER_LENGTH; |
1857 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1855 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1858 | ecclayout->eccbytes; | 1856 | ecclayout->eccpos[i] = oob_index; |
1857 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1858 | oob_index++; | ||
1859 | } | ||
1860 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1861 | ecclayout->oobfree->offset = 1 + | ||
1862 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1859 | /* software bch library is used for locating errors */ | 1863 | /* software bch library is used for locating errors */ |
1860 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1864 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1861 | nand_chip->ecc.size, | 1865 | nand_chip->ecc.size, |
@@ -1889,9 +1893,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1889 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1893 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1890 | (mtd->writesize / | 1894 | (mtd->writesize / |
1891 | nand_chip->ecc.size); | 1895 | nand_chip->ecc.size); |
1892 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1896 | oob_index = BADBLOCK_MARKER_LENGTH; |
1893 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1897 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1894 | ecclayout->eccbytes; | 1898 | ecclayout->eccpos[i] = oob_index; |
1899 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1900 | ecclayout->oobfree->offset = | ||
1901 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1895 | /* This ECC scheme requires ELM H/W block */ | 1902 | /* This ECC scheme requires ELM H/W block */ |
1896 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { | 1903 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { |
1897 | pr_err("nand: error: could not initialize ELM\n"); | 1904 | pr_err("nand: error: could not initialize ELM\n"); |
@@ -1919,9 +1926,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1919 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1926 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1920 | (mtd->writesize / | 1927 | (mtd->writesize / |
1921 | nand_chip->ecc.size); | 1928 | nand_chip->ecc.size); |
1922 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1929 | oob_index = BADBLOCK_MARKER_LENGTH; |
1923 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1930 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1924 | ecclayout->eccbytes; | 1931 | ecclayout->eccpos[i] = oob_index; |
1932 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1933 | oob_index++; | ||
1934 | } | ||
1935 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1936 | ecclayout->oobfree->offset = 1 + | ||
1937 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1925 | /* software bch library is used for locating errors */ | 1938 | /* software bch library is used for locating errors */ |
1926 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1939 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1927 | nand_chip->ecc.size, | 1940 | nand_chip->ecc.size, |
@@ -1962,9 +1975,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1962 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1975 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1963 | (mtd->writesize / | 1976 | (mtd->writesize / |
1964 | nand_chip->ecc.size); | 1977 | nand_chip->ecc.size); |
1965 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1978 | oob_index = BADBLOCK_MARKER_LENGTH; |
1966 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1979 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1967 | ecclayout->eccbytes; | 1980 | ecclayout->eccpos[i] = oob_index; |
1981 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1982 | ecclayout->oobfree->offset = | ||
1983 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1968 | break; | 1984 | break; |
1969 | #else | 1985 | #else |
1970 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | 1986 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); |
@@ -1978,11 +1994,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1978 | goto return_error; | 1994 | goto return_error; |
1979 | } | 1995 | } |
1980 | 1996 | ||
1981 | /* populate remaining ECC layout data */ | 1997 | /* all OOB bytes from oobfree->offset till end off OOB are free */ |
1982 | ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH + | 1998 | ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; |
1983 | ecclayout->eccbytes); | ||
1984 | for (i = 1; i < ecclayout->eccbytes; i++) | ||
1985 | ecclayout->eccpos[i] = ecclayout->eccpos[0] + i; | ||
1986 | /* check if NAND device's OOB is enough to store ECC signatures */ | 1999 | /* check if NAND device's OOB is enough to store ECC signatures */ |
1987 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { | 2000 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { |
1988 | pr_err("not enough OOB bytes required = %d, available=%d\n", | 2001 | pr_err("not enough OOB bytes required = %d, available=%d\n", |