123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- From 5844feeaa4154d1c46d3462c7a4653d22356d8b4 Mon Sep 17 00:00:00 2001
- From: Brian Norris <computersforpeace@gmail.com>
- Date: Fri, 23 Jan 2015 00:22:27 -0800
- Subject: [PATCH 20/32] mtd: nand: add common DT init code
- 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@gmail.com>
- ---
- drivers/mtd/nand/nand_base.c | 41 +++++++++++++++++++++++++++++++++++++++++
- include/linux/mtd/nand.h | 5 +++++
- 2 files changed, 46 insertions(+)
- --- 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 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);
- --- 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);
|