
From: Shmuel Hazan shmuel.h@siklu.com
Signed-off-by: Shmuel Hazan shmuel.h@siklu.com Signed-off-by: Baruch Siach baruch@tkos.co.il --- drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/pxa3xx_nand.c | 114 +++++++++++++---------------- 2 files changed, 54 insertions(+), 62 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 06b2ff972cad..bcfaa09ac720 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -195,6 +195,8 @@ endif config NAND_PXA3XX bool "Support for NAND on PXA3xx and Armada 370/XP/38x" select SYS_NAND_SELF_INIT + select DM_MTD + select SYSCON imply CMD_NAND help This enables the driver for the NAND flash device found on diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c index a30e82166b96..d455201b91a3 100644 --- a/drivers/mtd/nand/raw/pxa3xx_nand.c +++ b/drivers/mtd/nand/raw/pxa3xx_nand.c @@ -22,6 +22,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/types.h> +#include <dm/uclass.h> +#include <dm/read.h>
#include "pxa3xx_nand.h"
@@ -417,6 +419,14 @@ static struct nand_ecclayout ecc_layout_8KB_bch8bit = { /* convert nano-seconds to nand flash controller clock cycles */ #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000)
+static const struct udevice_id pxa3xx_nand_dt_ids[] = { + { + .compatible = "marvell,mvebu-pxa3xx-nand", + .data = PXA3XX_NAND_VARIANT_ARMADA370, + }, + {} +}; + static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(void) { /* We only support the Armada 370/XP/38x for now */ @@ -1810,79 +1820,58 @@ fail_disable_clk: return ret; }
-static int pxa3xx_nand_probe_dt(struct pxa3xx_nand_info *info) +static int pxa3xx_nand_probe_dt(struct udevice *dev, struct pxa3xx_nand_info *info) { struct pxa3xx_nand_platform_data *pdata; - const void *blob = gd->fdt_blob; - int node = -1;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM;
- /* Get address decoding nodes from the FDT blob */ - do { - node = fdt_node_offset_by_compatible(blob, node, - "marvell,mvebu-pxa3xx-nand"); - if (node < 0) - break; - - /* Bypass disabeld nodes */ - if (!fdtdec_get_is_enabled(blob, node)) - continue; - - /* Get the first enabled NAND controler base address */ - info->mmio_base = - (void __iomem *)fdtdec_get_addr_size_auto_noparent( - blob, node, "reg", 0, NULL, true); + info->mmio_base = dev_read_addr_ptr(dev);
- pdata->num_cs = fdtdec_get_int(blob, node, "num-cs", 1); - if (pdata->num_cs != 1) { - pr_err("pxa3xx driver supports single CS only\n"); - break; - } - - if (fdtdec_get_bool(blob, node, "nand-enable-arbiter")) - pdata->enable_arbiter = 1; + pdata->num_cs = dev_read_u32_default(dev, "num-cs", 1); + if (pdata->num_cs != 1) { + pr_err("pxa3xx driver supports single CS only\n"); + return -EINVAL; + }
- if (fdtdec_get_bool(blob, node, "nand-keep-config")) - pdata->keep_config = 1; + if (dev_read_bool(dev, "nand-enable-arbiter")) + pdata->enable_arbiter = 1;
- /* - * ECC parameters. - * If these are not set, they will be selected according - * to the detected flash type. - */ - /* ECC strength */ - pdata->ecc_strength = fdtdec_get_int(blob, node, - "nand-ecc-strength", 0); + if (dev_read_bool(dev, "nand-keep-config")) + pdata->keep_config = 1;
- /* ECC step size */ - pdata->ecc_step_size = fdtdec_get_int(blob, node, - "nand-ecc-step-size", 0); - - info->pdata = pdata; + /* + * ECC parameters. + * If these are not set, they will be selected according + * to the detected flash type. + */ + /* ECC strength */ + pdata->ecc_strength = dev_read_u32_default(dev, "nand-ecc-strength", 0);
- /* Currently support only a single NAND controller */ - return 0; + /* ECC step size */ + pdata->ecc_step_size = dev_read_u32_default(dev, "nand-ecc-step-size", + 0);
- } while (node >= 0); + info->pdata = pdata;
- return -EINVAL; + return 0; }
-static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info) +static int pxa3xx_nand_probe(struct udevice *dev) { struct pxa3xx_nand_platform_data *pdata; int ret, cs, probe_success; + struct pxa3xx_nand_info *info = dev_get_priv(dev);
- ret = pxa3xx_nand_probe_dt(info); + ret = pxa3xx_nand_probe_dt(dev, info); if (ret) return ret;
pdata = info->pdata;
- ret = alloc_nand_resource(info); + ret = alloc_nand_resource(dev, info); if (ret) { dev_err(&pdev->dev, "alloc nand resource failed\n"); return ret; @@ -1918,22 +1907,23 @@ static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info) return 0; }
-/* - * Main initialization routine - */ +U_BOOT_DRIVER(pxa3xx_nand) = { + .name = "pxa3xx-nand", + .id = UCLASS_MTD, + .of_match = pxa3xx_nand_dt_ids, + .probe = pxa3xx_nand_probe, + .priv_auto_alloc_size = sizeof(struct pxa3xx_nand_info) + + sizeof(struct pxa3xx_nand_host) * CONFIG_SYS_MAX_NAND_DEVICE, +}; + void board_nand_init(void) { - struct pxa3xx_nand_info *info; - struct pxa3xx_nand_host *host; + struct udevice *dev; int ret;
- info = kzalloc(sizeof(*info) + - sizeof(*host) * CONFIG_SYS_MAX_NAND_DEVICE, - GFP_KERNEL); - if (!info) - return; - - ret = pxa3xx_nand_probe(info); - if (ret) - return; + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_GET_DRIVER(pxa3xx_nand), &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize %s. (error %d)\n", dev->name, + ret); }