aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEzequiel GarcĂ­a <ezequiel@vanguardiasur.com.ar>2014-09-20 12:53:12 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-09-22 14:37:51 -0400
commit93af53b8633c4cb474585158512182b21219d743 (patch)
treeed913991563b48f45a45096fe535325be297ff35
parent2a960cce03d1dbd3dba54e660c479f64674eb5e3 (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.c130
-rw-r--r--include/linux/platform_data/elm.h16
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
140static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55, 139static 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,
144static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, 143static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
145 0xac, 0x6b, 0xff, 0x99, 0x7b}; 144 0xac, 0x6b, 0xff, 0x99, 0x7b};
146static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; 145static 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 */
150static struct nand_ecclayout omap_oobinfo; 148static 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 */
1598static int is_elm_present(struct omap_nand_info *info, 1594static 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; 1615static 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
1624static int omap_nand_probe(struct platform_device *pdev) 1659static 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)
45void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, 46void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
46 struct elm_errorvec *err_vec); 47 struct elm_errorvec *err_vec);
47int elm_config(struct device *dev, enum bch_ecc bch_type, 48int 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
51static inline void
52elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
53 struct elm_errorvec *err_vec)
54{
55}
56
57static 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 */