Some chip characteristics have known incompatibilities with the function
of this driver. Here we check for this characteristics and refuse to run
if they are present.

Signed-off-by: Lee Jones <lee.jo...@linaro.org>
---
 drivers/mtd/nand/stm_nand_bch.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/stm_nand_bch.c b/drivers/mtd/nand/stm_nand_bch.c
index 31864e5..66ff99d 100644
--- a/drivers/mtd/nand/stm_nand_bch.c
+++ b/drivers/mtd/nand/stm_nand_bch.c
@@ -309,6 +309,36 @@ static void nandi_disable_interrupts(struct 
nandi_controller *nandi,
        writel(val, nandi->base + NANDBCH_INT_EN);
 }
 
+/*
+ * Initialisation
+ */
+static int bch_check_compatibility(struct nandi_controller *nandi,
+                                  struct mtd_info *mtd,
+                                  struct nand_chip *chip)
+{
+       if (chip->bits_per_cell > 1)
+               dev_warn(nandi->dev, "MLC NAND not fully supported\n");
+
+       if (chip->options & NAND_BUSWIDTH_16) {
+               dev_err(nandi->dev, "x16 NAND not supported\n");
+               return false;
+       }
+
+       if (nandi->blocks_per_device / 4 > mtd->writesize) {
+               /* Need to implement multi-page BBT support... */
+               dev_err(nandi->dev, "BBT too big to fit in single page\n");
+               return false;
+       }
+
+       if (bch_ecc_sizes[nandi->bch_ecc_mode] * nandi->sectors_per_page >
+           mtd->oobsize) {
+               dev_err(nandi->dev, "insufficient OOB for selected ECC\n");
+               return false;
+       }
+
+       return true;
+}
+
 /* Select strongest ECC scheme compatible with OOB size */
 static int bch_set_ecc_auto(struct nandi_controller *nandi,
                            struct mtd_info *mtd)
@@ -886,7 +916,7 @@ static int stm_nand_bch_probe(struct platform_device *pdev)
        struct nandi_info *info;
        struct nand_chip *chip;
        struct mtd_info *mtd;
-       int err;
+       int compatible, err;
 
        if (!np) {
                dev_err(&pdev->dev, "DT node found\n");
@@ -982,6 +1012,13 @@ static int stm_nand_bch_probe(struct platform_device 
*pdev)
        info->ecclayout.eccbytes =
                nandi->sectors_per_page * bch_ecc_sizes[nandi->bch_ecc_mode];
 
+       compatible = bch_check_compatibility(nandi, mtd, chip);
+       if (!compatible) {
+               dev_err(nandi->dev,
+                       "NAND device incompatible with NANDi/BCH Controller\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to