Merge tag 'for-linus-20131112' of git://git.infradead.org/linux-mtd
[cascardo/linux.git] / arch / arm / mach-omap2 / gpmc.c
index 51525fa..81de562 100644 (file)
@@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-       [OMAP_ECC_HAMMING_CODE_DEFAULT]         = "sw",
-       [OMAP_ECC_HAMMING_CODE_HW]              = "hw",
-       [OMAP_ECC_HAMMING_CODE_HW_ROMCODE]      = "hw-romcode",
-       [OMAP_ECC_BCH4_CODE_HW]                 = "bch4",
-       [OMAP_ECC_BCH8_CODE_HW]                 = "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
        [NAND_OMAP_PREFETCH_POLLED]             = "prefetch-polled",
        [NAND_OMAP_POLLED]                      = "polled",
@@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
        gpmc_nand_data->cs = val;
        gpmc_nand_data->of_node = child;
 
-       if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-               for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-                       if (!strcasecmp(s, nand_ecc_opts[val])) {
-                               gpmc_nand_data->ecc_opt = val;
-                               break;
-                       }
+       /* Detect availability of ELM module */
+       gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+       if (gpmc_nand_data->elm_of_node == NULL)
+               gpmc_nand_data->elm_of_node =
+                                       of_parse_phandle(child, "elm_id", 0);
+       if (gpmc_nand_data->elm_of_node == NULL)
+               pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+       /* select ecc-scheme for NAND */
+       if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+               pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+               return -ENODEV;
+       }
+       if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
+               !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
+               gpmc_nand_data->ecc_opt =
+                               OMAP_ECC_HAM1_CODE_HW;
+       else if (!strcmp(s, "bch4"))
+               if (gpmc_nand_data->elm_of_node)
+                       gpmc_nand_data->ecc_opt =
+                               OMAP_ECC_BCH4_CODE_HW;
+               else
+                       gpmc_nand_data->ecc_opt =
+                               OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+       else if (!strcmp(s, "bch8"))
+               if (gpmc_nand_data->elm_of_node)
+                       gpmc_nand_data->ecc_opt =
+                               OMAP_ECC_BCH8_CODE_HW;
+               else
+                       gpmc_nand_data->ecc_opt =
+                               OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+       else
+               pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
+       /* select data transfer mode for NAND controller */
        if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
                for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
                        if (!strcasecmp(s, nand_xfer_types[val])) {