.oobfree = { {.offset = 0, .length = 0} }
};
+static const struct gpmi_devdata gpmi_devdata_imx23 = {
+ .type = IS_MX23,
+ .bch_max_ecc_strength = 20,
+ .max_chain_delay = 16,
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx28 = {
+ .type = IS_MX28,
+ .bch_max_ecc_strength = 20,
+ .max_chain_delay = 16,
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx6q = {
+ .type = IS_MX6Q,
+ .bch_max_ecc_strength = 40,
+ .max_chain_delay = 12,
+};
+
static irqreturn_t bch_irq(int irq, void *cookie)
{
struct gpmi_nand_data *this = cookie;
/* The mx23/mx28 only support the GF13. */
if (geo->gf_len == 14)
return false;
-
- if (geo->ecc_strength > MXS_ECC_STRENGTH_MAX)
- return false;
- } else if (GPMI_IS_MX6Q(this)) {
- if (geo->ecc_strength > MX6_ECC_STRENGTH_MAX)
- return false;
}
- return true;
+ return geo->ecc_strength <= this->devdata->bch_max_ecc_strength;
}
/*
"We can not support this nand chip."
" Its required ecc strength(%d) is beyond our"
" capability(%d).\n", geo->ecc_strength,
- (GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX
- : MXS_ECC_STRENGTH_MAX));
+ this->devdata->bch_max_ecc_strength);
return -EINVAL;
}
return ret;
}
-static const struct platform_device_id gpmi_ids[] = {
- { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, },
- { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, },
- { .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, },
- {}
-};
-
static const struct of_device_id gpmi_nand_id_table[] = {
{
.compatible = "fsl,imx23-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX23],
+ .data = (void *)&gpmi_devdata_imx23,
}, {
.compatible = "fsl,imx28-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX28],
+ .data = (void *)&gpmi_devdata_imx28,
}, {
.compatible = "fsl,imx6q-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX6Q],
+ .data = (void *)&gpmi_devdata_imx6q,
}, {}
};
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
const struct of_device_id *of_id;
int ret;
+ this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
+ if (!this)
+ return -ENOMEM;
+
of_id = of_match_device(gpmi_nand_id_table, &pdev->dev);
if (of_id) {
- pdev->id_entry = of_id->data;
+ this->devdata = of_id->data;
} else {
dev_err(&pdev->dev, "Failed to find the right device id.\n");
return -ENODEV;
}
- this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
- if (!this)
- return -ENOMEM;
-
platform_set_drvdata(pdev, this);
this->pdev = pdev;
this->dev = &pdev->dev;
},
.probe = gpmi_nand_probe,
.remove = gpmi_nand_remove,
- .id_table = gpmi_ids,
};
module_platform_driver(gpmi_nand_driver);
int8_t tRHOH_in_ns;
};
+enum gpmi_type {
+ IS_MX23,
+ IS_MX28,
+ IS_MX6Q
+};
+
+struct gpmi_devdata {
+ enum gpmi_type type;
+ int bch_max_ecc_strength;
+ int max_chain_delay; /* See the async EDO mode */
+};
+
struct gpmi_nand_data {
/* flags */
#define GPMI_ASYNC_EDO_ENABLED (1 << 0)
#define GPMI_TIMING_INIT_OK (1 << 1)
int flags;
+ const struct gpmi_devdata *devdata;
/* System Interface */
struct device *dev;
#define STATUS_ERASED 0xff
#define STATUS_UNCORRECTABLE 0xfe
-/* BCH's bit correction capability. */
-#define MXS_ECC_STRENGTH_MAX 20 /* mx23 and mx28 */
-#define MX6_ECC_STRENGTH_MAX 40
-
-/* Use the platform_id to distinguish different Archs. */
-#define IS_MX23 0x0
-#define IS_MX28 0x1
-#define IS_MX6Q 0x2
-#define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23)
-#define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28)
-#define GPMI_IS_MX6Q(x) ((x)->pdev->id_entry->driver_data == IS_MX6Q)
+/* Use the devdata to distinguish different Archs. */
+#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23)
+#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
+#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
#endif