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>
master
Masahiro Yamada 7 years ago
parent 7b8b47bd29
commit 1d9654dc43
  1. 7
      drivers/mtd/nand/Kconfig
  2. 1
      drivers/mtd/nand/Makefile
  3. 4
      drivers/mtd/nand/denali.c
  4. 2
      drivers/mtd/nand/denali.h
  5. 68
      drivers/mtd/nand/denali_dt.c

@ -16,6 +16,13 @@ config NAND_DENALI
help
Enable support for the Denali NAND controller.
config NAND_DENALI_DT
bool "Support Denali NAND controller as a DT device"
depends on NAND_DENALI && OF_CONTROL && DM
help
Enable the driver for NAND flash on platforms using a Denali NAND
controller as a DT device.
config SYS_NAND_DENALI_64BIT
bool "Use 64-bit variant of Denali NAND controller"
depends on NAND_DENALI

@ -44,6 +44,7 @@ obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o
obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_NAND_DENALI) += denali.o
obj-$(CONFIG_NAND_DENALI_DT) += denali_dt.o
obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o

@ -1175,7 +1175,7 @@ static void denali_hw_init(struct denali_nand_info *denali)
static struct nand_ecclayout nand_oob;
static int denali_init(struct denali_nand_info *denali)
int denali_init(struct denali_nand_info *denali)
{
struct mtd_info *mtd = nand_to_mtd(&denali->nand);
int ret;
@ -1273,6 +1273,7 @@ fail:
return ret;
}
#ifndef CONFIG_NAND_DENALI_DT
static int __board_nand_init(void)
{
struct denali_nand_info *denali;
@ -1296,3 +1297,4 @@ void board_nand_init(void)
if (__board_nand_init() < 0)
pr_warn("Failed to initialize Denali NAND controller.\n");
}
#endif

@ -464,4 +464,6 @@ struct denali_nand_info {
uint32_t max_banks;
};
int denali_init(struct denali_nand_info *denali);
#endif /* __DENALI_H__ */

@ -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);
}
Loading…
Cancel
Save