[PATCH] mtd: nand_imx: Add devicetree probe support
Sascha Hauer
s.hauer at pengutronix.de
Mon Jul 15 15:56:31 EDT 2013
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
drivers/mtd/nand/nand_imx.c | 75 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 67 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index 75aefd6..426ee2e 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -27,6 +27,7 @@
#include <mach/generic.h>
#include <mach/imx-nand.h>
#include <io.h>
+#include <of_mtd.h>
#include <errno.h>
#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
@@ -100,6 +101,10 @@ struct imx_nand_host {
int spare_len;
int eccsize;
+ int hw_ecc;
+ int data_width;
+ int flash_bbt;
+
void (*preset)(struct mtd_info *);
void (*send_cmd)(struct imx_nand_host *, uint16_t);
void (*send_addr)(struct imx_nand_host *, uint16_t);
@@ -1087,6 +1092,28 @@ static struct nand_bbt_descr bbt_mirror_descr = {
.pattern = mirror_pattern,
};
+static int __init mxcnd_probe_dt(struct imx_nand_host *host)
+{
+ struct device_node *np = host->dev->device_node;
+ int buswidth;
+
+ if (!np)
+ return 1;
+
+ if (of_get_nand_ecc_mode(np) == NAND_ECC_HW)
+ host->hw_ecc = 1;
+
+ host->flash_bbt = of_get_nand_on_flash_bbt(np);
+
+ buswidth = of_get_nand_bus_width(np);
+ if (buswidth < 0)
+ return buswidth;
+
+ host->data_width = buswidth / 8;
+
+ return 0;
+}
+
/*
* This function is called during the driver binding process.
*
@@ -1101,7 +1128,6 @@ static int __init imxnd_probe(struct device_d *dev)
{
struct nand_chip *this;
struct mtd_info *mtd;
- struct imx_nand_platform_data *pdata = dev->platform_data;
struct imx_nand_host *host;
struct nand_ecclayout *oob_smallpage, *oob_largepage, *oob_4kpage;
int err = 0;
@@ -1112,6 +1138,23 @@ static int __init imxnd_probe(struct device_d *dev)
if (!host)
return -ENOMEM;
+ host->dev = dev;
+
+ if (IS_ENABLED(CONFIG_OFDEVICE)) {
+ err = mxcnd_probe_dt(host);
+ if (err < 0)
+ goto escan;
+
+ if (err > 0) {
+ struct imx_nand_platform_data *pdata;
+
+ pdata = dev->platform_data;
+ host->flash_bbt = pdata->flash_bbt;
+ host->data_width = pdata->width;
+ host->hw_ecc = pdata->hw_ecc;
+ }
+ }
+
host->data_buf = (uint8_t *)(host + 1);
if (nfc_is_v1() || nfc_is_v21()) {
@@ -1173,7 +1216,6 @@ static int __init imxnd_probe(struct device_d *dev)
goto escan;
}
- host->dev = dev;
/* structures must be linked */
this = &host->nand;
mtd = &host->mtd;
@@ -1194,7 +1236,7 @@ static int __init imxnd_probe(struct device_d *dev)
this->read_buf = imx_nand_read_buf;
this->verify_buf = imx_nand_verify_buf;
- if (pdata->hw_ecc) {
+ if (host->hw_ecc) {
this->ecc.calculate = imx_nand_calculate_ecc;
this->ecc.hwctl = imx_nand_enable_hwecc;
if (nfc_is_v1())
@@ -1211,13 +1253,13 @@ static int __init imxnd_probe(struct device_d *dev)
this->ecc.layout = oob_smallpage;
/* NAND bus width determines access functions used by upper layer */
- if (pdata->width == 2) {
+ if (host->data_width == 2) {
this->options |= NAND_BUSWIDTH_16;
this->ecc.layout = &nandv1_hw_eccoob_smallpage;
imx_nand_set_layout(0, 16);
}
- if (pdata->flash_bbt) {
+ if (host->flash_bbt) {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
/* update flash based bbt */
@@ -1233,10 +1275,10 @@ static int __init imxnd_probe(struct device_d *dev)
/* Call preset again, with correct writesize this time */
host->preset(mtd);
- imx_nand_set_layout(mtd->writesize, pdata->width == 2 ? 16 : 8);
+ imx_nand_set_layout(mtd->writesize, host->data_width == 2 ? 16 : 8);
if (mtd->writesize >= 2048) {
- if (!pdata->flash_bbt)
+ if (!host->flash_bbt)
dev_warn(dev, "2k or 4k flash detected without flash_bbt. "
"You will loose factory bad block markers!\n");
@@ -1261,7 +1303,7 @@ static int __init imxnd_probe(struct device_d *dev)
goto escan;
}
- if (pdata->flash_bbt && this->bbt_td->pages[0] == -1 && this->bbt_md->pages[0] == -1) {
+ if (host->flash_bbt && this->bbt_td->pages[0] == -1 && this->bbt_md->pages[0] == -1) {
dev_warn(dev, "no BBT found. create one using the imx_nand_bbm command\n");
} else {
bbt_main_descr.options |= NAND_BBT_WRITE | NAND_BBT_CREATE;
@@ -1281,9 +1323,26 @@ escan:
}
+static __maybe_unused struct of_device_id imx_nand_compatible[] = {
+ {
+ .compatible = "fsl,imx21-nand",
+ }, {
+ .compatible = "fsl,imx25-nand",
+ }, {
+ .compatible = "fsl,imx27-nand",
+ }, {
+ .compatible = "fsl,imx51-nand",
+ }, {
+ .compatible = "fsl,imx53-nand",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_nand_driver = {
.name = "imx_nand",
.probe = imxnd_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_nand_compatible),
};
device_platform_driver(imx_nand_driver);
--
1.8.3.2
More information about the barebox
mailing list