diff options
| author | Ezequiel GarcĂa <ezequiel@vanguardiasur.com.ar> | 2014-09-20 12:53:12 -0400 |
|---|---|---|
| committer | Brian Norris <computersforpeace@gmail.com> | 2014-09-22 14:37:51 -0400 |
| commit | 93af53b8633c4cb474585158512182b21219d743 (patch) | |
| tree | ed913991563b48f45a45096fe535325be297ff35 | |
| parent | 2a960cce03d1dbd3dba54e660c479f64674eb5e3 (diff) | |
nand: omap2: Remove horrible ifdefs to fix module probe
The current code abuses ifdefs to determine if the selected ECC scheme
is supported by the running kernel. As a result the code is hard to read,
and it also fails to load as a module.
This commit removes all the ifdefs and instead introduces a function
omap2_nand_ecc_check() to check if the ECC is supported by using
IS_ENABLED(CONFIG_xxx).
Since IS_ENABLED() is true when a config is =y or =m, this change fixes the
module so it can be loaded with no issues.
Acked-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
| -rw-r--r-- | drivers/mtd/nand/omap2.c | 130 | ||||
| -rw-r--r-- | include/linux/platform_data/elm.h | 16 |
2 files changed, 87 insertions, 59 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index e1a9b310c159..f97a4ffd489d 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -136,7 +136,6 @@ | |||
| 136 | 136 | ||
| 137 | #define BADBLOCK_MARKER_LENGTH 2 | 137 | #define BADBLOCK_MARKER_LENGTH 2 |
| 138 | 138 | ||
| 139 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
| 140 | static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55, | 139 | static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55, |
| 141 | 0x2e, 0x2c, 0x86, 0xa3, 0xed, 0x36, 0x1b, 0x78, | 140 | 0x2e, 0x2c, 0x86, 0xa3, 0xed, 0x36, 0x1b, 0x78, |
| 142 | 0x48, 0x76, 0xa9, 0x3b, 0x97, 0xd1, 0x7a, 0x93, | 141 | 0x48, 0x76, 0xa9, 0x3b, 0x97, 0xd1, 0x7a, 0x93, |
| @@ -144,7 +143,6 @@ static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55, | |||
| 144 | static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, | 143 | static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, |
| 145 | 0xac, 0x6b, 0xff, 0x99, 0x7b}; | 144 | 0xac, 0x6b, 0xff, 0x99, 0x7b}; |
| 146 | static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; | 145 | static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; |
| 147 | #endif | ||
| 148 | 146 | ||
| 149 | /* oob info generated runtime depending on ecc algorithm and layout selected */ | 147 | /* oob info generated runtime depending on ecc algorithm and layout selected */ |
| 150 | static struct nand_ecclayout omap_oobinfo; | 148 | static struct nand_ecclayout omap_oobinfo; |
| @@ -1292,7 +1290,6 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, | |||
| 1292 | return 0; | 1290 | return 0; |
| 1293 | } | 1291 | } |
| 1294 | 1292 | ||
| 1295 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
| 1296 | /** | 1293 | /** |
| 1297 | * erased_sector_bitflips - count bit flips | 1294 | * erased_sector_bitflips - count bit flips |
| 1298 | * @data: data sector buffer | 1295 | * @data: data sector buffer |
| @@ -1593,33 +1590,71 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1593 | /** | 1590 | /** |
| 1594 | * is_elm_present - checks for presence of ELM module by scanning DT nodes | 1591 | * is_elm_present - checks for presence of ELM module by scanning DT nodes |
| 1595 | * @omap_nand_info: NAND device structure containing platform data | 1592 | * @omap_nand_info: NAND device structure containing platform data |
| 1596 | * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16 | ||
| 1597 | */ | 1593 | */ |
| 1598 | static int is_elm_present(struct omap_nand_info *info, | 1594 | static bool is_elm_present(struct omap_nand_info *info, |
| 1599 | struct device_node *elm_node, enum bch_ecc bch_type) | 1595 | struct device_node *elm_node) |
| 1600 | { | 1596 | { |
| 1601 | struct platform_device *pdev; | 1597 | struct platform_device *pdev; |
| 1602 | struct nand_ecc_ctrl *ecc = &info->nand.ecc; | 1598 | |
| 1603 | int err; | ||
| 1604 | /* check whether elm-id is passed via DT */ | 1599 | /* check whether elm-id is passed via DT */ |
| 1605 | if (!elm_node) { | 1600 | if (!elm_node) { |
| 1606 | pr_err("nand: error: ELM DT node not found\n"); | 1601 | pr_err("nand: error: ELM DT node not found\n"); |
| 1607 | return -ENODEV; | 1602 | return false; |
| 1608 | } | 1603 | } |
| 1609 | pdev = of_find_device_by_node(elm_node); | 1604 | pdev = of_find_device_by_node(elm_node); |
| 1610 | /* check whether ELM device is registered */ | 1605 | /* check whether ELM device is registered */ |
| 1611 | if (!pdev) { | 1606 | if (!pdev) { |
| 1612 | pr_err("nand: error: ELM device not found\n"); | 1607 | pr_err("nand: error: ELM device not found\n"); |
| 1613 | return -ENODEV; | 1608 | return false; |
| 1614 | } | 1609 | } |
| 1615 | /* ELM module available, now configure it */ | 1610 | /* ELM module available, now configure it */ |
| 1616 | info->elm_dev = &pdev->dev; | 1611 | info->elm_dev = &pdev->dev; |
| 1617 | err = elm_config(info->elm_dev, bch_type, | 1612 | return true; |
| 1618 | (info->mtd.writesize / ecc->size), ecc->size, ecc->bytes); | 1613 | } |
| 1619 | 1614 | ||
| 1620 | return err; | 1615 | static bool omap2_nand_ecc_check(struct omap_nand_info *info, |
| 1616 | struct omap_nand_platform_data *pdata) | ||
| 1617 | { | ||
| 1618 | bool ecc_needs_bch, ecc_needs_omap_bch, ecc_needs_elm; | ||
| 1619 | |||
| 1620 | switch (info->ecc_opt) { | ||
| 1621 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | ||
| 1622 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: | ||
| 1623 | ecc_needs_omap_bch = false; | ||
| 1624 | ecc_needs_bch = true; | ||
| 1625 | ecc_needs_elm = false; | ||
| 1626 | break; | ||
| 1627 | case OMAP_ECC_BCH4_CODE_HW: | ||
| 1628 | case OMAP_ECC_BCH8_CODE_HW: | ||
| 1629 | case OMAP_ECC_BCH16_CODE_HW: | ||
| 1630 | ecc_needs_omap_bch = true; | ||
| 1631 | ecc_needs_bch = false; | ||
| 1632 | ecc_needs_elm = true; | ||
| 1633 | break; | ||
| 1634 | default: | ||
| 1635 | ecc_needs_omap_bch = false; | ||
| 1636 | ecc_needs_bch = false; | ||
| 1637 | ecc_needs_elm = false; | ||
| 1638 | break; | ||
| 1639 | } | ||
| 1640 | |||
| 1641 | if (ecc_needs_bch && !IS_ENABLED(CONFIG_MTD_NAND_ECC_BCH)) { | ||
| 1642 | dev_err(&info->pdev->dev, | ||
| 1643 | "CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | ||
| 1644 | return false; | ||
| 1645 | } | ||
| 1646 | if (ecc_needs_omap_bch && !IS_ENABLED(CONFIG_MTD_NAND_OMAP_BCH)) { | ||
| 1647 | dev_err(&info->pdev->dev, | ||
| 1648 | "CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | ||
| 1649 | return false; | ||
| 1650 | } | ||
| 1651 | if (ecc_needs_elm && !is_elm_present(info, pdata->elm_of_node)) { | ||
| 1652 | dev_err(&info->pdev->dev, "ELM not available\n"); | ||
| 1653 | return false; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | return true; | ||
| 1621 | } | 1657 | } |
| 1622 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | ||
| 1623 | 1658 | ||
| 1624 | static int omap_nand_probe(struct platform_device *pdev) | 1659 | static int omap_nand_probe(struct platform_device *pdev) |
| 1625 | { | 1660 | { |
| @@ -1797,6 +1832,11 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1797 | goto return_error; | 1832 | goto return_error; |
| 1798 | } | 1833 | } |
| 1799 | 1834 | ||
| 1835 | if (!omap2_nand_ecc_check(info, pdata)) { | ||
| 1836 | err = -EINVAL; | ||
| 1837 | goto return_error; | ||
| 1838 | } | ||
| 1839 | |||
| 1800 | /* populate MTD interface based on ECC scheme */ | 1840 | /* populate MTD interface based on ECC scheme */ |
| 1801 | ecclayout = &omap_oobinfo; | 1841 | ecclayout = &omap_oobinfo; |
| 1802 | switch (info->ecc_opt) { | 1842 | switch (info->ecc_opt) { |
| @@ -1829,7 +1869,6 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1829 | break; | 1869 | break; |
| 1830 | 1870 | ||
| 1831 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | 1871 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: |
| 1832 | #ifdef CONFIG_MTD_NAND_ECC_BCH | ||
| 1833 | pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n"); | 1872 | pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n"); |
| 1834 | nand_chip->ecc.mode = NAND_ECC_HW; | 1873 | nand_chip->ecc.mode = NAND_ECC_HW; |
| 1835 | nand_chip->ecc.size = 512; | 1874 | nand_chip->ecc.size = 512; |
| @@ -1861,14 +1900,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1861 | err = -EINVAL; | 1900 | err = -EINVAL; |
| 1862 | } | 1901 | } |
| 1863 | break; | 1902 | break; |
| 1864 | #else | ||
| 1865 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | ||
| 1866 | err = -EINVAL; | ||
| 1867 | goto return_error; | ||
| 1868 | #endif | ||
| 1869 | 1903 | ||
| 1870 | case OMAP_ECC_BCH4_CODE_HW: | 1904 | case OMAP_ECC_BCH4_CODE_HW: |
| 1871 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
| 1872 | pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n"); | 1905 | pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n"); |
| 1873 | nand_chip->ecc.mode = NAND_ECC_HW; | 1906 | nand_chip->ecc.mode = NAND_ECC_HW; |
| 1874 | nand_chip->ecc.size = 512; | 1907 | nand_chip->ecc.size = 512; |
| @@ -1890,21 +1923,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1890 | /* reserved marker already included in ecclayout->eccbytes */ | 1923 | /* reserved marker already included in ecclayout->eccbytes */ |
| 1891 | ecclayout->oobfree->offset = | 1924 | ecclayout->oobfree->offset = |
| 1892 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | 1925 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; |
| 1893 | /* This ECC scheme requires ELM H/W block */ | 1926 | |
| 1894 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { | 1927 | err = elm_config(info->elm_dev, BCH4_ECC, |
| 1895 | pr_err("nand: error: could not initialize ELM\n"); | 1928 | info->mtd.writesize / nand_chip->ecc.size, |
| 1896 | err = -ENODEV; | 1929 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
| 1930 | if (err < 0) | ||
| 1897 | goto return_error; | 1931 | goto return_error; |
| 1898 | } | ||
| 1899 | break; | 1932 | break; |
| 1900 | #else | ||
| 1901 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | ||
| 1902 | err = -EINVAL; | ||
| 1903 | goto return_error; | ||
| 1904 | #endif | ||
| 1905 | 1933 | ||
| 1906 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: | 1934 | case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: |
| 1907 | #ifdef CONFIG_MTD_NAND_ECC_BCH | ||
| 1908 | pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); | 1935 | pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); |
| 1909 | nand_chip->ecc.mode = NAND_ECC_HW; | 1936 | nand_chip->ecc.mode = NAND_ECC_HW; |
| 1910 | nand_chip->ecc.size = 512; | 1937 | nand_chip->ecc.size = 512; |
| @@ -1937,14 +1964,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1937 | goto return_error; | 1964 | goto return_error; |
| 1938 | } | 1965 | } |
| 1939 | break; | 1966 | break; |
| 1940 | #else | ||
| 1941 | pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | ||
| 1942 | err = -EINVAL; | ||
| 1943 | goto return_error; | ||
| 1944 | #endif | ||
| 1945 | 1967 | ||
| 1946 | case OMAP_ECC_BCH8_CODE_HW: | 1968 | case OMAP_ECC_BCH8_CODE_HW: |
| 1947 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
| 1948 | pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n"); | 1969 | pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n"); |
| 1949 | nand_chip->ecc.mode = NAND_ECC_HW; | 1970 | nand_chip->ecc.mode = NAND_ECC_HW; |
| 1950 | nand_chip->ecc.size = 512; | 1971 | nand_chip->ecc.size = 512; |
| @@ -1956,12 +1977,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1956 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; | 1977 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
| 1957 | nand_chip->ecc.read_page = omap_read_page_bch; | 1978 | nand_chip->ecc.read_page = omap_read_page_bch; |
| 1958 | nand_chip->ecc.write_page = omap_write_page_bch; | 1979 | nand_chip->ecc.write_page = omap_write_page_bch; |
| 1959 | /* This ECC scheme requires ELM H/W block */ | 1980 | |
| 1960 | err = is_elm_present(info, pdata->elm_of_node, BCH8_ECC); | 1981 | err = elm_config(info->elm_dev, BCH8_ECC, |
| 1961 | if (err < 0) { | 1982 | info->mtd.writesize / nand_chip->ecc.size, |
| 1962 | pr_err("nand: error: could not initialize ELM\n"); | 1983 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
| 1984 | if (err < 0) | ||
| 1963 | goto return_error; | 1985 | goto return_error; |
| 1964 | } | 1986 | |
| 1965 | /* define ECC layout */ | 1987 | /* define ECC layout */ |
| 1966 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1988 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
| 1967 | (mtd->writesize / | 1989 | (mtd->writesize / |
| @@ -1973,14 +1995,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1973 | ecclayout->oobfree->offset = | 1995 | ecclayout->oobfree->offset = |
| 1974 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | 1996 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; |
| 1975 | break; | 1997 | break; |
| 1976 | #else | ||
| 1977 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | ||
| 1978 | err = -EINVAL; | ||
| 1979 | goto return_error; | ||
| 1980 | #endif | ||
| 1981 | 1998 | ||
| 1982 | case OMAP_ECC_BCH16_CODE_HW: | 1999 | case OMAP_ECC_BCH16_CODE_HW: |
| 1983 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
| 1984 | pr_info("using OMAP_ECC_BCH16_CODE_HW ECC scheme\n"); | 2000 | pr_info("using OMAP_ECC_BCH16_CODE_HW ECC scheme\n"); |
| 1985 | nand_chip->ecc.mode = NAND_ECC_HW; | 2001 | nand_chip->ecc.mode = NAND_ECC_HW; |
| 1986 | nand_chip->ecc.size = 512; | 2002 | nand_chip->ecc.size = 512; |
| @@ -1991,12 +2007,13 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1991 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; | 2007 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
| 1992 | nand_chip->ecc.read_page = omap_read_page_bch; | 2008 | nand_chip->ecc.read_page = omap_read_page_bch; |
| 1993 | nand_chip->ecc.write_page = omap_write_page_bch; | 2009 | nand_chip->ecc.write_page = omap_write_page_bch; |
| 1994 | /* This ECC scheme requires ELM H/W block */ | 2010 | |
| 1995 | err = is_elm_present(info, pdata->elm_of_node, BCH16_ECC); | 2011 | err = elm_config(info->elm_dev, BCH16_ECC, |
| 1996 | if (err < 0) { | 2012 | info->mtd.writesize / nand_chip->ecc.size, |
| 1997 | pr_err("ELM is required for this ECC scheme\n"); | 2013 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
| 2014 | if (err < 0) | ||
| 1998 | goto return_error; | 2015 | goto return_error; |
| 1999 | } | 2016 | |
| 2000 | /* define ECC layout */ | 2017 | /* define ECC layout */ |
| 2001 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 2018 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
| 2002 | (mtd->writesize / | 2019 | (mtd->writesize / |
| @@ -2008,11 +2025,6 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 2008 | ecclayout->oobfree->offset = | 2025 | ecclayout->oobfree->offset = |
| 2009 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | 2026 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; |
| 2010 | break; | 2027 | break; |
| 2011 | #else | ||
| 2012 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | ||
| 2013 | err = -EINVAL; | ||
| 2014 | goto return_error; | ||
| 2015 | #endif | ||
| 2016 | default: | 2028 | default: |
| 2017 | pr_err("nand: error: invalid or unsupported ECC scheme\n"); | 2029 | pr_err("nand: error: invalid or unsupported ECC scheme\n"); |
| 2018 | err = -EINVAL; | 2030 | err = -EINVAL; |
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h index 780d1e97f620..b8686c00f15f 100644 --- a/include/linux/platform_data/elm.h +++ b/include/linux/platform_data/elm.h | |||
| @@ -42,8 +42,24 @@ struct elm_errorvec { | |||
| 42 | int error_loc[16]; | 42 | int error_loc[16]; |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | #if IS_ENABLED(CONFIG_MTD_NAND_OMAP_BCH) | ||
| 45 | void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, | 46 | void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, |
| 46 | struct elm_errorvec *err_vec); | 47 | struct elm_errorvec *err_vec); |
| 47 | int elm_config(struct device *dev, enum bch_ecc bch_type, | 48 | int elm_config(struct device *dev, enum bch_ecc bch_type, |
| 48 | int ecc_steps, int ecc_step_size, int ecc_syndrome_size); | 49 | int ecc_steps, int ecc_step_size, int ecc_syndrome_size); |
| 50 | #else | ||
| 51 | static inline void | ||
| 52 | elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, | ||
| 53 | struct elm_errorvec *err_vec) | ||
| 54 | { | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline int elm_config(struct device *dev, enum bch_ecc bch_type, | ||
| 58 | int ecc_steps, int ecc_step_size, | ||
| 59 | int ecc_syndrome_size) | ||
| 60 | { | ||
| 61 | return -ENOSYS; | ||
| 62 | } | ||
| 63 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | ||
| 64 | |||
| 49 | #endif /* __ELM_H */ | 65 | #endif /* __ELM_H */ |
