[PATCH v3 01/10] mtd: nand: add common DT init code

Brian Norris computersforpeace at gmail.com
Mon May 11 16:25:56 PDT 2015


On Wed, May 06, 2015 at 10:59:45AM -0700, Brian Norris wrote:
> These are already-documented common bindings for NAND chips. Let's
> handle them in nand_base.
> 
> If NAND controller drivers need to act on this data before bringing up
> the NAND chip (e.g., fill out ECC callback functions, change HW modes,
> etc.), then they can do so between calling nand_scan_ident() and
> nand_scan_tail().
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>

Pushed just this patch to l2-mtd.git, since it's relatively
uncontroversial and hasn't changed across the first three revisions. It
should be of benefit to a few other driver writers out there that I've
reviewed.

Brian

> ---
>  drivers/mtd/nand/nand_base.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/nand.h     |  5 +++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index c2e1232cd45c..c6cf775ee431 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -48,6 +48,7 @@
>  #include <linux/leds.h>
>  #include <linux/io.h>
>  #include <linux/mtd/partitions.h>
> +#include <linux/of_mtd.h>
>  
>  /* Define default oob placement schemes for large and small page devices */
>  static struct nand_ecclayout nand_oob_8 = {
> @@ -3798,6 +3799,39 @@ ident_done:
>  	return type;
>  }
>  
> +static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip,
> +			struct device_node *dn)
> +{
> +	int ecc_mode, ecc_strength, ecc_step;
> +
> +	if (of_get_nand_bus_width(dn) == 16)
> +		chip->options |= NAND_BUSWIDTH_16;
> +
> +	if (of_get_nand_on_flash_bbt(dn))
> +		chip->bbt_options |= NAND_BBT_USE_FLASH;
> +
> +	ecc_mode = of_get_nand_ecc_mode(dn);
> +	ecc_strength = of_get_nand_ecc_strength(dn);
> +	ecc_step = of_get_nand_ecc_step_size(dn);
> +
> +	if ((ecc_step >= 0 && !(ecc_strength >= 0)) ||
> +	    (!(ecc_step >= 0) && ecc_strength >= 0)) {
> +		pr_err("must set both strength and step size in DT\n");
> +		return -EINVAL;
> +	}
> +
> +	if (ecc_mode >= 0)
> +		chip->ecc.mode = ecc_mode;
> +
> +	if (ecc_strength >= 0)
> +		chip->ecc.strength = ecc_strength;
> +
> +	if (ecc_step > 0)
> +		chip->ecc.size = ecc_step;
> +
> +	return 0;
> +}
> +
>  /**
>   * nand_scan_ident - [NAND Interface] Scan for the NAND device
>   * @mtd: MTD device structure
> @@ -3815,6 +3849,13 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
>  	int i, nand_maf_id, nand_dev_id;
>  	struct nand_chip *chip = mtd->priv;
>  	struct nand_flash_dev *type;
> +	int ret;
> +
> +	if (chip->dn) {
> +		ret = nand_dt_init(mtd, chip, chip->dn);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	/* Set the default functions */
>  	nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> index 3d4ea7eb2b68..e0f40e12a2c8 100644
> --- a/include/linux/mtd/nand.h
> +++ b/include/linux/mtd/nand.h
> @@ -26,6 +26,8 @@
>  
>  struct mtd_info;
>  struct nand_flash_dev;
> +struct device_node;
> +
>  /* Scan and identify a NAND device */
>  extern int nand_scan(struct mtd_info *mtd, int max_chips);
>  /*
> @@ -542,6 +544,7 @@ struct nand_buffers {
>   *			flash device
>   * @IO_ADDR_W:		[BOARDSPECIFIC] address to write the 8 I/O lines of the
>   *			flash device.
> + * @dn:			[BOARDSPECIFIC] device node describing this instance
>   * @read_byte:		[REPLACEABLE] read one byte from the chip
>   * @read_word:		[REPLACEABLE] read one word from the chip
>   * @write_byte:		[REPLACEABLE] write a single byte to the chip on the
> @@ -644,6 +647,8 @@ struct nand_chip {
>  	void __iomem *IO_ADDR_R;
>  	void __iomem *IO_ADDR_W;
>  
> +	struct device_node *dn;
> +
>  	uint8_t (*read_byte)(struct mtd_info *mtd);
>  	u16 (*read_word)(struct mtd_info *mtd);
>  	void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
> -- 
> 1.9.1
> 



More information about the linux-mtd mailing list