diff mbox

[U-Boot,v2,10/15] drivers: nand: implement a NAND uclass

Message ID 20170131213717.30745-11-grygorii.strashko@ti.com
State Changes Requested
Delegated to: Simon Glass
Headers show

Commit Message

Grygorii Strashko Jan. 31, 2017, 9:37 p.m. UTC
From: Mugunthan V N <mugunthanvnm@ti.com>

Implement a NAND uclass so that the NAND devices can be
accessed via the DM framework.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/mtd/nand/Kconfig       | 10 ++++++++++
 drivers/mtd/nand/Makefile      |  2 ++
 drivers/mtd/nand/nand-uclass.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/nand.c        | 17 +++++++++++++++--
 include/dm/uclass-id.h         |  1 +
 5 files changed, 66 insertions(+), 2 deletions(-)
 create mode 100644 drivers/mtd/nand/nand-uclass.c

Comments

Simon Glass Feb. 6, 2017, 3:34 p.m. UTC | #1
Hi,

On 31 January 2017 at 13:37, Grygorii Strashko <grygorii.strashko@ti.com> wrote:
> From: Mugunthan V N <mugunthanvnm@ti.com>
>
> Implement a NAND uclass so that the NAND devices can be
> accessed via the DM framework.
>
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> ---
>  drivers/mtd/nand/Kconfig       | 10 ++++++++++
>  drivers/mtd/nand/Makefile      |  2 ++
>  drivers/mtd/nand/nand-uclass.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/mtd/nand/nand.c        | 17 +++++++++++++++--
>  include/dm/uclass-id.h         |  1 +
>  5 files changed, 66 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/mtd/nand/nand-uclass.c
>
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 65bb040..a96b646 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -1,5 +1,15 @@
>  menu "NAND Device Support"
>
> +config DM_NAND
> +       bool "Enable driver model for NAND"
> +       depends on DM
> +       help
> +         Enable driver model for NAND. The NAND interface is then
> +         implemented by the NAND uclass. Multiple NAND devices can
> +         be attached and used. The 'nand' command works as normal.
> +
> +         If the NAND drivers doesn't support DM, say N.
> +
>  config SYS_NAND_SELF_INIT
>         bool
>         help
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index fd4bb66..83a986a 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -38,6 +38,8 @@ endif # not spl
>
>  ifdef NORMAL_DRIVERS
>
> +obj-$(CONFIG_DM_NAND) += nand-uclass.o
> +
>  obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
>
>  obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
> diff --git a/drivers/mtd/nand/nand-uclass.c b/drivers/mtd/nand/nand-uclass.c
> new file mode 100644
> index 0000000..403c363
> --- /dev/null
> +++ b/drivers/mtd/nand/nand-uclass.c
> @@ -0,0 +1,38 @@
> +/*
> + * NAND uclass driver for NAND bus.
> + *
> + * (C) Copyright 2017
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <nand.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct mtd_info *get_nand_dev_by_index(int idx)
> +{
> +       struct nand_chip *chip;
> +       struct udevice *dev;
> +       int ret;
> +
> +       ret = uclass_get_device(UCLASS_NAND, idx, &dev);
> +       if (ret) {
> +               debug("NAND device (%d) not found\n", idx);
> +               return NULL;
> +       }
> +
> +       chip = (struct nand_chip *)dev_get_priv(dev);
> +
> +       return nand_to_mtd(chip);

Can you add some comments to the nand.h header file (perhaps within
#ifdef CONFIG_DM_NAND) to explain that drivers must have struct
nand_chip as the first part of their private data? Assuming I have
this right...

> +}
> +
> +UCLASS_DRIVER(nand) = {
> +       .id                             = UCLASS_NAND,
> +       .name                           = "nand",
> +       .flags                          = DM_UC_FLAG_SEQ_ALIAS,
> +};

Also can we have a sandbox NAND driver and some tests.

> diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
> index 18c346a..408b7ef 100644
> --- a/drivers/mtd/nand/nand.c
> +++ b/drivers/mtd/nand/nand.c
> @@ -21,7 +21,7 @@ int nand_curr_device = -1;
>
>  struct mtd_info *nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
>
> -#ifndef CONFIG_SYS_NAND_SELF_INIT
> +#if !defined(CONFIG_SYS_NAND_SELF_INIT) && !defined(CONFIG_DM_NAND)
>  static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
>  static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
>  #endif
> @@ -30,6 +30,7 @@ static char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
>
>  static unsigned long total_nand_size; /* in kiB */
>
> +#ifndef CONFIG_DM_NAND
>  struct mtd_info *get_nand_dev_by_index(int dev)
>  {
>         if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
> @@ -40,6 +41,7 @@ struct mtd_info *get_nand_dev_by_index(int dev)
>
>         return nand_info[dev];
>  }
> +#endif
>
>  int nand_mtd_to_devnum(struct mtd_info *mtd)
>  {
> @@ -59,8 +61,9 @@ int nand_register(int devnum, struct mtd_info *mtd)
>         if (devnum >= CONFIG_SYS_MAX_NAND_DEVICE)
>                 return -EINVAL;
>
> +#if !defined(CONFIG_SYS_NAND_SELF_INIT) && !defined(CONFIG_DM_NAND)
>         nand_info[devnum] = mtd;
> -
> +#endif
>         sprintf(dev_name[devnum], "nand%d", devnum);
>         mtd->name = dev_name[devnum];
>
> @@ -83,18 +86,28 @@ int nand_register(int devnum, struct mtd_info *mtd)
>  #ifndef CONFIG_SYS_NAND_SELF_INIT
>  static void nand_init_chip(int i)
>  {
> +#ifndef CONFIG_DM_NAND
>         struct nand_chip *nand = &nand_chip[i];
>         struct mtd_info *mtd = nand_to_mtd(nand);
>         ulong base_addr = base_address[i];
> +#else
> +       struct mtd_info *mtd;
> +#endif
>         int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
>
>         if (maxchips < 1)
>                 maxchips = 1;
>
> +#ifdef CONFIG_DM_NAND
> +       mtd = get_nand_dev_by_index(i);
> +       if (!mtd)
> +               return;
> +#else
>         nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
>
>         if (board_nand_init(nand))
>                 return;
> +#endif
>
>         if (nand_scan(mtd, maxchips))
>                 return;
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 8c92d0b..6556dc8 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -49,6 +49,7 @@ enum uclass_id {
>         UCLASS_MMC,             /* SD / MMC card or chip */
>         UCLASS_MOD_EXP,         /* RSA Mod Exp device */
>         UCLASS_MTD,             /* Memory Technology Device (MTD) device */
> +       UCLASS_NAND,            /* NAND device */
>         UCLASS_NORTHBRIDGE,     /* Intel Northbridge / SDRAM controller */
>         UCLASS_PANEL,           /* Display panel, such as an LCD */
>         UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
> --
> 2.10.1.dirty
>

Regards,
Simon
diff mbox

Patch

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 65bb040..a96b646 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,15 @@ 
 menu "NAND Device Support"
 
+config DM_NAND
+	bool "Enable driver model for NAND"
+	depends on DM
+	help
+	  Enable driver model for NAND. The NAND interface is then
+	  implemented by the NAND uclass. Multiple NAND devices can
+	  be attached and used. The 'nand' command works as normal.
+
+	  If the NAND drivers doesn't support DM, say N.
+
 config SYS_NAND_SELF_INIT
 	bool
 	help
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index fd4bb66..83a986a 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -38,6 +38,8 @@  endif # not spl
 
 ifdef NORMAL_DRIVERS
 
+obj-$(CONFIG_DM_NAND) += nand-uclass.o
+
 obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
 
 obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
diff --git a/drivers/mtd/nand/nand-uclass.c b/drivers/mtd/nand/nand-uclass.c
new file mode 100644
index 0000000..403c363
--- /dev/null
+++ b/drivers/mtd/nand/nand-uclass.c
@@ -0,0 +1,38 @@ 
+/*
+ * NAND uclass driver for NAND bus.
+ *
+ * (C) Copyright 2017
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <nand.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mtd_info *get_nand_dev_by_index(int idx)
+{
+	struct nand_chip *chip;
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_NAND, idx, &dev);
+	if (ret) {
+		debug("NAND device (%d) not found\n", idx);
+		return NULL;
+	}
+
+	chip = (struct nand_chip *)dev_get_priv(dev);
+
+	return nand_to_mtd(chip);
+}
+
+UCLASS_DRIVER(nand) = {
+	.id				= UCLASS_NAND,
+	.name				= "nand",
+	.flags				= DM_UC_FLAG_SEQ_ALIAS,
+};
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index 18c346a..408b7ef 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -21,7 +21,7 @@  int nand_curr_device = -1;
 
 struct mtd_info *nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
 
-#ifndef CONFIG_SYS_NAND_SELF_INIT
+#if !defined(CONFIG_SYS_NAND_SELF_INIT) && !defined(CONFIG_DM_NAND)
 static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
 #endif
@@ -30,6 +30,7 @@  static char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
 
 static unsigned long total_nand_size; /* in kiB */
 
+#ifndef CONFIG_DM_NAND
 struct mtd_info *get_nand_dev_by_index(int dev)
 {
 	if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
@@ -40,6 +41,7 @@  struct mtd_info *get_nand_dev_by_index(int dev)
 
 	return nand_info[dev];
 }
+#endif
 
 int nand_mtd_to_devnum(struct mtd_info *mtd)
 {
@@ -59,8 +61,9 @@  int nand_register(int devnum, struct mtd_info *mtd)
 	if (devnum >= CONFIG_SYS_MAX_NAND_DEVICE)
 		return -EINVAL;
 
+#if !defined(CONFIG_SYS_NAND_SELF_INIT) && !defined(CONFIG_DM_NAND)
 	nand_info[devnum] = mtd;
-
+#endif
 	sprintf(dev_name[devnum], "nand%d", devnum);
 	mtd->name = dev_name[devnum];
 
@@ -83,18 +86,28 @@  int nand_register(int devnum, struct mtd_info *mtd)
 #ifndef CONFIG_SYS_NAND_SELF_INIT
 static void nand_init_chip(int i)
 {
+#ifndef CONFIG_DM_NAND
 	struct nand_chip *nand = &nand_chip[i];
 	struct mtd_info *mtd = nand_to_mtd(nand);
 	ulong base_addr = base_address[i];
+#else
+	struct mtd_info *mtd;
+#endif
 	int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
 
 	if (maxchips < 1)
 		maxchips = 1;
 
+#ifdef CONFIG_DM_NAND
+	mtd = get_nand_dev_by_index(i);
+	if (!mtd)
+		return;
+#else
 	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
 
 	if (board_nand_init(nand))
 		return;
+#endif
 
 	if (nand_scan(mtd, maxchips))
 		return;
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 8c92d0b..6556dc8 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -49,6 +49,7 @@  enum uclass_id {
 	UCLASS_MMC,		/* SD / MMC card or chip */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
 	UCLASS_MTD,		/* Memory Technology Device (MTD) device */
+	UCLASS_NAND,		/* NAND device */
 	UCLASS_NORTHBRIDGE,	/* Intel Northbridge / SDRAM controller */
 	UCLASS_PANEL,		/* Display panel, such as an LCD */
 	UCLASS_PANEL_BACKLIGHT,	/* Backlight controller for panel */