mtd: nand: denali_dt: add a DT driver

A patch for NAND uclass support was proposed about half a year ago:
https://patchwork.ozlabs.org/patch/722282/

It was not merged and I do not see on-going work for this.

Without DM-based probing, we need to set up pinctrl etc. in an ad-hoc
way and give lots of crappy CONFIG options for base addresses and
properties, which are supposed to be specified by DT.  This is painful.

This commit just provides a probe hook to retrieve "reg" from DT and
allocate private data in a DM manner.  This DT driver is not essentially
a NAND driver, in fact it is (ab)using UCLASS_MISC.  Once UCLASS_NAND is
supported, it would be possible to migrate to it.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c
new file mode 100644
index 0000000..0a6155c
--- /dev/null
+++ b/drivers/mtd/nand/denali_dt.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include "denali.h"
+
+static const struct udevice_id denali_nand_dt_ids[] = {
+	{
+		.compatible = "altr,socfpga-denali-nand",
+	},
+	{
+		.compatible = "socionext,uniphier-denali-nand-v5a",
+	},
+	{
+		.compatible = "socionext,uniphier-denali-nand-v5b",
+	},
+	{ /* sentinel */ }
+};
+
+static int denali_dt_probe(struct udevice *dev)
+{
+	struct denali_nand_info *denali = dev_get_priv(dev);
+	struct resource res;
+	int ret;
+
+	ret = dev_read_resource_byname(dev, "denali_reg", &res);
+	if (ret)
+		return ret;
+
+	denali->flash_reg = devm_ioremap(dev, res.start, resource_size(&res));
+
+	ret = dev_read_resource_byname(dev, "nand_data", &res);
+	if (ret)
+		return ret;
+
+	denali->flash_mem = devm_ioremap(dev, res.start, resource_size(&res));
+
+	return denali_init(denali);
+}
+
+U_BOOT_DRIVER(denali_nand_dt) = {
+	.name = "denali-nand-dt",
+	.id = UCLASS_MISC,
+	.of_match = denali_nand_dt_ids,
+	.probe = denali_dt_probe,
+	.priv_auto_alloc_size = sizeof(struct denali_nand_info),
+};
+
+void board_nand_init(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(denali_nand_dt),
+					  &dev);
+	if (ret && ret != -ENODEV)
+		printf("Failed to initialize Denali NAND controller. (error %d)\n",
+		       ret);
+}