Discussion:
[PATCH v3 03/22] mtd: rawnand: legacy: Drop useless test in nand_legacy_set_defaults()
Boris Brezillon
2018-11-11 07:55:05 UTC
Permalink
nand_legacy_set_defaults() returns directly if chip->exec_op != NULL,
no need to test !chip->exec_op after that.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz's T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/nand_legacy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index bf0304c4a640..f76b9356ba9c 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -585,7 +585,7 @@ void nand_legacy_set_defaults(struct nand_chip *chip)
chip->legacy.chip_delay = 20;

/* check, if a user supplied command function given */
- if (!chip->legacy.cmdfunc && !chip->exec_op)
+ if (!chip->legacy.cmdfunc)
chip->legacy.cmdfunc = nand_command;

/* check, if a user supplied wait function given */
--
2.17.1
Boris Brezillon
2018-11-11 07:55:06 UTC
Permalink
nand_exec_op() is only used by core code (nand_xxx.c files). Let's
move this inline function in drivers/mtd/nand/raw/internals.h.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz's T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/internals.h | 9 +++++++++
include/linux/mtd/rawnand.h | 9 ---------
2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index 04c2cf74eff3..6e2f61fbc5f0 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -95,6 +95,15 @@ void nand_decode_ext_id(struct nand_chip *chip);
void panic_nand_wait(struct nand_chip *chip, unsigned long timeo);
void sanitize_string(uint8_t *s, size_t len);

+static inline int nand_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op)
+{
+ if (!chip->exec_op)
+ return -ENOTSUPP;
+
+ return chip->exec_op(chip, op, false);
+}
+
/* BBT functions */
int nand_markbad_bbt(struct nand_chip *chip, loff_t offs);
int nand_isreserved_bbt(struct nand_chip *chip, loff_t offs);
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 4e91a70ede10..85dd89abcd22 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1098,15 +1098,6 @@ struct nand_chip {
} manufacturer;
};

-static inline int nand_exec_op(struct nand_chip *chip,
- const struct nand_operation *op)
-{
- if (!chip->exec_op)
- return -ENOTSUPP;
-
- return chip->exec_op(chip, op, false);
-}
-
extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops;
extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:04 UTC
Permalink
Avoid forward declaration of nand_get_device(), nand_do_write_oob()
and nand_update_bbt() by moving functions around.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz's T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/nand_base.c | 388 +++++++++++++++----------------
drivers/mtd/nand/raw/nand_bbt.c | 112 +++++----
2 files changed, 246 insertions(+), 254 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 2a50afbdeeeb..6d9de6949366 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -49,11 +49,6 @@

#include "internals.h"

-static int nand_get_device(struct nand_chip *chip, int new_state);
-
-static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
- struct mtd_oob_ops *ops);
-
/* Define default oob placement schemes for large and small page devices */
static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
@@ -286,6 +281,197 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs)
return 0;
}

+static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
+{
+ if (chip->legacy.block_bad)
+ return chip->legacy.block_bad(chip, ofs);
+
+ return nand_block_bad(chip, ofs);
+}
+
+/**
+ * panic_nand_get_device - [GENERIC] Get chip for selected access
+ * @chip: the nand chip descriptor
+ * @new_state: the state which is requested
+ *
+ * Used when in panic, no locks are taken.
+ */
+static void panic_nand_get_device(struct nand_chip *chip, int new_state)
+{
+ /* Hardware controller shared among independent devices */
+ chip->controller->active = chip;
+ chip->state = new_state;
+}
+
+/**
+ * nand_get_device - [GENERIC] Get chip for selected access
+ * @chip: NAND chip structure
+ * @new_state: the state which is requested
+ *
+ * Get the device and lock it for exclusive access
+ */
+static int
+nand_get_device(struct nand_chip *chip, int new_state)
+{
+ spinlock_t *lock = &chip->controller->lock;
+ wait_queue_head_t *wq = &chip->controller->wq;
+ DECLARE_WAITQUEUE(wait, current);
+retry:
+ spin_lock(lock);
+
+ /* Hardware controller shared among independent devices */
+ if (!chip->controller->active)
+ chip->controller->active = chip;
+
+ if (chip->controller->active == chip && chip->state == FL_READY) {
+ chip->state = new_state;
+ spin_unlock(lock);
+ return 0;
+ }
+ if (new_state == FL_PM_SUSPENDED) {
+ if (chip->controller->active->state == FL_PM_SUSPENDED) {
+ chip->state = FL_PM_SUSPENDED;
+ spin_unlock(lock);
+ return 0;
+ }
+ }
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(wq, &wait);
+ spin_unlock(lock);
+ schedule();
+ remove_wait_queue(wq, &wait);
+ goto retry;
+}
+
+/**
+ * nand_check_wp - [GENERIC] check if the chip is write protected
+ * @chip: NAND chip object
+ *
+ * Check, if the device is write protected. The function expects, that the
+ * device is already selected.
+ */
+static int nand_check_wp(struct nand_chip *chip)
+{
+ u8 status;
+ int ret;
+
+ /* Broken xD cards report WP despite being writable */
+ if (chip->options & NAND_BROKEN_XD)
+ return 0;
+
+ /* Check the WP bit */
+ ret = nand_status_op(chip, &status);
+ if (ret)
+ return ret;
+
+ return status & NAND_STATUS_WP ? 0 : 1;
+}
+
+/**
+ * nand_fill_oob - [INTERN] Transfer client buffer to oob
+ * @oob: oob data buffer
+ * @len: oob data write length
+ * @ops: oob ops structure
+ */
+static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int ret;
+
+ /*
+ * Initialise to all 0xFF, to avoid the possibility of left over OOB
+ * data from a previous OOB read.
+ */
+ memset(chip->oob_poi, 0xff, mtd->oobsize);
+
+ switch (ops->mode) {
+
+ case MTD_OPS_PLACE_OOB:
+ case MTD_OPS_RAW:
+ memcpy(chip->oob_poi + ops->ooboffs, oob, len);
+ return oob + len;
+
+ case MTD_OPS_AUTO_OOB:
+ ret = mtd_ooblayout_set_databytes(mtd, oob, chip->oob_poi,
+ ops->ooboffs, len);
+ BUG_ON(ret);
+ return oob + len;
+
+ default:
+ BUG();
+ }
+ return NULL;
+}
+
+/**
+ * nand_do_write_oob - [MTD Interface] NAND write out-of-band
+ * @chip: NAND chip object
+ * @to: offset to write to
+ * @ops: oob operation description structure
+ *
+ * NAND write out-of-band.
+ */
+static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int chipnr, page, status, len;
+
+ pr_debug("%s: to = 0x%08x, len = %i\n",
+ __func__, (unsigned int)to, (int)ops->ooblen);
+
+ len = mtd_oobavail(mtd, ops);
+
+ /* Do not allow write past end of page */
+ if ((ops->ooboffs + ops->ooblen) > len) {
+ pr_debug("%s: attempt to write past end of page\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ chipnr = (int)(to >> chip->chip_shift);
+
+ /*
+ * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
+ * of my DiskOnChip 2000 test units) will clear the whole data page too
+ * if we don't do this. I have no clue why, but I seem to have 'fixed'
+ * it in the doc2000 driver in August 1999. dwmw2.
+ */
+ nand_reset(chip, chipnr);
+
+ chip->select_chip(chip, chipnr);
+
+ /* Shift to get page */
+ page = (int)(to >> chip->page_shift);
+
+ /* Check, if it is write protected */
+ if (nand_check_wp(chip)) {
+ chip->select_chip(chip, -1);
+ return -EROFS;
+ }
+
+ /* Invalidate the page cache, if we write to the cached page */
+ if (page == chip->pagebuf)
+ chip->pagebuf = -1;
+
+ nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
+
+ if (ops->mode == MTD_OPS_RAW)
+ status = chip->ecc.write_oob_raw(chip, page & chip->pagemask);
+ else
+ status = chip->ecc.write_oob(chip, page & chip->pagemask);
+
+ chip->select_chip(chip, -1);
+
+ if (status)
+ return status;
+
+ ops->oobretlen = ops->ooblen;
+
+ return 0;
+}
+
/**
* nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker
* @chip: NAND chip object
@@ -341,14 +527,6 @@ int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs)
return nand_default_block_markbad(chip, ofs);
}

-static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
-{
- if (chip->legacy.block_bad)
- return chip->legacy.block_bad(chip, ofs);
-
- return nand_block_bad(chip, ofs);
-}
-
/**
* nand_block_markbad_lowlevel - mark a block bad
* @chip: NAND chip object
@@ -401,30 +579,6 @@ static int nand_block_markbad_lowlevel(struct nand_chip *chip, loff_t ofs)
return ret;
}

-/**
- * nand_check_wp - [GENERIC] check if the chip is write protected
- * @chip: NAND chip object
- *
- * Check, if the device is write protected. The function expects, that the
- * device is already selected.
- */
-static int nand_check_wp(struct nand_chip *chip)
-{
- u8 status;
- int ret;
-
- /* Broken xD cards report WP despite being writable */
- if (chip->options & NAND_BROKEN_XD)
- return 0;
-
- /* Check the WP bit */
- ret = nand_status_op(chip, &status);
- if (ret)
- return ret;
-
- return status & NAND_STATUS_WP ? 0 : 1;
-}
-
/**
* nand_block_isreserved - [GENERIC] Check if a block is marked reserved.
* @mtd: MTD device structure
@@ -555,60 +709,6 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod,
};
EXPORT_SYMBOL_GPL(nand_gpio_waitrdy);

-/**
- * panic_nand_get_device - [GENERIC] Get chip for selected access
- * @chip: the nand chip descriptor
- * @new_state: the state which is requested
- *
- * Used when in panic, no locks are taken.
- */
-static void panic_nand_get_device(struct nand_chip *chip, int new_state)
-{
- /* Hardware controller shared among independent devices */
- chip->controller->active = chip;
- chip->state = new_state;
-}
-
-/**
- * nand_get_device - [GENERIC] Get chip for selected access
- * @chip: NAND chip structure
- * @new_state: the state which is requested
- *
- * Get the device and lock it for exclusive access
- */
-static int
-nand_get_device(struct nand_chip *chip, int new_state)
-{
- spinlock_t *lock = &chip->controller->lock;
- wait_queue_head_t *wq = &chip->controller->wq;
- DECLARE_WAITQUEUE(wait, current);
-retry:
- spin_lock(lock);
-
- /* Hardware controller shared among independent devices */
- if (!chip->controller->active)
- chip->controller->active = chip;
-
- if (chip->controller->active == chip && chip->state == FL_READY) {
- chip->state = new_state;
- spin_unlock(lock);
- return 0;
- }
- if (new_state == FL_PM_SUSPENDED) {
- if (chip->controller->active->state == FL_PM_SUSPENDED) {
- chip->state = FL_PM_SUSPENDED;
- spin_unlock(lock);
- return 0;
- }
- }
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(wq, &wait);
- spin_unlock(lock);
- schedule();
- remove_wait_queue(wq, &wait);
- goto retry;
-}
-
/**
* panic_nand_wait - [GENERIC] wait until the command is done
* @chip: NAND chip structure
@@ -3807,44 +3907,6 @@ static int nand_write_page(struct nand_chip *chip, uint32_t offset,
return 0;
}

-/**
- * nand_fill_oob - [INTERN] Transfer client buffer to oob
- * @chip: NAND chip object
- * @oob: oob data buffer
- * @len: oob data write length
- * @ops: oob ops structure
- */
-static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
- struct mtd_oob_ops *ops)
-{
- struct mtd_info *mtd = nand_to_mtd(chip);
- int ret;
-
- /*
- * Initialise to all 0xFF, to avoid the possibility of left over OOB
- * data from a previous OOB read.
- */
- memset(chip->oob_poi, 0xff, mtd->oobsize);
-
- switch (ops->mode) {
-
- case MTD_OPS_PLACE_OOB:
- case MTD_OPS_RAW:
- memcpy(chip->oob_poi + ops->ooboffs, oob, len);
- return oob + len;
-
- case MTD_OPS_AUTO_OOB:
- ret = mtd_ooblayout_set_databytes(mtd, oob, chip->oob_poi,
- ops->ooboffs, len);
- BUG_ON(ret);
- return oob + len;
-
- default:
- BUG();
- }
- return NULL;
-}
-
#define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0)

/**
@@ -4012,74 +4074,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
return ret;
}

-/**
- * nand_do_write_oob - [MTD Interface] NAND write out-of-band
- * @chip: NAND chip object
- * @to: offset to write to
- * @ops: oob operation description structure
- *
- * NAND write out-of-band.
- */
-static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
- struct mtd_oob_ops *ops)
-{
- struct mtd_info *mtd = nand_to_mtd(chip);
- int chipnr, page, status, len;
-
- pr_debug("%s: to = 0x%08x, len = %i\n",
- __func__, (unsigned int)to, (int)ops->ooblen);
-
- len = mtd_oobavail(mtd, ops);
-
- /* Do not allow write past end of page */
- if ((ops->ooboffs + ops->ooblen) > len) {
- pr_debug("%s: attempt to write past end of page\n",
- __func__);
- return -EINVAL;
- }
-
- chipnr = (int)(to >> chip->chip_shift);
-
- /*
- * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
- * of my DiskOnChip 2000 test units) will clear the whole data page too
- * if we don't do this. I have no clue why, but I seem to have 'fixed'
- * it in the doc2000 driver in August 1999. dwmw2.
- */
- nand_reset(chip, chipnr);
-
- chip->select_chip(chip, chipnr);
-
- /* Shift to get page */
- page = (int)(to >> chip->page_shift);
-
- /* Check, if it is write protected */
- if (nand_check_wp(chip)) {
- chip->select_chip(chip, -1);
- return -EROFS;
- }
-
- /* Invalidate the page cache, if we write to the cached page */
- if (page == chip->pagebuf)
- chip->pagebuf = -1;
-
- nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
-
- if (ops->mode == MTD_OPS_RAW)
- status = chip->ecc.write_oob_raw(chip, page & chip->pagemask);
- else
- status = chip->ecc.write_oob(chip, page & chip->pagemask);
-
- chip->select_chip(chip, -1);
-
- if (status)
- return status;
-
- ops->oobretlen = ops->ooblen;
-
- return 0;
-}
-
/**
* nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
* @mtd: MTD device structure
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index b5e3b54cc767..1b722fe9213c 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -77,8 +77,6 @@
#define BBT_ENTRY_MASK 0x03
#define BBT_ENTRY_SHIFT 2

-static int nand_update_bbt(struct nand_chip *chip, loff_t offs);
-
static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
{
uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
@@ -1034,6 +1032,61 @@ static int check_create(struct nand_chip *this, uint8_t *buf,
return 0;
}

+/**
+ * nand_update_bbt - update bad block table(s)
+ * @this: the NAND device
+ * @offs: the offset of the newly marked block
+ *
+ * The function updates the bad block table(s).
+ */
+static int nand_update_bbt(struct nand_chip *this, loff_t offs)
+{
+ struct mtd_info *mtd = nand_to_mtd(this);
+ int len, res = 0;
+ int chip, chipsel;
+ uint8_t *buf;
+ struct nand_bbt_descr *td = this->bbt_td;
+ struct nand_bbt_descr *md = this->bbt_md;
+
+ if (!this->bbt || !td)
+ return -EINVAL;
+
+ /* Allocate a temporary buffer for one eraseblock incl. oob */
+ len = (1 << this->bbt_erase_shift);
+ len += (len >> this->page_shift) * mtd->oobsize;
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ /* Do we have a bbt per chip? */
+ if (td->options & NAND_BBT_PERCHIP) {
+ chip = (int)(offs >> this->chip_shift);
+ chipsel = chip;
+ } else {
+ chip = 0;
+ chipsel = -1;
+ }
+
+ td->version[chip]++;
+ if (md)
+ md->version[chip]++;
+
+ /* Write the bad block table to the device? */
+ if (td->options & NAND_BBT_WRITE) {
+ res = write_bbt(this, buf, td, md, chipsel);
+ if (res < 0)
+ goto out;
+ }
+ /* Write the mirror bad block table to the device? */
+ if (md && (md->options & NAND_BBT_WRITE)) {
+ res = write_bbt(this, buf, md, td, chipsel);
+ }
+
+ out:
+ kfree(buf);
+ return res;
+}
+
/**
* mark_bbt_regions - [GENERIC] mark the bad block table regions
* @this: the NAND device
@@ -1220,61 +1273,6 @@ static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd)
return res;
}

-/**
- * nand_update_bbt - update bad block table(s)
- * @this: the NAND device
- * @offs: the offset of the newly marked block
- *
- * The function updates the bad block table(s).
- */
-static int nand_update_bbt(struct nand_chip *this, loff_t offs)
-{
- struct mtd_info *mtd = nand_to_mtd(this);
- int len, res = 0;
- int chip, chipsel;
- uint8_t *buf;
- struct nand_bbt_descr *td = this->bbt_td;
- struct nand_bbt_descr *md = this->bbt_md;
-
- if (!this->bbt || !td)
- return -EINVAL;
-
- /* Allocate a temporary buffer for one eraseblock incl. oob */
- len = (1 << this->bbt_erase_shift);
- len += (len >> this->page_shift) * mtd->oobsize;
- buf = kmalloc(len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /* Do we have a bbt per chip? */
- if (td->options & NAND_BBT_PERCHIP) {
- chip = (int)(offs >> this->chip_shift);
- chipsel = chip;
- } else {
- chip = 0;
- chipsel = -1;
- }
-
- td->version[chip]++;
- if (md)
- md->version[chip]++;
-
- /* Write the bad block table to the device? */
- if (td->options & NAND_BBT_WRITE) {
- res = write_bbt(this, buf, td, md, chipsel);
- if (res < 0)
- goto out;
- }
- /* Write the mirror bad block table to the device? */
- if (md && (md->options & NAND_BBT_WRITE)) {
- res = write_bbt(this, buf, md, td, chipsel);
- }
-
- out:
- kfree(buf);
- return res;
-}
-
/*
* Define some generic bad / good block scan pattern which are used
* while scanning a device for factory marked good / bad blocks.
--
2.17.1
Boris Brezillon
2018-11-11 07:55:09 UTC
Permalink
Add an SPDX GPL-2.0 tag and update MODULE_LICENSE() to match the
license text.

Signed-off-by: Boris Brezillon <***@bootlin.com>
---
Changes in v3:
- Use GPL-2.0 instead of GPL-2.0+

Changes in v2:
- New patch
---
drivers/mtd/nand/raw/ams-delta.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index a7c0e3af3b11..4862d4df1a15 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2006 Jonathan McDowell <***@earth.li>
*
@@ -8,10 +9,6 @@
* Converted to platform driver by Janusz Krzysztofik <***@tis.icnet.pl>
* Partially stolen from plat_nand.c
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
* Overview:
* This is a device driver for the NAND flash device found on the
* Amstrad E3 (Delta).
@@ -332,6 +329,6 @@ static struct platform_driver ams_delta_nand_driver = {

module_platform_driver(ams_delta_nand_driver);

-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jonathan McDowell <***@earth.li>");
MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");
--
2.17.1
Boris Brezillon
2018-11-11 07:55:07 UTC
Permalink
Looks like NAND_CONTROLLER_ALLOC has been introduced a long time ago
back when the dummy nand_hw_ctrl object was dynamically allocated
instead of being embedded in nand_chip.

We can safely get rid of this unused flag.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz's T-b

Changes in v2:
- None
---
include/linux/mtd/rawnand.h | 4 ----
1 file changed, 4 deletions(-)

diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 85dd89abcd22..2a3dd3e633f1 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -203,10 +203,6 @@ enum nand_ecc_algo {
*/
#define NAND_IS_BOOT_MEDIUM 0x00400000

-/* Options set by nand scan */
-/* Nand scan has allocated controller struct */
-#define NAND_CONTROLLER_ALLOC 0x80000000
-
/* Cell info constants */
#define NAND_CI_CHIPNR_MSK 0x03
#define NAND_CI_CELLTYPE_MSK 0x0C
--
2.17.1
Boris Brezillon
2018-11-11 07:55:08 UTC
Permalink
Drop the asm and mach headers inclusion and allow this driver to be
compiled when COMPILE_TEST=y in order to increase compile-test
coverage.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b
- Include linux/sizes.h and linux/io.h

Changes in v2:
- New patch
---
drivers/mtd/nand/raw/Kconfig | 2 +-
drivers/mtd/nand/raw/ams-delta.c | 7 ++-----
2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index c7efc31384d5..1a55d3e3d4c5 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -70,7 +70,7 @@ config MTD_NAND_GPIO

config MTD_NAND_AMS_DELTA
tristate "NAND Flash device on Amstrad E3"
- depends on MACH_AMS_DELTA
+ depends on MACH_AMS_DELTA || COMPILE_TEST
default y
help
Support for NAND flash on Amstrad E3 (Delta).
diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 9ca70aab199d..a7c0e3af3b11 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -21,15 +21,12 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
+#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_data/gpio-omap.h>
-
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-#include <mach/hardware.h>
+#include <linux/sizes.h>

/*
* MTD structure for E3 (Delta)
--
2.17.1
Boris Brezillon
2018-11-11 07:55:13 UTC
Permalink
All NAND objects are supposed to inherit from nand_controller. The
framework is providing a dummy controller object, but we're moving
away from this approach in favor of explicit inheritance.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/ams-delta.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index c59672a92832..34b83edb965c 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -29,6 +29,7 @@
* MTD structure for E3 (Delta)
*/
struct ams_delta_nand {
+ struct nand_controller base;
struct nand_chip nand_chip;
struct gpio_desc *gpiod_rdy;
struct gpio_desc *gpiod_nce;
@@ -277,6 +278,10 @@ static int ams_delta_init(struct platform_device *pdev)
/* Initialize data port direction to a known state */
ams_delta_dir_input(priv, true);

+ /* Initialize the NAND controller object embedded in ams_delta_nand. */
+ nand_controller_init(&priv->base);
+ this->controller = &priv->base;
+
/* Scan to find existence of the device */
err = nand_scan(this, 1);
if (err)
--
2.17.1
Boris Brezillon
2018-11-11 07:55:15 UTC
Permalink
In order to deprecate the ->select_chip hook we need to pass the CS
line a NAND operations are targeting. This is done through the
addition of a cs field to the nand_operation struct.

We also need to keep track of the currently selected target to
properly initialize op->cs, hence the ->cur_cs field addition to the
nand_chip struct.

Note that op->cs is not assigned in nand_exec_op() because we might
rework the way we execute NAND operations in the future (adopt a
queuing mechanism instead of the serialization we have right now).

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- Initialize ->cur_cs
---
drivers/mtd/nand/raw/internals.h | 3 +++
drivers/mtd/nand/raw/nand_base.c | 39 +++++++++++++++++--------------
drivers/mtd/nand/raw/nand_hynix.c | 4 ++--
include/linux/mtd/rawnand.h | 11 ++++++++-
4 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index 6e2f61fbc5f0..b62728d5884b 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -101,6 +101,9 @@ static inline int nand_exec_op(struct nand_chip *chip,
if (!chip->exec_op)
return -ENOTSUPP;

+ if (WARN_ON(op->cs >= chip->numchips))
+ return -EINVAL;
+
return chip->exec_op(chip, op, false);
}

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index f85e6f3b1b2f..7aa661f76891 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -246,6 +246,7 @@ void nand_select_target(struct nand_chip *chip, unsigned int cs)
if (WARN_ON(cs > chip->numchips))
return;

+ chip->cur_cs = cs;
chip->select_chip(chip, cs);
}
EXPORT_SYMBOL_GPL(nand_select_target);
@@ -260,6 +261,7 @@ EXPORT_SYMBOL_GPL(nand_select_target);
void nand_deselect_target(struct nand_chip *chip)
{
chip->select_chip(chip, -1);
+ chip->cur_cs = -1;
}
EXPORT_SYMBOL_GPL(nand_deselect_target);

@@ -1022,7 +1024,7 @@ static int nand_sp_exec_read_page_op(struct nand_chip *chip, unsigned int page,
PSEC_TO_NSEC(sdr->tRR_min)),
NAND_OP_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
int ret;

/* Drop the DATA_IN instruction if len is set to 0. */
@@ -1065,7 +1067,7 @@ static int nand_lp_exec_read_page_op(struct nand_chip *chip, unsigned int page,
PSEC_TO_NSEC(sdr->tRR_min)),
NAND_OP_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
int ret;

/* Drop the DATA_IN instruction if len is set to 0. */
@@ -1160,7 +1162,7 @@ int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
PSEC_TO_NSEC(sdr->tRR_min)),
NAND_OP_8BIT_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

/* Drop the DATA_IN instruction if len is set to 0. */
if (!len)
@@ -1216,7 +1218,7 @@ int nand_change_read_column_op(struct nand_chip *chip,
PSEC_TO_NSEC(sdr->tCCS_min)),
NAND_OP_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
int ret;

ret = nand_fill_column_cycles(chip, addrs, offset_in_page);
@@ -1298,7 +1300,7 @@ static int nand_exec_prog_page_op(struct nand_chip *chip, unsigned int page,
NAND_OP_CMD(NAND_CMD_PAGEPROG, PSEC_TO_NSEC(sdr->tWB_max)),
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tPROG_max), 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
int naddrs = nand_fill_column_cycles(chip, addrs, offset_in_page);
int ret;
u8 status;
@@ -1412,7 +1414,7 @@ int nand_prog_page_end_op(struct nand_chip *chip)
PSEC_TO_NSEC(sdr->tWB_max)),
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tPROG_max), 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

ret = nand_exec_op(chip, &op);
if (ret)
@@ -1520,7 +1522,7 @@ int nand_change_write_column_op(struct nand_chip *chip,
NAND_OP_ADDR(2, addrs, PSEC_TO_NSEC(sdr->tCCS_min)),
NAND_OP_DATA_OUT(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
int ret;

ret = nand_fill_column_cycles(chip, addrs, offset_in_page);
@@ -1574,7 +1576,7 @@ int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
NAND_OP_ADDR(1, &addr, PSEC_TO_NSEC(sdr->tADL_min)),
NAND_OP_8BIT_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

/* Drop the DATA_IN instruction if len is set to 0. */
if (!len)
@@ -1613,7 +1615,7 @@ int nand_status_op(struct nand_chip *chip, u8 *status)
PSEC_TO_NSEC(sdr->tADL_min)),
NAND_OP_8BIT_DATA_IN(1, status, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

if (!status)
op.ninstrs--;
@@ -1646,7 +1648,7 @@ int nand_exit_status_op(struct nand_chip *chip)
struct nand_op_instr instrs[] = {
NAND_OP_CMD(NAND_CMD_READ0, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -1685,7 +1687,7 @@ int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock)
PSEC_TO_MSEC(sdr->tWB_max)),
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tBERS_max), 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

if (chip->options & NAND_ROW_ADDR_3)
instrs[1].ctx.addr.naddrs++;
@@ -1743,7 +1745,7 @@ static int nand_set_features_op(struct nand_chip *chip, u8 feature,
PSEC_TO_NSEC(sdr->tWB_max)),
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tFEAT_max), 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -1791,7 +1793,7 @@ static int nand_get_features_op(struct nand_chip *chip, u8 feature,
NAND_OP_8BIT_DATA_IN(ONFI_SUBFEATURE_PARAM_LEN,
data, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -1811,7 +1813,7 @@ static int nand_wait_rdy_op(struct nand_chip *chip, unsigned int timeout_ms,
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(timeout_ms),
PSEC_TO_NSEC(delay_ns)),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -1844,7 +1846,7 @@ int nand_reset_op(struct nand_chip *chip)
NAND_OP_CMD(NAND_CMD_RESET, PSEC_TO_NSEC(sdr->tWB_max)),
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tRST_max), 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -1878,7 +1880,7 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
struct nand_op_instr instrs[] = {
NAND_OP_DATA_IN(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

instrs[0].ctx.data.force_8bit = force_8bit;

@@ -1922,7 +1924,7 @@ int nand_write_data_op(struct nand_chip *chip, const void *buf,
struct nand_op_instr instrs[] = {
NAND_OP_DATA_OUT(len, buf, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

instrs[0].ctx.data.force_8bit = force_8bit;

@@ -5006,6 +5008,9 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
unsigned int i;
int ret;

+ /* Assume all dies are deselected when we enter nand_scan_ident(). */
+ chip->cur_cs = -1;
+
/* Enforce the right timings for reset/detection */
onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0);

diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index ac1b5c103968..1e4499d01e14 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -84,7 +84,7 @@ static int hynix_nand_cmd_op(struct nand_chip *chip, u8 cmd)
struct nand_op_instr instrs[] = {
NAND_OP_CMD(cmd, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
@@ -103,7 +103,7 @@ static int hynix_nand_reg_write_op(struct nand_chip *chip, u8 addr, u8 val)
NAND_OP_ADDR(1, &addr, 0),
NAND_OP_8BIT_DATA_OUT(1, &val, 0),
};
- struct nand_operation op = NAND_OPERATION(instrs);
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

return nand_exec_op(chip, &op);
}
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index def6dff11e8b..aa1512df38a9 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -875,18 +875,21 @@ struct nand_op_parser {

/**
* struct nand_operation - NAND operation descriptor
+ * @cs: the CS line to select for this NAND operation
* @instrs: array of instructions to execute
* @ninstrs: length of the @instrs array
*
* The actual operation structure that will be passed to chip->exec_op().
*/
struct nand_operation {
+ unsigned int cs;
const struct nand_op_instr *instrs;
unsigned int ninstrs;
};

-#define NAND_OPERATION(_instrs) \
+#define NAND_OPERATION(_cs, _instrs) \
{ \
+ .cs = _cs, \
.instrs = _instrs, \
.ninstrs = ARRAY_SIZE(_instrs), \
}
@@ -1008,6 +1011,10 @@ struct nand_legacy {
* this nand device will encounter their life times.
* @blocks_per_die: [INTERN] The number of PEBs in a die
* @data_interface: [INTERN] NAND interface timing information
+ * @cur_cs: currently selected target. -1 means no target selected,
+ * otherwise we should always have cur_cs >= 0 &&
+ * cur_cs < numchips. NAND Controller drivers should not
+ * modify this value, but they're allowed to read it.
* @read_retries: [INTERN] the number of read retry modes supported
* @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
* chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
@@ -1069,6 +1076,8 @@ struct nand_chip {

struct nand_data_interface data_interface;

+ int cur_cs;
+
int read_retries;

flstate_t state;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:14 UTC
Permalink
Add a wrapper to prevent drivers and core code from directly calling
the ->select_chip hook which we are about to deprecate.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b
- Initialize ->numchips to maxchips in nand_scan_ident() (bug reported
by Janusz Krzysztofik)

Changes in v2:
- None
---
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 23 ++--
drivers/mtd/nand/raw/jz4740_nand.c | 4 +-
drivers/mtd/nand/raw/nand_base.c | 120 ++++++++++++++-------
drivers/mtd/nand/raw/r852.c | 4 +-
include/linux/mtd/rawnand.h | 5 +-
5 files changed, 104 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 94c2b7525c85..302ddd3d4a5f 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1549,7 +1549,7 @@ static int gpmi_block_markbad(struct nand_chip *chip, loff_t ofs)
int column, page, chipnr;

chipnr = (int)(ofs >> chip->chip_shift);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

column = !GPMI_IS_MX23(this) ? mtd->writesize : 0;

@@ -1562,7 +1562,7 @@ static int gpmi_block_markbad(struct nand_chip *chip, loff_t ofs)

ret = nand_prog_page_op(chip, page, column, block_mark, 1);

- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

return ret;
}
@@ -1610,7 +1610,7 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
search_area_size_in_strides = 1 << rom_geo->search_area_stride_exponent;

saved_chip_number = this->current_chip;
- chip->select_chip(chip, 0);
+ nand_select_target(chip, 0);

/*
* Loop through the first search area, looking for the NCB fingerprint.
@@ -1638,7 +1638,10 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)

}

- chip->select_chip(chip, saved_chip_number);
+ if (saved_chip_number >= 0)
+ nand_select_target(chip, saved_chip_number);
+ else
+ nand_deselect_target(chip);

if (found_an_ncb_fingerprint)
dev_dbg(dev, "\tFound a fingerprint\n");
@@ -1681,7 +1684,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)

/* Select chip 0. */
saved_chip_number = this->current_chip;
- chip->select_chip(chip, 0);
+ nand_select_target(chip, 0);

/* Loop over blocks in the first search area, erasing them. */
dev_dbg(dev, "Erasing the search area...\n");
@@ -1713,7 +1716,11 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
}

/* Deselect chip 0. */
- chip->select_chip(chip, saved_chip_number);
+ if (saved_chip_number >= 0)
+ nand_select_target(chip, saved_chip_number);
+ else
+ nand_deselect_target(chip);
+
return 0;
}

@@ -1762,10 +1769,10 @@ static int mx23_boot_init(struct gpmi_nand_data *this)
byte = block << chip->phys_erase_shift;

/* Send the command to read the conventional block mark. */
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
nand_read_page_op(chip, page, mtd->writesize, NULL, 0);
block_mark = chip->legacy.read_byte(chip);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

/*
* Check if the block is marked bad. If so, we need to mark it
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index fb59cfca11a7..d271004f16b0 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -335,14 +335,14 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
goto notfound_id;

/* Retrieve the IDs from the first chip. */
- chip->select_chip(chip, 0);
+ nand_select_target(chip, 0);
nand_reset_op(chip);
nand_readid_op(chip, 0, id, sizeof(id));
*nand_maf_id = id[0];
*nand_dev_id = id[1];
} else {
/* Detect additional chip. */
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
nand_reset_op(chip);
nand_readid_op(chip, 0, id, sizeof(id));
if (*nand_maf_id != id[0] || *nand_dev_id != id[1]) {
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 6d9de6949366..f85e6f3b1b2f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -228,6 +228,41 @@ static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
return ret;
}

+/**
+ * nand_select_target() - Select a NAND target (A.K.A. die)
+ * @chip: NAND chip object
+ * @cs: the CS line to select. Note that this CS id is always from the chip
+ * PoV, not the controller one
+ *
+ * Select a NAND target so that further operations executed on @chip go to the
+ * selected NAND target.
+ */
+void nand_select_target(struct nand_chip *chip, unsigned int cs)
+{
+ /*
+ * cs should always lie between 0 and chip->numchips, when that's not
+ * the case it's a bug and the caller should be fixed.
+ */
+ if (WARN_ON(cs > chip->numchips))
+ return;
+
+ chip->select_chip(chip, cs);
+}
+EXPORT_SYMBOL_GPL(nand_select_target);
+
+/**
+ * nand_deselect_target() - Deselect the currently selected target
+ * @chip: NAND chip object
+ *
+ * Deselect the currently selected NAND target. The result of operations
+ * executed on @chip after the target has been deselected is undefined.
+ */
+void nand_deselect_target(struct nand_chip *chip)
+{
+ chip->select_chip(chip, -1);
+}
+EXPORT_SYMBOL_GPL(nand_deselect_target);
+
/**
* nand_release_device - [GENERIC] release chip
* @chip: NAND chip object
@@ -440,14 +475,14 @@ static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
*/
nand_reset(chip, chipnr);

- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

/* Shift to get page */
page = (int)(to >> chip->page_shift);

/* Check, if it is write protected */
if (nand_check_wp(chip)) {
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
return -EROFS;
}

@@ -462,7 +497,7 @@ static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
else
status = chip->ecc.write_oob(chip, page & chip->pagemask);

- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

if (status)
return status;
@@ -816,10 +851,10 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)

/* Change the mode on the chip side (if supported by the NAND chip) */
if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
ret = nand_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
tmode_param);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
if (ret)
return ret;
}
@@ -834,10 +869,10 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
return 0;

memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
ret = nand_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
tmode_param);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
if (ret)
goto err_reset_chip;

@@ -855,9 +890,9 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
* timing mode.
*/
nand_reset_data_interface(chip, chipnr);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
nand_reset_op(chip);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

return ret;
}
@@ -2345,11 +2380,12 @@ int nand_reset(struct nand_chip *chip, int chipnr)

/*
* The CS line has to be released before we can apply the new NAND
- * interface settings, hence this weird ->select_chip() dance.
+ * interface settings, hence this weird nand_select_target()
+ * nand_deselect_target() dance.
*/
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);
ret = nand_reset_op(chip);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
if (ret)
return ret;

@@ -3133,7 +3169,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
bool ecc_fail = false;

chipnr = (int)(from >> chip->chip_shift);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

realpage = (int)(from >> chip->page_shift);
page = realpage & chip->pagemask;
@@ -3264,11 +3300,11 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
/* Check, if we cross a chip boundary */
if (!page) {
chipnr++;
- chip->select_chip(chip, -1);
- chip->select_chip(chip, chipnr);
+ nand_deselect_target(chip);
+ nand_select_target(chip, chipnr);
}
}
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

ops->retlen = ops->len - (size_t) readlen;
if (oob)
@@ -3465,7 +3501,7 @@ static int nand_do_read_oob(struct nand_chip *chip, loff_t from,
len = mtd_oobavail(mtd, ops);

chipnr = (int)(from >> chip->chip_shift);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

/* Shift to get page */
realpage = (int)(from >> chip->page_shift);
@@ -3498,11 +3534,11 @@ static int nand_do_read_oob(struct nand_chip *chip, loff_t from,
/* Check, if we cross a chip boundary */
if (!page) {
chipnr++;
- chip->select_chip(chip, -1);
- chip->select_chip(chip, chipnr);
+ nand_deselect_target(chip);
+ nand_select_target(chip, chipnr);
}
}
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

ops->oobretlen = ops->ooblen - readlen;

@@ -3946,7 +3982,7 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
column = to & (mtd->writesize - 1);

chipnr = (int)(to >> chip->chip_shift);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

/* Check, if it is write protected */
if (nand_check_wp(chip)) {
@@ -4022,8 +4058,8 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
/* Check, if we cross a chip boundary */
if (!page) {
chipnr++;
- chip->select_chip(chip, -1);
- chip->select_chip(chip, chipnr);
+ nand_deselect_target(chip);
+ nand_select_target(chip, chipnr);
}
}

@@ -4032,7 +4068,7 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
ops->oobretlen = ops->ooblen;

err_out:
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
return ret;
}

@@ -4058,7 +4094,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
/* Grab the device */
panic_nand_get_device(chip, FL_WRITING);

- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

/* Wait for the device to get ready */
panic_nand_wait(chip, 400);
@@ -4171,7 +4207,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift);

/* Select the NAND device */
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

/* Check, if it is write protected */
if (nand_check_wp(chip)) {
@@ -4225,8 +4261,8 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
/* Check, if we cross a chip boundary */
if (len && !(page & chip->pagemask)) {
chipnr++;
- chip->select_chip(chip, -1);
- chip->select_chip(chip, chipnr);
+ nand_deselect_target(chip);
+ nand_select_target(chip, chipnr);
}
}

@@ -4234,7 +4270,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
erase_exit:

/* Deselect and wake up anyone waiting on the device */
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
nand_release_device(chip);

/* Return more or less happy */
@@ -4272,11 +4308,11 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)

/* Select the NAND device */
nand_get_device(chip, FL_READING);
- chip->select_chip(chip, chipnr);
+ nand_select_target(chip, chipnr);

ret = nand_block_checkbad(chip, offs, 0);

- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
nand_release_device(chip);

return ret;
@@ -4645,7 +4681,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
return ret;

/* Select the device */
- chip->select_chip(chip, 0);
+ nand_select_target(chip, 0);

/* Send the command for reading device ID */
ret = nand_readid_op(chip, 0, id_data, 2);
@@ -4989,6 +5025,12 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
if (ret)
return ret;

+ /*
+ * Start with chips->numchips = maxchips to let nand_select_target() do
+ * its job. chip->numchips will be adjusted after.
+ */
+ chip->numchips = maxchips;
+
/* Set the default functions */
nand_set_defaults(chip);

@@ -4997,14 +5039,14 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
if (ret) {
if (!(chip->options & NAND_SCAN_SILENT_NODEV))
pr_warn("No NAND device found\n");
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
return ret;
}

nand_maf_id = chip->id.data[0];
nand_dev_id = chip->id.data[1];

- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);

/* Check for a chip array */
for (i = 1; i < maxchips; i++) {
@@ -5013,15 +5055,15 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
/* See comment in nand_get_flash_type for reset */
nand_reset(chip, i);

- chip->select_chip(chip, i);
+ nand_select_target(chip, i);
/* Send the command for reading device ID */
nand_readid_op(chip, 0, id, sizeof(id));
/* Read manufacturer and device IDs */
if (nand_maf_id != id[0] || nand_dev_id != id[1]) {
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
break;
}
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
}
if (i > 1)
pr_info("%d chips detected\n", i);
@@ -5447,9 +5489,9 @@ static int nand_scan_tail(struct nand_chip *chip)
* to explictly select the relevant die when interacting with the NAND
* chip.
*/
- chip->select_chip(chip, 0);
+ nand_select_target(chip, 0);
ret = nand_manufacturer_init(chip);
- chip->select_chip(chip, -1);
+ nand_deselect_target(chip);
if (ret)
goto err_free_buf;

diff --git a/drivers/mtd/nand/raw/r852.c b/drivers/mtd/nand/raw/r852.c
index 35f0b343cf90..c01422d953dd 100644
--- a/drivers/mtd/nand/raw/r852.c
+++ b/drivers/mtd/nand/raw/r852.c
@@ -1045,9 +1045,9 @@ static int r852_resume(struct device *device)
/* Otherwise, initialize the card */
if (dev->card_registered) {
r852_engine_enable(dev);
- dev->chip->select_chip(dev->chip, 0);
+ nand_select_target(dev->chip, 0);
nand_reset_op(dev->chip);
- dev->chip->select_chip(dev->chip, -1);
+ nand_deselect_target(dev->chip);
}

/* Program card detection IRQ */
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 2a3dd3e633f1..def6dff11e8b 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1332,9 +1332,12 @@ void nand_release(struct nand_chip *chip);
* instruction and have no physical pin to check it.
*/
int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms);
-
struct gpio_desc;
int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod,
unsigned long timeout_ms);

+/* Select/deselect a NAND target. */
+void nand_select_target(struct nand_chip *chip, unsigned int cs);
+void nand_deselect_target(struct nand_chip *chip);
+
#endif /* __LINUX_MTD_RAWNAND_H */
--
2.17.1
Boris Brezillon
2018-11-11 07:55:12 UTC
Permalink
mtd_device_register() can fail, and when it does we should propagate
the error and cleanup what has been done before.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/ams-delta.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 0fc7563fba10..c59672a92832 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -283,10 +283,16 @@ static int ams_delta_init(struct platform_device *pdev)
goto err_unmap;

/* Register the partitions */
- mtd_device_register(mtd, partition_info, ARRAY_SIZE(partition_info));
+ err = mtd_device_register(mtd, partition_info,
+ ARRAY_SIZE(partition_info));
+ if (err)
+ goto err_nand_cleanup;

return 0;

+err_nand_cleanup:
+ nand_cleanup(this);
+
err_unmap:
iounmap(io_base);
--
2.17.1
Boris Brezillon
2018-11-11 07:55:20 UTC
Permalink
Now that the CS to be selected is kept in chip->cur_cs and passed
in nand_operation->cs, we can get rid of the ->select_chip()
implementation and replace it by an internal function which is called
from the chip->exec_op() and chip->ecc.read/write_xxx() hooks.

Signed-off-by: Boris Brezillon <***@bootlin.com>
---
Changes in v3:
- None

Changes in v2:
- Use op->cs instead of chip->cur_cs in vf610_nfc_exec_op()
---
drivers/mtd/nand/raw/vf610_nfc.c | 34 +++++++++++++++++---------------
1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
index 9814fd4a84cf..49a174e30211 100644
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -487,36 +487,35 @@ static const struct nand_op_parser vf610_nfc_op_parser = NAND_OP_PARSER(
NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, PAGE_2K + OOB_MAX)),
);

-static int vf610_nfc_exec_op(struct nand_chip *chip,
- const struct nand_operation *op,
- bool check_only)
-{
- return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op,
- check_only);
-}
-
/*
* This function supports Vybrid only (MPC5125 would have full RB and four CS)
*/
-static void vf610_nfc_select_chip(struct nand_chip *chip, int cs)
+static void vf610_nfc_select_target(struct nand_chip *chip, unsigned int cs)
{
struct vf610_nfc *nfc = mtd_to_nfc(nand_to_mtd(chip));
- u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
+ u32 tmp;

/* Vybrid only (MPC5125 would have full RB and four CS) */
if (nfc->variant != NFC_VFC610)
return;

+ tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
-
- if (cs >= 0) {
- tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
- tmp |= BIT(cs) << ROW_ADDR_CHIP_SEL_SHIFT;
- }
+ tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
+ tmp |= BIT(cs) << ROW_ADDR_CHIP_SEL_SHIFT;

vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
}

+static int vf610_nfc_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only)
+{
+ vf610_nfc_select_target(chip, op->cs);
+ return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op,
+ check_only);
+}
+
static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
uint8_t *oob, int page)
{
@@ -566,6 +565,8 @@ static int vf610_nfc_read_page(struct nand_chip *chip, uint8_t *buf,
u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0;
int stat;

+ vf610_nfc_select_target(chip, chip->cur_cs);
+
cmd2 |= NAND_CMD_READ0 << CMD_BYTE1_SHIFT;
code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2;

@@ -613,6 +614,8 @@ static int vf610_nfc_write_page(struct nand_chip *chip, const uint8_t *buf,
u8 status;
int ret;

+ vf610_nfc_select_target(chip, chip->cur_cs);
+
cmd2 |= NAND_CMD_SEQIN << CMD_BYTE1_SHIFT;
code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2;

@@ -877,7 +880,6 @@ static int vf610_nfc_probe(struct platform_device *pdev)
}

chip->exec_op = vf610_nfc_exec_op;
- chip->select_chip = vf610_nfc_select_chip;

chip->options |= NAND_NO_SUBPAGE_WRITE;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:24 UTC
Permalink
->setup_data_interface() is a controller specific method and should
thus be placed in nand_controller_ops.

In order to make that work with controllers that support keeping
pre-configured timings we need to add a new NAND_KEEP_TIMINGS flag to
inform the core it should skip the timings selection step.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/atmel/nand-controller.c | 5 +++--
drivers/mtd/nand/raw/denali.c | 3 ++-
drivers/mtd/nand/raw/fsmc_nand.c | 7 ++++---
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 2 +-
drivers/mtd/nand/raw/internals.h | 12 ++++++++++++
drivers/mtd/nand/raw/marvell_nand.c | 3 ++-
drivers/mtd/nand/raw/mtk_nand.c | 2 +-
drivers/mtd/nand/raw/mxc_nand.c | 12 +++++++++++-
drivers/mtd/nand/raw/nand_base.c | 14 ++++++++------
drivers/mtd/nand/raw/nand_legacy.c | 2 +-
drivers/mtd/nand/raw/s3c2410.c | 5 +++--
drivers/mtd/nand/raw/sunxi_nand.c | 2 +-
drivers/mtd/nand/raw/tango_nand.c | 2 +-
drivers/mtd/nand/raw/tegra_nand.c | 2 +-
include/linux/mtd/rawnand.h | 20 ++++++++++++++------
15 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index d5c58eb040d8..dcd3bd73e549 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1479,8 +1479,8 @@ static void atmel_nand_init(struct atmel_nand_controller *nc,
chip->legacy.write_buf = atmel_nand_write_buf;
chip->legacy.select_chip = atmel_nand_select_chip;

- if (nc->mck && nc->caps->ops->setup_data_interface)
- chip->setup_data_interface = atmel_nand_setup_data_interface;
+ if (!nc->mck || !nc->caps->ops->setup_data_interface)
+ chip->options |= NAND_KEEP_TIMINGS;

/* Some NANDs require a longer delay than the default one (20us). */
chip->legacy.chip_delay = 40;
@@ -1908,6 +1908,7 @@ static int atmel_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops atmel_nand_controller_ops = {
.attach_chip = atmel_nand_attach_chip,
+ .setup_data_interface = atmel_nand_setup_data_interface,
};

static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 64895ca68c8d..bad3b8ad5e0a 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1316,6 +1316,7 @@ static void denali_detach_chip(struct nand_chip *chip)
static const struct nand_controller_ops denali_controller_ops = {
.attach_chip = denali_attach_chip,
.detach_chip = denali_detach_chip,
+ .setup_data_interface = denali_setup_data_interface,
};

int denali_init(struct denali_nand_info *denali)
@@ -1372,7 +1373,7 @@ int denali_init(struct denali_nand_info *denali)

/* clk rate info is needed for setup_data_interface */
if (denali->clk_rate && denali->clk_x_rate)
- chip->setup_data_interface = denali_setup_data_interface;
+ chip->options |= NAND_KEEP_TIMINGS;

chip->dummy_controller.ops = &denali_controller_ops;
ret = nand_scan(chip, denali->max_banks);
diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
index 1eb5008e7453..61927c4c2650 100644
--- a/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -996,6 +996,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand)
static const struct nand_controller_ops fsmc_nand_controller_ops = {
.attach_chip = fsmc_nand_attach_chip,
.exec_op = fsmc_exec_op,
+ .setup_data_interface = fsmc_setup_data_interface,
};

/*
@@ -1108,10 +1109,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
}
}

- if (host->dev_timings)
+ if (host->dev_timings) {
fsmc_nand_setup(host, host->dev_timings);
- else
- nand->setup_data_interface = fsmc_setup_data_interface;
+ nand->options |= NAND_KEEP_TIMINGS;
+ }

if (AMBA_REV_BITS(host->pid) >= 8) {
nand->ecc.read_page = fsmc_read_page_hwecc;
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index c461d5efabc0..25f9fe79796a 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1889,6 +1889,7 @@ static int gpmi_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops gpmi_nand_controller_ops = {
.attach_chip = gpmi_nand_attach_chip,
+ .setup_data_interface = gpmi_setup_data_interface,
};

static int gpmi_nand_init(struct gpmi_nand_data *this)
@@ -1908,7 +1909,6 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
nand_set_controller_data(chip, this);
nand_set_flash_node(chip, this->pdev->dev.of_node);
chip->legacy.select_chip = gpmi_select_chip;
- chip->setup_data_interface = gpmi_setup_data_interface;
chip->legacy.cmd_ctrl = gpmi_cmd_ctrl;
chip->legacy.dev_ready = gpmi_dev_ready;
chip->legacy.read_byte = gpmi_read_byte;
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index ac66b458566f..fbf6ca015cd7 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -116,6 +116,18 @@ static inline int nand_exec_op(struct nand_chip *chip,
return chip->controller->ops->exec_op(chip, op, false);
}

+static inline bool nand_has_setup_data_iface(struct nand_chip *chip)
+{
+ if (!chip->controller || !chip->controller->ops ||
+ !chip->controller->ops->setup_data_interface)
+ return false;
+
+ if (chip->options & NAND_KEEP_TIMINGS)
+ return false;
+
+ return true;
+}
+
/* BBT functions */
int nand_markbad_bbt(struct nand_chip *chip, loff_t offs);
int nand_isreserved_bbt(struct nand_chip *chip, loff_t offs);
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 2e8257fe7d00..b7b4d9b14da1 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -2506,6 +2506,7 @@ static int marvell_nand_attach_chip(struct nand_chip *chip)
static const struct nand_controller_ops marvell_nand_controller_ops = {
.attach_chip = marvell_nand_attach_chip,
.exec_op = marvell_nfc_exec_op,
+ .setup_data_interface = marvell_nfc_setup_data_interface,
};

static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
@@ -2629,7 +2630,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
nand_set_flash_node(chip, np);

if (!of_property_read_bool(np, "marvell,nand-keep-config"))
- chip->setup_data_interface = marvell_nfc_setup_data_interface;
+ chip->options |= NAND_KEEP_TIMINGS;

mtd = nand_to_mtd(chip);
mtd->dev.parent = dev;
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index ce124f8c02cd..b6b4602f5132 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1288,6 +1288,7 @@ static int mtk_nfc_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops mtk_nfc_controller_ops = {
.attach_chip = mtk_nfc_attach_chip,
+ .setup_data_interface = mtk_nfc_setup_data_interface,
};

static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
@@ -1339,7 +1340,6 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
nand->legacy.read_byte = mtk_nfc_read_byte;
nand->legacy.read_buf = mtk_nfc_read_buf;
nand->legacy.cmd_ctrl = mtk_nfc_cmd_ctrl;
- nand->setup_data_interface = mtk_nfc_setup_data_interface;

/* set default mode in case dt entry is missing */
nand->ecc.mode = NAND_ECC_HW;
diff --git a/drivers/mtd/nand/raw/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c
index c00b1d408a04..9b75d894cb74 100644
--- a/drivers/mtd/nand/raw/mxc_nand.c
+++ b/drivers/mtd/nand/raw/mxc_nand.c
@@ -1738,8 +1738,17 @@ static int mxcnd_attach_chip(struct nand_chip *chip)
return 0;
}

+static int mxcnd_setup_data_interface(struct nand_chip *chip, int chipnr,
+ const struct nand_data_interface *conf)
+{
+ struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+ return host->devtype_data->setup_data_interface(chip, chipnr, conf);
+}
+
static const struct nand_controller_ops mxcnd_controller_ops = {
.attach_chip = mxcnd_attach_chip,
+ .setup_data_interface = mxcnd_setup_data_interface,
};

static int mxcnd_probe(struct platform_device *pdev)
@@ -1800,7 +1809,8 @@ static int mxcnd_probe(struct platform_device *pdev)
if (err < 0)
return err;

- this->setup_data_interface = host->devtype_data->setup_data_interface;
+ if (!host->devtype_data->setup_data_interface)
+ this->options |= NAND_KEEP_TIMINGS;

if (host->devtype_data->needs_ip) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index a62bbf22f135..a036333629dc 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -807,7 +807,7 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr)
{
int ret;

- if (!chip->setup_data_interface)
+ if (!nand_has_setup_data_iface(chip))
return 0;

/*
@@ -825,7 +825,8 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr)
*/

onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0);
- ret = chip->setup_data_interface(chip, chipnr, &chip->data_interface);
+ ret = chip->controller->ops->setup_data_interface(chip, chipnr,
+ &chip->data_interface);
if (ret)
pr_err("Failed to configure data interface to SDR timing mode 0\n");

@@ -852,7 +853,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
};
int ret;

- if (!chip->setup_data_interface)
+ if (!nand_has_setup_data_iface(chip))
return 0;

/* Change the mode on the chip side (if supported by the NAND chip) */
@@ -866,7 +867,8 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
}

/* Change the mode on the controller side */
- ret = chip->setup_data_interface(chip, chipnr, &chip->data_interface);
+ ret = chip->controller->ops->setup_data_interface(chip, chipnr,
+ &chip->data_interface);
if (ret)
return ret;

@@ -921,7 +923,7 @@ static int nand_init_data_interface(struct nand_chip *chip)
{
int modes, mode, ret;

- if (!chip->setup_data_interface)
+ if (!nand_has_setup_data_iface(chip))
return 0;

/*
@@ -947,7 +949,7 @@ static int nand_init_data_interface(struct nand_chip *chip)
* Pass NAND_DATA_IFACE_CHECK_ONLY to only check if the
* controller supports the requested timings.
*/
- ret = chip->setup_data_interface(chip,
+ ret = chip->controller->ops->setup_data_interface(chip,
NAND_DATA_IFACE_CHECK_ONLY,
&chip->data_interface);
if (!ret) {
diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index 47364237861e..43575943f13b 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -364,7 +364,7 @@ static void nand_ccs_delay(struct nand_chip *chip)
* Wait tCCS_min if it is correctly defined, otherwise wait 500ns
* (which should be safe for all NANDs).
*/
- if (chip->setup_data_interface)
+ if (nand_has_setup_data_iface(chip))
ndelay(chip->data_interface.timings.sdr.tCCS_min / 1000);
else
ndelay(500);
diff --git a/drivers/mtd/nand/raw/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c
index a8905463701a..adc7a196e383 100644
--- a/drivers/mtd/nand/raw/s3c2410.c
+++ b/drivers/mtd/nand/raw/s3c2410.c
@@ -876,8 +876,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
* let's keep behavior unchanged for legacy boards booting via pdata and
* auto-detect timings only when booting with a device tree.
*/
- if (np)
- chip->setup_data_interface = s3c2410_nand_setup_data_interface;
+ if (!np)
+ chip->options |= NAND_KEEP_TIMINGS;

switch (info->cpu_type) {
case TYPE_S3C2410:
@@ -1011,6 +1011,7 @@ static int s3c2410_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops s3c24xx_nand_controller_ops = {
.attach_chip = s3c2410_nand_attach_chip,
+ .setup_data_interface = s3c2410_nand_setup_data_interface,
};

static const struct of_device_id s3c24xx_nand_dt_ids[] = {
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index e489a6ff57d7..a5c83cbe4897 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1847,6 +1847,7 @@ static int sunxi_nand_attach_chip(struct nand_chip *nand)

static const struct nand_controller_ops sunxi_nand_controller_ops = {
.attach_chip = sunxi_nand_attach_chip,
+ .setup_data_interface = sunxi_nfc_setup_data_interface,
};

static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
@@ -1927,7 +1928,6 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
nand->legacy.read_buf = sunxi_nfc_read_buf;
nand->legacy.write_buf = sunxi_nfc_write_buf;
nand->legacy.read_byte = sunxi_nfc_read_byte;
- nand->setup_data_interface = sunxi_nfc_setup_data_interface;

mtd = nand_to_mtd(nand);
mtd->dev.parent = dev;
diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c
index ebca4579c033..cb3beda88789 100644
--- a/drivers/mtd/nand/raw/tango_nand.c
+++ b/drivers/mtd/nand/raw/tango_nand.c
@@ -530,6 +530,7 @@ static int tango_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops tango_controller_ops = {
.attach_chip = tango_attach_chip,
+ .setup_data_interface = tango_set_timings,
};

static int chip_init(struct device *dev, struct device_node *np)
@@ -570,7 +571,6 @@ static int chip_init(struct device *dev, struct device_node *np)
chip->legacy.select_chip = tango_select_chip;
chip->legacy.cmd_ctrl = tango_cmd_ctrl;
chip->legacy.dev_ready = tango_dev_ready;
- chip->setup_data_interface = tango_set_timings;
chip->options = NAND_USE_BOUNCE_BUFFER |
NAND_NO_SUBPAGE_WRITE |
NAND_WAIT_TCCS;
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 2fe6de09f4ff..13be32c38194 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -1051,6 +1051,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)
static const struct nand_controller_ops tegra_nand_controller_ops = {
.attach_chip = &tegra_nand_attach_chip,
.exec_op = tegra_nand_exec_op,
+ .setup_data_interface = tegra_nand_setup_data_interface,
};

static int tegra_nand_chips_init(struct device *dev,
@@ -1113,7 +1114,6 @@ static int tegra_nand_chips_init(struct device *dev,
mtd->name = "tegra_nand";

chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
- chip->setup_data_interface = tegra_nand_setup_data_interface;

ret = nand_scan(chip, 1);
if (ret)
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 297b40c56403..f50f40643895 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -203,6 +203,13 @@ enum nand_ecc_algo {
*/
#define NAND_IS_BOOT_MEDIUM 0x00400000

+/*
+ * Do not try to tweak the timings at runtime. This is needed when the
+ * controller initializes the timings on itself or when it relies on
+ * configuration done by the bootloader.
+ */
+#define NAND_KEEP_TIMINGS 0x00800000
+
/* Cell info constants */
#define NAND_CI_CHIPNR_MSK 0x03
#define NAND_CI_CELLTYPE_MSK 0x0C
@@ -871,6 +878,11 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
* This method replaces chip->legacy.cmdfunc(),
* chip->legacy.{read,write}_{buf,byte,word}(),
* chip->legacy.dev_ready() and chip->legacy.waifunc().
+ * @setup_data_interface: setup the data interface and timing. If
+ * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
+ * means the configuration should not be applied but
+ * only checked.
+ * This hook is optional.
*/
struct nand_controller_ops {
int (*attach_chip)(struct nand_chip *chip);
@@ -878,6 +890,8 @@ struct nand_controller_ops {
int (*exec_op)(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only);
+ int (*setup_data_interface)(struct nand_chip *chip, int chipnr,
+ const struct nand_data_interface *conf);
};

/**
@@ -1019,10 +1033,6 @@ struct nand_legacy {
* cur_cs < numchips. NAND Controller drivers should not
* modify this value, but they're allowed to read it.
* @read_retries: [INTERN] the number of read retry modes supported
- * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
- * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
- * means the configuration should not be applied but
- * only checked.
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
* lookup.
@@ -1044,8 +1054,6 @@ struct nand_chip {
struct nand_legacy legacy;

int (*setup_read_retry)(struct nand_chip *chip, int retry_mode);
- int (*setup_data_interface)(struct nand_chip *chip, int chipnr,
- const struct nand_data_interface *conf);

unsigned int options;
unsigned int bbt_options;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:22 UTC
Permalink
Now that the CS line to be selected is passed to ->exec_op() and
stored in chip->cur_cs and after patching all drivers implementing
->exec_op() to stop implementing this method, we can deprecate it by
moving it to the nand_legacy structure.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/atmel/nand-controller.c | 4 ++--
drivers/mtd/nand/raw/au1550nd.c | 2 +-
drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c | 2 +-
drivers/mtd/nand/raw/cafe_nand.c | 2 +-
drivers/mtd/nand/raw/davinci_nand.c | 2 +-
drivers/mtd/nand/raw/denali.c | 2 +-
drivers/mtd/nand/raw/diskonchip.c | 4 ++--
drivers/mtd/nand/raw/fsl_elbc_nand.c | 2 +-
drivers/mtd/nand/raw/fsl_ifc_nand.c | 2 +-
drivers/mtd/nand/raw/fsl_upm.c | 2 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 2 +-
drivers/mtd/nand/raw/hisi504_nand.c | 2 +-
drivers/mtd/nand/raw/jz4740_nand.c | 2 +-
drivers/mtd/nand/raw/jz4780_nand.c | 2 +-
drivers/mtd/nand/raw/mpc5121_nfc.c | 4 ++--
drivers/mtd/nand/raw/mtk_nand.c | 2 +-
drivers/mtd/nand/raw/mxc_nand.c | 2 +-
drivers/mtd/nand/raw/nand_base.c | 8 ++++----
drivers/mtd/nand/raw/nand_legacy.c | 9 +++++----
drivers/mtd/nand/raw/ndfc.c | 2 +-
drivers/mtd/nand/raw/plat_nand.c | 2 +-
drivers/mtd/nand/raw/qcom_nandc.c | 2 +-
drivers/mtd/nand/raw/s3c2410.c | 2 +-
drivers/mtd/nand/raw/sh_flctl.c | 2 +-
drivers/mtd/nand/raw/sunxi_nand.c | 2 +-
drivers/mtd/nand/raw/tango_nand.c | 2 +-
drivers/mtd/nand/raw/xway_nand.c | 2 +-
include/linux/mtd/rawnand.h | 4 ++--
28 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index fb33f6be7c4f..d5c58eb040d8 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1477,7 +1477,7 @@ static void atmel_nand_init(struct atmel_nand_controller *nc,
chip->legacy.write_byte = atmel_nand_write_byte;
chip->legacy.read_buf = atmel_nand_read_buf;
chip->legacy.write_buf = atmel_nand_write_buf;
- chip->select_chip = atmel_nand_select_chip;
+ chip->legacy.select_chip = atmel_nand_select_chip;

if (nc->mck && nc->caps->ops->setup_data_interface)
chip->setup_data_interface = atmel_nand_setup_data_interface;
@@ -1525,7 +1525,7 @@ static void atmel_hsmc_nand_init(struct atmel_nand_controller *nc,

/* Overload some methods for the HSMC controller. */
chip->legacy.cmd_ctrl = atmel_hsmc_nand_cmd_ctrl;
- chip->select_chip = atmel_hsmc_nand_select_chip;
+ chip->legacy.select_chip = atmel_hsmc_nand_select_chip;
}

static int atmel_nand_controller_remove_nand(struct atmel_nand *nand)
diff --git a/drivers/mtd/nand/raw/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c
index 9731c1c487f6..a963002663ed 100644
--- a/drivers/mtd/nand/raw/au1550nd.c
+++ b/drivers/mtd/nand/raw/au1550nd.c
@@ -430,7 +430,7 @@ static int au1550nd_probe(struct platform_device *pdev)
ctx->cs = cs;

this->legacy.dev_ready = au1550_device_ready;
- this->select_chip = au1550_select_chip;
+ this->legacy.select_chip = au1550_select_chip;
this->legacy.cmdfunc = au1550_command;

/* 30 us command delay time */
diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
index 9095a79ebc7d..a37cbfe56567 100644
--- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
@@ -383,7 +383,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
u8 tbits, col_bits, col_size, row_bits, row_bsize;
u32 val;

- b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
+ nand_chip->legacy.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
nand_chip->legacy.cmd_ctrl = bcm47xxnflash_ops_bcm4706_cmd_ctrl;
nand_chip->legacy.dev_ready = bcm47xxnflash_ops_bcm4706_dev_ready;
b47n->nand_chip.legacy.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc;
diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index c1a745940d12..a85f5fa5c66d 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -708,7 +708,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
cafe->nand.legacy.read_byte = cafe_read_byte;
cafe->nand.legacy.read_buf = cafe_read_buf;
cafe->nand.legacy.write_buf = cafe_write_buf;
- cafe->nand.select_chip = cafe_select_chip;
+ cafe->nand.legacy.select_chip = cafe_select_chip;
cafe->nand.legacy.set_features = nand_get_set_features_notsupp;
cafe->nand.legacy.get_features = nand_get_set_features_notsupp;

diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c
index 80f228d23cd2..f430aeb917e8 100644
--- a/drivers/mtd/nand/raw/davinci_nand.c
+++ b/drivers/mtd/nand/raw/davinci_nand.c
@@ -762,7 +762,7 @@ static int nand_davinci_probe(struct platform_device *pdev)
info->chip.legacy.IO_ADDR_R = vaddr;
info->chip.legacy.IO_ADDR_W = vaddr;
info->chip.legacy.chip_delay = 0;
- info->chip.select_chip = nand_davinci_select_chip;
+ info->chip.legacy.select_chip = nand_davinci_select_chip;

/* options such as NAND_BBT_USE_FLASH */
info->chip.bbt_options = pdata->bbt_options;
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 830ea247277b..64895ca68c8d 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1355,7 +1355,7 @@ int denali_init(struct denali_nand_info *denali)
if (!mtd->name)
mtd->name = "denali-nand";

- chip->select_chip = denali_select_chip;
+ chip->legacy.select_chip = denali_select_chip;
chip->legacy.read_byte = denali_read_byte;
chip->legacy.write_byte = denali_write_byte;
chip->legacy.cmd_ctrl = denali_cmd_ctrl;
diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
index 3a4c373affab..53f57e0f007e 100644
--- a/drivers/mtd/nand/raw/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -1390,7 +1390,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
this->legacy.read_buf = doc2001plus_readbuf;
doc->late_init = inftl_scan_bbt;
this->legacy.cmd_ctrl = NULL;
- this->select_chip = doc2001plus_select_chip;
+ this->legacy.select_chip = doc2001plus_select_chip;
this->legacy.cmdfunc = doc2001plus_command;
this->ecc.hwctl = doc2001plus_enable_hwecc;

@@ -1568,7 +1568,7 @@ static int __init doc_probe(unsigned long physadr)
mtd_set_ooblayout(mtd, &doc200x_ooblayout_ops);

nand_set_controller_data(nand, doc);
- nand->select_chip = doc200x_select_chip;
+ nand->legacy.select_chip = doc200x_select_chip;
nand->legacy.cmd_ctrl = doc200x_hwcontrol;
nand->legacy.dev_ready = doc200x_dev_ready;
nand->legacy.waitfunc = doc200x_wait;
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index d6ed697fcfe6..70f0d2b450ea 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -779,7 +779,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->legacy.read_byte = fsl_elbc_read_byte;
chip->legacy.write_buf = fsl_elbc_write_buf;
chip->legacy.read_buf = fsl_elbc_read_buf;
- chip->select_chip = fsl_elbc_select_chip;
+ chip->legacy.select_chip = fsl_elbc_select_chip;
chip->legacy.cmdfunc = fsl_elbc_cmdfunc;
chip->legacy.waitfunc = fsl_elbc_wait;
chip->legacy.set_features = nand_get_set_features_notsupp;
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index 6f4afc44381a..e65d274399f9 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -864,7 +864,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)

chip->legacy.write_buf = fsl_ifc_write_buf;
chip->legacy.read_buf = fsl_ifc_read_buf;
- chip->select_chip = fsl_ifc_select_chip;
+ chip->legacy.select_chip = fsl_ifc_select_chip;
chip->legacy.cmdfunc = fsl_ifc_cmdfunc;
chip->legacy.waitfunc = fsl_ifc_wait;
chip->legacy.set_features = nand_get_set_features_notsupp;
diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c
index 673c5a0c9345..5ccc28ec0985 100644
--- a/drivers/mtd/nand/raw/fsl_upm.c
+++ b/drivers/mtd/nand/raw/fsl_upm.c
@@ -170,7 +170,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun,
fun->chip.ecc.mode = NAND_ECC_SOFT;
fun->chip.ecc.algo = NAND_ECC_HAMMING;
if (fun->mchip_count > 1)
- fun->chip.select_chip = fun_select_chip;
+ fun->chip.legacy.select_chip = fun_select_chip;

if (fun->rnb_gpio[0] >= 0)
fun->chip.legacy.dev_ready = fun_chip_ready;
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 302ddd3d4a5f..c461d5efabc0 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1907,7 +1907,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
/* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */
nand_set_controller_data(chip, this);
nand_set_flash_node(chip, this->pdev->dev.of_node);
- chip->select_chip = gpmi_select_chip;
+ chip->legacy.select_chip = gpmi_select_chip;
chip->setup_data_interface = gpmi_setup_data_interface;
chip->legacy.cmd_ctrl = gpmi_cmd_ctrl;
chip->legacy.dev_ready = gpmi_dev_ready;
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index f043938ee36b..e41c13499fd5 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -783,7 +783,7 @@ static int hisi_nfc_probe(struct platform_device *pdev)
nand_set_controller_data(chip, host);
nand_set_flash_node(chip, np);
chip->legacy.cmdfunc = hisi_nfc_cmdfunc;
- chip->select_chip = hisi_nfc_select_chip;
+ chip->legacy.select_chip = hisi_nfc_select_chip;
chip->legacy.read_byte = hisi_nfc_read_byte;
chip->legacy.write_buf = hisi_nfc_write_buf;
chip->legacy.read_buf = hisi_nfc_read_buf;
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index d271004f16b0..0bcfdd3d66a8 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -427,7 +427,7 @@ static int jz_nand_probe(struct platform_device *pdev)

chip->legacy.chip_delay = 50;
chip->legacy.cmd_ctrl = jz_nand_cmd_ctrl;
- chip->select_chip = jz_nand_select_chip;
+ chip->legacy.select_chip = jz_nand_select_chip;
chip->dummy_controller.ops = &jz_nand_controller_ops;

if (nand->busy_gpio)
diff --git a/drivers/mtd/nand/raw/jz4780_nand.c b/drivers/mtd/nand/raw/jz4780_nand.c
index cdf22100ab77..22e58975f0d5 100644
--- a/drivers/mtd/nand/raw/jz4780_nand.c
+++ b/drivers/mtd/nand/raw/jz4780_nand.c
@@ -279,7 +279,7 @@ static int jz4780_nand_init_chip(struct platform_device *pdev,
chip->legacy.IO_ADDR_W = cs->base + OFFSET_DATA;
chip->legacy.chip_delay = RB_DELAY_US;
chip->options = NAND_NO_SUBPAGE_WRITE;
- chip->select_chip = jz4780_nand_select_chip;
+ chip->legacy.select_chip = jz4780_nand_select_chip;
chip->legacy.cmd_ctrl = jz4780_nand_cmd_ctrl;
chip->ecc.mode = NAND_ECC_HW;
chip->controller = &nfc->controller;
diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c
index 86a0aabe08df..062cd1eb2861 100644
--- a/drivers/mtd/nand/raw/mpc5121_nfc.c
+++ b/drivers/mtd/nand/raw/mpc5121_nfc.c
@@ -697,7 +697,7 @@ static int mpc5121_nfc_probe(struct platform_device *op)
chip->legacy.read_byte = mpc5121_nfc_read_byte;
chip->legacy.read_buf = mpc5121_nfc_read_buf;
chip->legacy.write_buf = mpc5121_nfc_write_buf;
- chip->select_chip = mpc5121_nfc_select_chip;
+ chip->legacy.select_chip = mpc5121_nfc_select_chip;
chip->legacy.set_features = nand_get_set_features_notsupp;
chip->legacy.get_features = nand_get_set_features_notsupp;
chip->bbt_options = NAND_BBT_USE_FLASH;
@@ -712,7 +712,7 @@ static int mpc5121_nfc_probe(struct platform_device *op)
return retval;
}

- chip->select_chip = ads5121_select_chip;
+ chip->legacy.select_chip = ads5121_select_chip;
}

/* Enable NFC clock */
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 2bb0df1b7244..ce124f8c02cd 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1333,7 +1333,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,

nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ;
nand->legacy.dev_ready = mtk_nfc_dev_ready;
- nand->select_chip = mtk_nfc_select_chip;
+ nand->legacy.select_chip = mtk_nfc_select_chip;
nand->legacy.write_byte = mtk_nfc_write_byte;
nand->legacy.write_buf = mtk_nfc_write_buf;
nand->legacy.read_byte = mtk_nfc_read_byte;
diff --git a/drivers/mtd/nand/raw/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c
index 88bd3f6a499c..c00b1d408a04 100644
--- a/drivers/mtd/nand/raw/mxc_nand.c
+++ b/drivers/mtd/nand/raw/mxc_nand.c
@@ -1828,7 +1828,7 @@ static int mxcnd_probe(struct platform_device *pdev)
this->ecc.bytes = host->devtype_data->eccbytes;
host->eccsize = host->devtype_data->eccsize;

- this->select_chip = host->devtype_data->select_chip;
+ this->legacy.select_chip = host->devtype_data->select_chip;
this->ecc.size = 512;
mtd_set_ooblayout(mtd, host->devtype_data->ooblayout);

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 93a19f551796..cef6633fdce9 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -248,8 +248,8 @@ void nand_select_target(struct nand_chip *chip, unsigned int cs)

chip->cur_cs = cs;

- if (chip->select_chip)
- chip->select_chip(chip, cs);
+ if (chip->legacy.select_chip)
+ chip->legacy.select_chip(chip, cs);
}
EXPORT_SYMBOL_GPL(nand_select_target);

@@ -262,8 +262,8 @@ EXPORT_SYMBOL_GPL(nand_select_target);
*/
void nand_deselect_target(struct nand_chip *chip)
{
- if (chip->select_chip)
- chip->select_chip(chip, -1);
+ if (chip->legacy.select_chip)
+ chip->legacy.select_chip(chip, -1);

chip->cur_cs = -1;
}
diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index f76b9356ba9c..4596a538b967 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -592,8 +592,8 @@ void nand_legacy_set_defaults(struct nand_chip *chip)
if (chip->legacy.waitfunc == NULL)
chip->legacy.waitfunc = nand_wait;

- if (!chip->select_chip)
- chip->select_chip = nand_select_chip;
+ if (!chip->legacy.select_chip)
+ chip->legacy.select_chip = nand_select_chip;

/* If called twice, pointers that depend on busw may need to be reset */
if (!chip->legacy.read_byte || chip->legacy.read_byte == nand_read_byte)
@@ -626,9 +626,10 @@ int nand_legacy_check_hooks(struct nand_chip *chip)

/*
* Default functions assigned for ->legacy.cmdfunc() and
- * ->select_chip() both expect ->legacy.cmd_ctrl() to be populated.
+ * ->legacy.select_chip() both expect ->legacy.cmd_ctrl() to be
+ * populated.
*/
- if ((!chip->legacy.cmdfunc || !chip->select_chip) &&
+ if ((!chip->legacy.cmdfunc || !chip->legacy.select_chip) &&
!chip->legacy.cmd_ctrl) {
pr_err("->legacy.cmd_ctrl() should be provided\n");
return -EINVAL;
diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index d49a7a17146c..9857e0e5acd4 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -146,7 +146,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
chip->legacy.IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
chip->legacy.cmd_ctrl = ndfc_hwcontrol;
chip->legacy.dev_ready = ndfc_ready;
- chip->select_chip = ndfc_select_chip;
+ chip->legacy.select_chip = ndfc_select_chip;
chip->legacy.chip_delay = 50;
chip->controller = &ndfc->ndfc_control;
chip->legacy.read_buf = ndfc_read_buf;
diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
index 86c536ddaf24..a994b76daa50 100644
--- a/drivers/mtd/nand/raw/plat_nand.c
+++ b/drivers/mtd/nand/raw/plat_nand.c
@@ -63,7 +63,7 @@ static int plat_nand_probe(struct platform_device *pdev)
data->chip.legacy.IO_ADDR_W = data->io_base;
data->chip.legacy.cmd_ctrl = pdata->ctrl.cmd_ctrl;
data->chip.legacy.dev_ready = pdata->ctrl.dev_ready;
- data->chip.select_chip = pdata->ctrl.select_chip;
+ data->chip.legacy.select_chip = pdata->ctrl.select_chip;
data->chip.legacy.write_buf = pdata->ctrl.write_buf;
data->chip.legacy.read_buf = pdata->ctrl.read_buf;
data->chip.legacy.chip_delay = pdata->chip.chip_delay;
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index ef75dfa62a4f..6b76fb5c0aed 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2804,7 +2804,7 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
mtd->dev.parent = dev;

chip->legacy.cmdfunc = qcom_nandc_command;
- chip->select_chip = qcom_nandc_select_chip;
+ chip->legacy.select_chip = qcom_nandc_select_chip;
chip->legacy.read_byte = qcom_nandc_read_byte;
chip->legacy.read_buf = qcom_nandc_read_buf;
chip->legacy.write_buf = qcom_nandc_write_buf;
diff --git a/drivers/mtd/nand/raw/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c
index d2e42e9d0e8c..a8905463701a 100644
--- a/drivers/mtd/nand/raw/s3c2410.c
+++ b/drivers/mtd/nand/raw/s3c2410.c
@@ -866,7 +866,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,

chip->legacy.write_buf = s3c2410_nand_write_buf;
chip->legacy.read_buf = s3c2410_nand_read_buf;
- chip->select_chip = s3c2410_nand_select_chip;
+ chip->legacy.select_chip = s3c2410_nand_select_chip;
chip->legacy.chip_delay = 50;
nand_set_controller_data(chip, nmtd);
chip->options = set->options;
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index 4d20d033de7b..8c538e6c4926 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -1183,7 +1183,7 @@ static int flctl_probe(struct platform_device *pdev)
nand->legacy.read_byte = flctl_read_byte;
nand->legacy.write_buf = flctl_write_buf;
nand->legacy.read_buf = flctl_read_buf;
- nand->select_chip = flctl_select_chip;
+ nand->legacy.select_chip = flctl_select_chip;
nand->legacy.cmdfunc = flctl_cmdfunc;
nand->legacy.set_features = nand_get_set_features_notsupp;
nand->legacy.get_features = nand_get_set_features_notsupp;
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index 51b1a548064b..e489a6ff57d7 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1922,7 +1922,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
*/
nand->ecc.mode = NAND_ECC_HW;
nand_set_flash_node(nand, np);
- nand->select_chip = sunxi_nfc_select_chip;
+ nand->legacy.select_chip = sunxi_nfc_select_chip;
nand->legacy.cmd_ctrl = sunxi_nfc_cmd_ctrl;
nand->legacy.read_buf = sunxi_nfc_read_buf;
nand->legacy.write_buf = sunxi_nfc_write_buf;
diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c
index 8818f893f300..ebca4579c033 100644
--- a/drivers/mtd/nand/raw/tango_nand.c
+++ b/drivers/mtd/nand/raw/tango_nand.c
@@ -567,7 +567,7 @@ static int chip_init(struct device *dev, struct device_node *np)
chip->legacy.read_byte = tango_read_byte;
chip->legacy.write_buf = tango_write_buf;
chip->legacy.read_buf = tango_read_buf;
- chip->select_chip = tango_select_chip;
+ chip->legacy.select_chip = tango_select_chip;
chip->legacy.cmd_ctrl = tango_cmd_ctrl;
chip->legacy.dev_ready = tango_dev_ready;
chip->setup_data_interface = tango_set_timings;
diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index a234a5cb4868..4cb78106af14 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -176,7 +176,7 @@ static int xway_nand_probe(struct platform_device *pdev)

data->chip.legacy.cmd_ctrl = xway_cmd_ctrl;
data->chip.legacy.dev_ready = xway_dev_ready;
- data->chip.select_chip = xway_select_chip;
+ data->chip.legacy.select_chip = xway_select_chip;
data->chip.legacy.write_buf = xway_write_buf;
data->chip.legacy.read_buf = xway_read_buf;
data->chip.legacy.read_byte = xway_read_byte;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index aa1512df38a9..40b74fb1792d 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -902,6 +902,7 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
* struct nand_legacy - NAND chip legacy fields/hooks
* @IO_ADDR_R: address to read the 8 I/O lines of the flash device
* @IO_ADDR_W: address to write the 8 I/O lines of the flash device
+ * @select_chip: select/deselect a specific target/die
* @read_byte: read one byte from the chip
* @write_byte: write a single byte to the chip on the low 8 I/O lines
* @write_buf: write data from the buffer to the chip
@@ -927,6 +928,7 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
struct nand_legacy {
void __iomem *IO_ADDR_R;
void __iomem *IO_ADDR_W;
+ void (*select_chip)(struct nand_chip *chip, int cs);
u8 (*read_byte)(struct nand_chip *chip);
void (*write_byte)(struct nand_chip *chip, u8 byte);
void (*write_buf)(struct nand_chip *chip, const u8 *buf, int len);
@@ -954,7 +956,6 @@ struct nand_legacy {
* you're modifying an existing driver that is using those
* fields/hooks, you should consider reworking the driver
* avoid using them.
- * @select_chip: [REPLACEABLE] select chip nr
* @exec_op: controller specific method to execute NAND operations.
* This method replaces ->cmdfunc(),
* ->legacy.{read,write}_{buf,byte,word}(),
@@ -1040,7 +1041,6 @@ struct nand_chip {

struct nand_legacy legacy;

- void (*select_chip)(struct nand_chip *chip, int cs);
int (*exec_op)(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only);
--
2.17.1
Boris Brezillon
2018-11-11 07:55:17 UTC
Permalink
Now that the CS line to assert is directly passed through the
nand_operation struct we can replace the fsmc_select_chip()
implementation by an internal fsmc_ce_ctrl() function which is
directly called from fsmc_exec_op()

Signed-off-by: Boris Brezillon <***@bootlin.com>
---
Changes in v3:
- None

Changes in v2:
- None
---
drivers/mtd/nand/raw/fsmc_nand.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
index 41ba76efd6c8..ea69ac6e6d7a 100644
--- a/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -609,22 +609,19 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
}

/* fsmc_select_chip - assert or deassert nCE */
-static void fsmc_select_chip(struct nand_chip *chip, int chipnr)
+static void fsmc_ce_ctrl(struct fsmc_nand_data *host, bool assert)
{
- struct fsmc_nand_data *host = mtd_to_fsmc(nand_to_mtd(chip));
- u32 pc;
-
- /* Support only one CS */
- if (chipnr > 0)
- return;
+ u32 pc = readl(host->regs_va + FSMC_PC);

- pc = readl(host->regs_va + FSMC_PC);
- if (chipnr < 0)
+ if (!assert)
writel_relaxed(pc & ~FSMC_ENABLE, host->regs_va + FSMC_PC);
else
writel_relaxed(pc | FSMC_ENABLE, host->regs_va + FSMC_PC);

- /* nCE line must be asserted before starting any operation */
+ /*
+ * nCE line changes must be applied before returning from this
+ * function.
+ */
mb();
}

@@ -645,6 +642,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
int i;

pr_debug("Executing operation [%d instructions]:\n", op->ninstrs);
+
+ fsmc_ce_ctrl(host, true);
+
for (op_id = 0; op_id < op->ninstrs; op_id++) {
instr = &op->instrs[op_id];

@@ -701,6 +701,8 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
}
}

+ fsmc_ce_ctrl(host, false);
+
return ret;
}

@@ -1081,7 +1083,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)

mtd->dev.parent = &pdev->dev;
nand->exec_op = fsmc_exec_op;
- nand->select_chip = fsmc_select_chip;

/*
* Setup default ECC mode. nand_dt_init() called from nand_scan_ident()
--
2.17.1
Boris Brezillon
2018-11-11 07:55:19 UTC
Permalink
Now that the CS to be selected is kept in chip->cur_cs and passed
in nand_operation->cs, we can get rid of the ->select_chip()
implementation and replace it by an internal function which is called
from the chip->exec_op() and chip->ecc.read/write_xxx() hooks.

Signed-off-by: Boris Brezillon <***@bootlin.com>
---
Changes in v3:
- None

Changes in v2:
- None
---
drivers/mtd/nand/raw/tegra_nand.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 9767e29d74e2..590393d93ffc 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -454,29 +454,24 @@ static const struct nand_op_parser tegra_nand_op_parser = NAND_OP_PARSER(
NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 4)),
);

+static void tegra_nand_select_target(struct nand_chip *chip,
+ unsigned int die_nr)
+{
+ struct tegra_nand_chip *nand = to_tegra_chip(chip);
+ struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller);
+
+ ctrl->cur_cs = nand->cs[die_nr];
+}
+
static int tegra_nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
+ tegra_nand_select_target(chip, op->cs);
return nand_op_parser_exec_op(chip, &tegra_nand_op_parser, op,
check_only);
}

-static void tegra_nand_select_chip(struct nand_chip *chip, int die_nr)
-{
- struct tegra_nand_chip *nand = to_tegra_chip(chip);
- struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller);
-
- WARN_ON(die_nr >= (int)ARRAY_SIZE(nand->cs));
-
- if (die_nr < 0 || die_nr > 0) {
- ctrl->cur_cs = -1;
- return;
- }
-
- ctrl->cur_cs = nand->cs[die_nr];
-}
-
static void tegra_nand_hw_ecc(struct tegra_nand_controller *ctrl,
struct nand_chip *chip, bool enable)
{
@@ -503,6 +498,8 @@ static int tegra_nand_page_xfer(struct mtd_info *mtd, struct nand_chip *chip,
u32 addr1, cmd, dma_ctrl;
int ret;

+ tegra_nand_select_target(chip, chip->cur_cs);
+
if (read) {
writel_relaxed(NAND_CMD_READ0, ctrl->regs + CMD_REG1);
writel_relaxed(NAND_CMD_READSTART, ctrl->regs + CMD_REG2);
@@ -1116,7 +1113,6 @@ static int tegra_nand_chips_init(struct device *dev,

chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
chip->exec_op = tegra_nand_exec_op;
- chip->select_chip = tegra_nand_select_chip;
chip->setup_data_interface = tegra_nand_setup_data_interface;

ret = nand_scan(chip, 1);
--
2.17.1
Boris Brezillon
2018-11-11 07:55:10 UTC
Permalink
Most of them were reported by checkpatch:

* s/u_char/u8/
* remove unneeded blank lines
* don't print warning messages when devm_kzalloc() fails
* Use ! instead of == NULL
* Remove invalid comment

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2
- New patch
---
drivers/mtd/nand/raw/ams-delta.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 4862d4df1a15..07ee513318ec 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -28,7 +28,6 @@
/*
* MTD structure for E3 (Delta)
*/
-
struct ams_delta_nand {
struct nand_chip nand_chip;
struct gpio_desc *gpiod_rdy;
@@ -67,7 +66,7 @@ static const struct mtd_partition partition_info[] = {
.size = 3 * SZ_256K },
};

-static void ams_delta_io_write(struct ams_delta_nand *priv, u_char byte)
+static void ams_delta_io_write(struct ams_delta_nand *priv, u8 byte)
{
writew(byte, priv->io_base + OMAP_MPUIO_OUTPUT);
gpiod_set_value(priv->gpiod_nwe, 0);
@@ -75,9 +74,9 @@ static void ams_delta_io_write(struct ams_delta_nand *priv, u_char byte)
gpiod_set_value(priv->gpiod_nwe, 1);
}

-static u_char ams_delta_io_read(struct ams_delta_nand *priv)
+static u8 ams_delta_io_read(struct ams_delta_nand *priv)
{
- u_char res;
+ u8 res;

gpiod_set_value(priv->gpiod_nre, 0);
ndelay(40);
@@ -93,7 +92,7 @@ static void ams_delta_dir_input(struct ams_delta_nand *priv, bool in)
priv->data_in = in;
}

-static void ams_delta_write_buf(struct ams_delta_nand *priv, const u_char *buf,
+static void ams_delta_write_buf(struct ams_delta_nand *priv, const u8 *buf,
int len)
{
int i;
@@ -105,8 +104,7 @@ static void ams_delta_write_buf(struct ams_delta_nand *priv, const u_char *buf,
ams_delta_io_write(priv, buf[i]);
}

-static void ams_delta_read_buf(struct ams_delta_nand *priv, u_char *buf,
- int len)
+static void ams_delta_read_buf(struct ams_delta_nand *priv, u8 *buf, int len)
{
int i;

@@ -138,7 +136,6 @@ static int ams_delta_exec_op(struct nand_chip *this,
return 0;

for (instr = op->instrs; instr < op->instrs + op->ninstrs; instr++) {
-
switch (instr->type) {
case NAND_OP_CMD_INSTR:
gpiod_set_value(priv->gpiod_cle, 1);
@@ -179,7 +176,6 @@ static int ams_delta_exec_op(struct nand_chip *this,
return ret;
}

-
/*
* Main initialization routine
*/
@@ -198,10 +194,9 @@ static int ams_delta_init(struct platform_device *pdev)
/* Allocate memory for MTD device structure and private data */
priv = devm_kzalloc(&pdev->dev, sizeof(struct ams_delta_nand),
GFP_KERNEL);
- if (!priv) {
- pr_warn("Unable to allocate E3 NAND MTD device structure.\n");
+ if (!priv)
return -ENOMEM;
- }
+
this = &priv->nand_chip;

mtd = nand_to_mtd(this);
@@ -212,9 +207,8 @@ static int ams_delta_init(struct platform_device *pdev)
* it should have been already requested from the
* gpio-omap driver and requesting it again would fail.
*/
-
io_base = ioremap(res->start, resource_size(res));
- if (io_base == NULL) {
+ if (!io_base) {
dev_err(&pdev->dev, "ioremap failed\n");
err = -EIO;
goto out_free;
@@ -223,7 +217,6 @@ static int ams_delta_init(struct platform_device *pdev)
priv->io_base = io_base;
nand_set_controller_data(this, priv);

- /* Set address of NAND IO lines */
this->select_chip = ams_delta_select_chip;
this->exec_op = ams_delta_exec_op;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:21 UTC
Permalink
Now that the CS to be selected is passed in nand_operation->cs, we can
get rid of the ->select_chip() implementation and replace it by an
internal function which is called from the chip->exec_op() hook.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- New patch
---
drivers/mtd/nand/raw/ams-delta.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 34b83edb965c..611c822e967f 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -116,14 +116,9 @@ static void ams_delta_read_buf(struct ams_delta_nand *priv, u8 *buf, int len)
buf[i] = ams_delta_io_read(priv);
}

-static void ams_delta_select_chip(struct nand_chip *this, int n)
+static void ams_delta_ctrl_cs(struct ams_delta_nand *priv, bool assert)
{
- struct ams_delta_nand *priv = nand_get_controller_data(this);
-
- if (n > 0)
- return;
-
- gpiod_set_value(priv->gpiod_nce, n < 0);
+ gpiod_set_value(priv->gpiod_nce, assert ? 0 : 1);
}

static int ams_delta_exec_op(struct nand_chip *this,
@@ -136,6 +131,8 @@ static int ams_delta_exec_op(struct nand_chip *this,
if (check_only)
return 0;

+ ams_delta_ctrl_cs(priv, 1);
+
for (instr = op->instrs; instr < op->instrs + op->ninstrs; instr++) {
switch (instr->type) {
case NAND_OP_CMD_INSTR:
@@ -174,6 +171,8 @@ static int ams_delta_exec_op(struct nand_chip *this,
break;
}

+ ams_delta_ctrl_cs(priv, 0);
+
return ret;
}

@@ -217,7 +216,6 @@ static int ams_delta_init(struct platform_device *pdev)
priv->io_base = io_base;
nand_set_controller_data(this, priv);

- this->select_chip = ams_delta_select_chip;
this->exec_op = ams_delta_exec_op;

priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);
--
2.17.1
Boris Brezillon
2018-11-11 07:55:18 UTC
Permalink
Now that the CS to be selected is kept in chip->cur_cs and passed
in nand_operation->cs, we can get rid of the ->select_chip()
implementation and replace it by an internal function which is called
from the chip->exec_op() and chip->ecc.read/write_xxx() hooks.

Signed-off-by: Boris Brezillon <***@bootlin.com>
---
Changes in v3:
- None

Changes in v2:
- None
---
drivers/mtd/nand/raw/marvell_nand.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 650f2b490a05..ba7a45fb1905 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -704,7 +704,8 @@ static int marvell_nfc_wait_op(struct nand_chip *chip, unsigned int timeout_ms)
return 0;
}

-static void marvell_nfc_select_chip(struct nand_chip *chip, int die_nr)
+static void marvell_nfc_select_target(struct nand_chip *chip,
+ unsigned int die_nr)
{
struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
@@ -713,12 +714,6 @@ static void marvell_nfc_select_chip(struct nand_chip *chip, int die_nr)
if (chip == nfc->selected_chip && die_nr == marvell_nand->selected_die)
return;

- if (die_nr < 0 || die_nr >= marvell_nand->nsels) {
- nfc->selected_chip = NULL;
- marvell_nand->selected_die = -1;
- return;
- }
-
writel_relaxed(marvell_nand->ndtr0, nfc->regs + NDTR0);
writel_relaxed(marvell_nand->ndtr1, nfc->regs + NDTR1);

@@ -1024,13 +1019,13 @@ static int marvell_nfc_hw_ecc_hmg_do_read_page(struct nand_chip *chip,
}

ret = marvell_nfc_wait_cmdd(chip);
-
return ret;
}

static int marvell_nfc_hw_ecc_hmg_read_page_raw(struct nand_chip *chip, u8 *buf,
int oob_required, int page)
{
+ marvell_nfc_select_target(chip, chip->cur_cs);
return marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi,
true, page);
}
@@ -1043,6 +1038,7 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf,
int max_bitflips = 0, ret;
u8 *raw_buf;

+ marvell_nfc_select_target(chip, chip->cur_cs);
marvell_nfc_enable_hw_ecc(chip);
marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, false,
page);
@@ -1079,6 +1075,7 @@ static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct nand_chip *chip, int page)
/* Invalidate page cache */
chip->pagebuf = -1;

+ marvell_nfc_select_target(chip, chip->cur_cs);
return marvell_nfc_hw_ecc_hmg_do_read_page(chip, chip->data_buf,
chip->oob_poi, true, page);
}
@@ -1142,6 +1139,7 @@ static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
const u8 *buf,
int oob_required, int page)
{
+ marvell_nfc_select_target(chip, chip->cur_cs);
return marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
true, page);
}
@@ -1152,6 +1150,7 @@ static int marvell_nfc_hw_ecc_hmg_write_page(struct nand_chip *chip,
{
int ret;

+ marvell_nfc_select_target(chip, chip->cur_cs);
marvell_nfc_enable_hw_ecc(chip);
ret = marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
false, page);
@@ -1175,6 +1174,7 @@ static int marvell_nfc_hw_ecc_hmg_write_oob_raw(struct nand_chip *chip,

memset(chip->data_buf, 0xFF, mtd->writesize);

+ marvell_nfc_select_target(chip, chip->cur_cs);
return marvell_nfc_hw_ecc_hmg_do_write_page(chip, chip->data_buf,
chip->oob_poi, true, page);
}
@@ -1194,6 +1194,8 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf,
int ecc_len = lt->ecc_bytes;
int chunk;

+ marvell_nfc_select_target(chip, chip->cur_cs);
+
if (oob_required)
memset(chip->oob_poi, 0xFF, mtd->oobsize);

@@ -1304,6 +1306,8 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip,
u32 failure_mask = 0;
int chunk, ret;

+ marvell_nfc_select_target(chip, chip->cur_cs);
+
/*
* With BCH, OOB is not fully used (and thus not read entirely), not
* expected bytes could show up at the end of the OOB buffer if not
@@ -1448,6 +1452,8 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct nand_chip *chip,
lt->last_spare_bytes;
int chunk;

+ marvell_nfc_select_target(chip, chip->cur_cs);
+
nand_prog_page_begin_op(chip, page, 0, NULL, 0);

for (chunk = 0; chunk < lt->nchunks; chunk++) {
@@ -1559,6 +1565,8 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
int spare_len = lt->spare_bytes;
int chunk, ret;

+ marvell_nfc_select_target(chip, chip->cur_cs);
+
/* Spare data will be written anyway, so clear it to avoid garbage */
if (!oob_required)
memset(chip->oob_poi, 0xFF, mtd->oobsize);
@@ -2097,6 +2105,8 @@ static int marvell_nfc_exec_op(struct nand_chip *chip,
{
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);

+ marvell_nfc_select_target(chip, op->cs);
+
if (nfc->caps->is_nfcv2)
return nand_op_parser_exec_op(chip, &marvell_nfcv2_op_parser,
op, check_only);
@@ -2618,7 +2628,6 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
nand_set_flash_node(chip, np);

chip->exec_op = marvell_nfc_exec_op;
- chip->select_chip = marvell_nfc_select_chip;
if (!of_property_read_bool(np, "marvell,nand-keep-config"))
chip->setup_data_interface = marvell_nfc_setup_data_interface;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:23 UTC
Permalink
->exec_op() is a controller method and has nothing to do in the
nand_chip struct. Let's move it to the nand_controller_ops struct and
adjust the core and drivers accordingly.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- Patch ams-delta
---
drivers/mtd/nand/raw/ams-delta.c | 7 +-
drivers/mtd/nand/raw/fsmc_nand.c | 2 +-
drivers/mtd/nand/raw/internals.h | 13 +++-
drivers/mtd/nand/raw/marvell_nand.c | 2 +-
drivers/mtd/nand/raw/nand_base.c | 38 +++++------
drivers/mtd/nand/raw/nand_hynix.c | 4 +-
drivers/mtd/nand/raw/nand_legacy.c | 4 +-
drivers/mtd/nand/raw/tegra_nand.c | 2 +-
drivers/mtd/nand/raw/vf610_nfc.c | 4 +-
include/linux/mtd/rawnand.h | 99 ++++++++++++++---------------
10 files changed, 93 insertions(+), 82 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 611c822e967f..f8eb4a419e77 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -176,6 +176,10 @@ static int ams_delta_exec_op(struct nand_chip *this,
return ret;
}

+static const struct nand_controller_ops ams_delta_ops = {
+ .exec_op = ams_delta_exec_op,
+};
+
/*
* Main initialization routine
*/
@@ -216,8 +220,6 @@ static int ams_delta_init(struct platform_device *pdev)
priv->io_base = io_base;
nand_set_controller_data(this, priv);

- this->exec_op = ams_delta_exec_op;
-
priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);
if (IS_ERR(priv->gpiod_rdy)) {
err = PTR_ERR(priv->gpiod_rdy);
@@ -277,6 +279,7 @@ static int ams_delta_init(struct platform_device *pdev)
ams_delta_dir_input(priv, true);

/* Initialize the NAND controller object embedded in ams_delta_nand. */
+ priv->base.ops = &ams_delta_ops;
nand_controller_init(&priv->base);
this->controller = &priv->base;

diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
index ea69ac6e6d7a..1eb5008e7453 100644
--- a/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -995,6 +995,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand)

static const struct nand_controller_ops fsmc_nand_controller_ops = {
.attach_chip = fsmc_nand_attach_chip,
+ .exec_op = fsmc_exec_op,
};

/*
@@ -1082,7 +1083,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
nand_set_flash_node(nand, pdev->dev.of_node);

mtd->dev.parent = &pdev->dev;
- nand->exec_op = fsmc_exec_op;

/*
* Setup default ECC mode. nand_dt_init() called from nand_scan_ident()
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index b62728d5884b..ac66b458566f 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -95,16 +95,25 @@ void nand_decode_ext_id(struct nand_chip *chip);
void panic_nand_wait(struct nand_chip *chip, unsigned long timeo);
void sanitize_string(uint8_t *s, size_t len);

+static inline bool nand_has_exec_op(struct nand_chip *chip)
+{
+ if (!chip->controller || !chip->controller->ops ||
+ !chip->controller->ops->exec_op)
+ return false;
+
+ return true;
+}
+
static inline int nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op)
{
- if (!chip->exec_op)
+ if (!nand_has_exec_op(chip))
return -ENOTSUPP;

if (WARN_ON(op->cs >= chip->numchips))
return -EINVAL;

- return chip->exec_op(chip, op, false);
+ return chip->controller->ops->exec_op(chip, op, false);
}

/* BBT functions */
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index ba7a45fb1905..2e8257fe7d00 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -2505,6 +2505,7 @@ static int marvell_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops marvell_nand_controller_ops = {
.attach_chip = marvell_nand_attach_chip,
+ .exec_op = marvell_nfc_exec_op,
};

static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
@@ -2627,7 +2628,6 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
chip->controller = &nfc->controller;
nand_set_flash_node(chip, np);

- chip->exec_op = marvell_nfc_exec_op;
if (!of_property_read_bool(np, "marvell,nand-keep-config"))
chip->setup_data_interface = marvell_nfc_setup_data_interface;

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index cef6633fdce9..a62bbf22f135 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -678,7 +678,7 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
u8 status = 0;
int ret;

- if (!chip->exec_op)
+ if (!nand_has_exec_op(chip))
return -ENOTSUPP;

/* Wait tWB before polling the STATUS reg. */
@@ -1117,7 +1117,7 @@ int nand_read_page_op(struct nand_chip *chip, unsigned int page,
if (offset_in_page + len > mtd->writesize + mtd->oobsize)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
if (mtd->writesize > 512)
return nand_lp_exec_read_page_op(chip, page,
offset_in_page, buf,
@@ -1156,7 +1156,7 @@ int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
if (len && !buf)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1211,7 +1211,7 @@ int nand_change_read_column_op(struct nand_chip *chip,
if (mtd->writesize <= 512)
return -ENOTSUPP;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
u8 addrs[2] = {};
@@ -1270,7 +1270,7 @@ int nand_read_oob_op(struct nand_chip *chip, unsigned int page,
if (offset_in_oob + len > mtd->oobsize)
return -EINVAL;

- if (chip->exec_op)
+ if (nand_has_exec_op(chip))
return nand_read_page_op(chip, page,
mtd->writesize + offset_in_oob,
buf, len);
@@ -1383,7 +1383,7 @@ int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page,
if (offset_in_page + len > mtd->writesize + mtd->oobsize)
return -EINVAL;

- if (chip->exec_op)
+ if (nand_has_exec_op(chip))
return nand_exec_prog_page_op(chip, page, offset_in_page, buf,
len, false);

@@ -1410,7 +1410,7 @@ int nand_prog_page_end_op(struct nand_chip *chip)
int ret;
u8 status;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1469,7 +1469,7 @@ int nand_prog_page_op(struct nand_chip *chip, unsigned int page,
if (offset_in_page + len > mtd->writesize + mtd->oobsize)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
status = nand_exec_prog_page_op(chip, page, offset_in_page, buf,
len, true);
} else {
@@ -1517,7 +1517,7 @@ int nand_change_write_column_op(struct nand_chip *chip,
if (mtd->writesize <= 512)
return -ENOTSUPP;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
u8 addrs[2];
@@ -1572,7 +1572,7 @@ int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
if (len && !buf)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1611,7 +1611,7 @@ EXPORT_SYMBOL_GPL(nand_readid_op);
*/
int nand_status_op(struct nand_chip *chip, u8 *status)
{
- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1648,7 +1648,7 @@ EXPORT_SYMBOL_GPL(nand_status_op);
*/
int nand_exit_status_op(struct nand_chip *chip)
{
- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_CMD(NAND_CMD_READ0, 0),
};
@@ -1680,7 +1680,7 @@ int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock)
int ret;
u8 status;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
u8 addrs[3] = { page, page >> 8, page >> 16 };
@@ -1739,7 +1739,7 @@ static int nand_set_features_op(struct nand_chip *chip, u8 feature,
const u8 *params = data;
int i, ret;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1786,7 +1786,7 @@ static int nand_get_features_op(struct nand_chip *chip, u8 feature,
u8 *params = data;
int i;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1812,7 +1812,7 @@ static int nand_get_features_op(struct nand_chip *chip, u8 feature,
static int nand_wait_rdy_op(struct nand_chip *chip, unsigned int timeout_ms,
unsigned int delay_ns)
{
- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_WAIT_RDY(PSEC_TO_MSEC(timeout_ms),
PSEC_TO_NSEC(delay_ns)),
@@ -1843,7 +1843,7 @@ static int nand_wait_rdy_op(struct nand_chip *chip, unsigned int timeout_ms,
*/
int nand_reset_op(struct nand_chip *chip)
{
- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
const struct nand_sdr_timings *sdr =
nand_get_sdr_timings(&chip->data_interface);
struct nand_op_instr instrs[] = {
@@ -1880,7 +1880,7 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
if (!len || !buf)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_DATA_IN(len, buf, 0),
};
@@ -1924,7 +1924,7 @@ int nand_write_data_op(struct nand_chip *chip, const void *buf,
if (!len || !buf)
return -EINVAL;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_DATA_OUT(len, buf, 0),
};
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index 1e4499d01e14..343f477362d1 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -80,7 +80,7 @@ static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)

static int hynix_nand_cmd_op(struct nand_chip *chip, u8 cmd)
{
- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_CMD(cmd, 0),
};
@@ -98,7 +98,7 @@ static int hynix_nand_reg_write_op(struct nand_chip *chip, u8 addr, u8 val)
{
u16 column = ((u16)addr << 8) | addr;

- if (chip->exec_op) {
+ if (nand_has_exec_op(chip)) {
struct nand_op_instr instrs[] = {
NAND_OP_ADDR(1, &addr, 0),
NAND_OP_8BIT_DATA_OUT(1, &val, 0),
diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index 4596a538b967..47364237861e 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -577,7 +577,7 @@ void nand_legacy_set_defaults(struct nand_chip *chip)
{
unsigned int busw = chip->options & NAND_BUSWIDTH_16;

- if (chip->exec_op)
+ if (nand_has_exec_op(chip))
return;

/* check for proper chip_delay setup, set 20us if not */
@@ -621,7 +621,7 @@ int nand_legacy_check_hooks(struct nand_chip *chip)
* ->legacy.cmdfunc() is legacy and will only be used if ->exec_op() is
* not populated.
*/
- if (chip->exec_op)
+ if (nand_has_exec_op(chip))
return 0;

/*
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 590393d93ffc..2fe6de09f4ff 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -1050,6 +1050,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops tegra_nand_controller_ops = {
.attach_chip = &tegra_nand_attach_chip,
+ .exec_op = tegra_nand_exec_op,
};

static int tegra_nand_chips_init(struct device *dev,
@@ -1112,7 +1113,6 @@ static int tegra_nand_chips_init(struct device *dev,
mtd->name = "tegra_nand";

chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
- chip->exec_op = tegra_nand_exec_op;
chip->setup_data_interface = tegra_nand_setup_data_interface;

ret = nand_scan(chip, 1);
diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
index 49a174e30211..0fa7cac4ce14 100644
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -812,6 +812,8 @@ static int vf610_nfc_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops vf610_nfc_controller_ops = {
.attach_chip = vf610_nfc_attach_chip,
+ .exec_op = vf610_nfc_exec_op,
+
};

static int vf610_nfc_probe(struct platform_device *pdev)
@@ -879,8 +881,6 @@ static int vf610_nfc_probe(struct platform_device *pdev)
goto err_disable_clk;
}

- chip->exec_op = vf610_nfc_exec_op;
-
chip->options |= NAND_NO_SUBPAGE_WRITE;

init_completion(&nfc->cmd_done);
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 40b74fb1792d..297b40c56403 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -240,49 +240,6 @@ struct nand_id {
int len;
};

-/**
- * struct nand_controller_ops - Controller operations
- *
- * @attach_chip: this method is called after the NAND detection phase after
- * flash ID and MTD fields such as erase size, page size and OOB
- * size have been set up. ECC requirements are available if
- * provided by the NAND chip or device tree. Typically used to
- * choose the appropriate ECC configuration and allocate
- * associated resources.
- * This hook is optional.
- * @detach_chip: free all resources allocated/claimed in
- * nand_controller_ops->attach_chip().
- * This hook is optional.
- */
-struct nand_controller_ops {
- int (*attach_chip)(struct nand_chip *chip);
- void (*detach_chip)(struct nand_chip *chip);
-};
-
-/**
- * struct nand_controller - Structure used to describe a NAND controller
- *
- * @lock: protection lock
- * @active: the mtd device which holds the controller currently
- * @wq: wait queue to sleep on if a NAND operation is in
- * progress used instead of the per chip wait queue
- * when a hw controller is available.
- * @ops: NAND controller operations.
- */
-struct nand_controller {
- spinlock_t lock;
- struct nand_chip *active;
- wait_queue_head_t wq;
- const struct nand_controller_ops *ops;
-};
-
-static inline void nand_controller_init(struct nand_controller *nfc)
-{
- nfc->active = NULL;
- spin_lock_init(&nfc->lock);
- init_waitqueue_head(&nfc->wq);
-}
-
/**
* struct nand_ecc_step_info - ECC step information of ECC engine
* @stepsize: data bytes per ECC step
@@ -897,6 +854,55 @@ struct nand_operation {
int nand_op_parser_exec_op(struct nand_chip *chip,
const struct nand_op_parser *parser,
const struct nand_operation *op, bool check_only);
+/**
+ * struct nand_controller_ops - Controller operations
+ *
+ * @attach_chip: this method is called after the NAND detection phase after
+ * flash ID and MTD fields such as erase size, page size and OOB
+ * size have been set up. ECC requirements are available if
+ * provided by the NAND chip or device tree. Typically used to
+ * choose the appropriate ECC configuration and allocate
+ * associated resources.
+ * This hook is optional.
+ * @detach_chip: free all resources allocated/claimed in
+ * nand_controller_ops->attach_chip().
+ * This hook is optional.
+ * @exec_op: controller specific method to execute NAND operations.
+ * This method replaces chip->legacy.cmdfunc(),
+ * chip->legacy.{read,write}_{buf,byte,word}(),
+ * chip->legacy.dev_ready() and chip->legacy.waifunc().
+ */
+struct nand_controller_ops {
+ int (*attach_chip)(struct nand_chip *chip);
+ void (*detach_chip)(struct nand_chip *chip);
+ int (*exec_op)(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only);
+};
+
+/**
+ * struct nand_controller - Structure used to describe a NAND controller
+ *
+ * @lock: protection lock
+ * @active: the mtd device which holds the controller currently
+ * @wq: wait queue to sleep on if a NAND operation is in
+ * progress used instead of the per chip wait queue
+ * when a hw controller is available.
+ * @ops: NAND controller operations.
+ */
+struct nand_controller {
+ spinlock_t lock;
+ struct nand_chip *active;
+ wait_queue_head_t wq;
+ const struct nand_controller_ops *ops;
+};
+
+static inline void nand_controller_init(struct nand_controller *nfc)
+{
+ nfc->active = NULL;
+ spin_lock_init(&nfc->lock);
+ init_waitqueue_head(&nfc->wq);
+}

/**
* struct nand_legacy - NAND chip legacy fields/hooks
@@ -956,10 +962,6 @@ struct nand_legacy {
* you're modifying an existing driver that is using those
* fields/hooks, you should consider reworking the driver
* avoid using them.
- * @exec_op: controller specific method to execute NAND operations.
- * This method replaces ->cmdfunc(),
- * ->legacy.{read,write}_{buf,byte,word}(),
- * ->legacy.dev_ready() and ->waifunc().
* @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
* setting the read-retry mode. Mostly needed for MLC NAND.
* @ecc: [BOARDSPECIFIC] ECC control structure
@@ -1041,9 +1043,6 @@ struct nand_chip {

struct nand_legacy legacy;

- int (*exec_op)(struct nand_chip *chip,
- const struct nand_operation *op,
- bool check_only);
int (*setup_read_retry)(struct nand_chip *chip, int retry_mode);
int (*setup_data_interface)(struct nand_chip *chip, int chipnr,
const struct nand_data_interface *conf);
--
2.17.1
Boris Brezillon
2018-11-11 07:55:16 UTC
Permalink
Now that the CS to be selected on a nand_operation is passed in
nand_operation->cs we can make the ->select_chip() hook optional for
drivers implementing ->exec_op().

When not implemented, the core is assuming the CS line is automatically
asserted/deasserted by the driver ->exec_op() implementation.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/nand_base.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 7aa661f76891..93a19f551796 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -247,7 +247,9 @@ void nand_select_target(struct nand_chip *chip, unsigned int cs)
return;

chip->cur_cs = cs;
- chip->select_chip(chip, cs);
+
+ if (chip->select_chip)
+ chip->select_chip(chip, cs);
}
EXPORT_SYMBOL_GPL(nand_select_target);

@@ -260,7 +262,9 @@ EXPORT_SYMBOL_GPL(nand_select_target);
*/
void nand_deselect_target(struct nand_chip *chip)
{
- chip->select_chip(chip, -1);
+ if (chip->select_chip)
+ chip->select_chip(chip, -1);
+
chip->cur_cs = -1;
}
EXPORT_SYMBOL_GPL(nand_deselect_target);
@@ -5021,11 +5025,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
if (!mtd->name && mtd->dev.parent)
mtd->name = dev_name(mtd->dev.parent);

- if (chip->exec_op && !chip->select_chip) {
- pr_err("->select_chip() is mandatory when implementing ->exec_op()\n");
- return -EINVAL;
- }
-
ret = nand_legacy_check_hooks(chip);
if (ret)
return ret;
--
2.17.1
Boris Brezillon
2018-11-11 07:55:11 UTC
Permalink
Remove unused labels, rename out_mtd into err_unmap to make it clearer
and return 0 instead of using a goto out at the end of the registration
procedure.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz T-b

Changes in v2:
- None
---
drivers/mtd/nand/raw/ams-delta.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index 07ee513318ec..0fc7563fba10 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -210,8 +210,7 @@ static int ams_delta_init(struct platform_device *pdev)
io_base = ioremap(res->start, resource_size(res));
if (!io_base) {
dev_err(&pdev->dev, "ioremap failed\n");
- err = -EIO;
- goto out_free;
+ return -EIO;
}

priv->io_base = io_base;
@@ -224,7 +223,7 @@ static int ams_delta_init(struct platform_device *pdev)
if (IS_ERR(priv->gpiod_rdy)) {
err = PTR_ERR(priv->gpiod_rdy);
dev_warn(&pdev->dev, "RDY GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

this->ecc.mode = NAND_ECC_SOFT;
@@ -237,42 +236,42 @@ static int ams_delta_init(struct platform_device *pdev)
if (IS_ERR(priv->gpiod_nwp)) {
err = PTR_ERR(priv->gpiod_nwp);
dev_err(&pdev->dev, "NWP GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

priv->gpiod_nce = devm_gpiod_get(&pdev->dev, "nce", GPIOD_OUT_HIGH);
if (IS_ERR(priv->gpiod_nce)) {
err = PTR_ERR(priv->gpiod_nce);
dev_err(&pdev->dev, "NCE GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

priv->gpiod_nre = devm_gpiod_get(&pdev->dev, "nre", GPIOD_OUT_HIGH);
if (IS_ERR(priv->gpiod_nre)) {
err = PTR_ERR(priv->gpiod_nre);
dev_err(&pdev->dev, "NRE GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

priv->gpiod_nwe = devm_gpiod_get(&pdev->dev, "nwe", GPIOD_OUT_HIGH);
if (IS_ERR(priv->gpiod_nwe)) {
err = PTR_ERR(priv->gpiod_nwe);
dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

priv->gpiod_ale = devm_gpiod_get(&pdev->dev, "ale", GPIOD_OUT_LOW);
if (IS_ERR(priv->gpiod_ale)) {
err = PTR_ERR(priv->gpiod_ale);
dev_err(&pdev->dev, "ALE GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

priv->gpiod_cle = devm_gpiod_get(&pdev->dev, "cle", GPIOD_OUT_LOW);
if (IS_ERR(priv->gpiod_cle)) {
err = PTR_ERR(priv->gpiod_cle);
dev_err(&pdev->dev, "CLE GPIO request failed (%d)\n", err);
- goto out_mtd;
+ goto err_unmap;
}

/* Initialize data port direction to a known state */
@@ -281,17 +280,16 @@ static int ams_delta_init(struct platform_device *pdev)
/* Scan to find existence of the device */
err = nand_scan(this, 1);
if (err)
- goto out_mtd;
+ goto err_unmap;

/* Register the partitions */
mtd_device_register(mtd, partition_info, ARRAY_SIZE(partition_info));

- goto out;
+ return 0;

- out_mtd:
+err_unmap:
iounmap(io_base);
-out_free:
- out:
+
return err;
}
--
2.17.1
Boris Brezillon
2018-11-11 07:55:03 UTC
Permalink
After having reworked the rawnand API to avoid passing mtd_info
objects around, let's do the same for internal functions.

Signed-off-by: Boris Brezillon <***@bootlin.com>
Tested-by: Janusz Krzysztofik <***@gmail.com>
---
Changes in v3:
- Add Janusz's T-b

Changes in v2:
- Patch a few more functions
- Update kernel-doc headers
---
drivers/mtd/nand/raw/nand_base.c | 171 +++++++++++++-------------
drivers/mtd/nand/raw/nand_bbt.c | 185 +++++++++++++++--------------
drivers/mtd/nand/raw/nand_legacy.c | 18 ++-
3 files changed, 184 insertions(+), 190 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 4bc89c959f23..2a50afbdeeeb 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -49,9 +49,9 @@

#include "internals.h"

-static int nand_get_device(struct mtd_info *mtd, int new_state);
+static int nand_get_device(struct nand_chip *chip, int new_state);

-static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
struct mtd_oob_ops *ops);

/* Define default oob placement schemes for large and small page devices */
@@ -214,10 +214,8 @@ static const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = {
.free = nand_ooblayout_free_lp_hamming,
};

-static int check_offs_len(struct mtd_info *mtd,
- loff_t ofs, uint64_t len)
+static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
int ret = 0;

/* Start address must align on block boundary */
@@ -237,14 +235,12 @@ static int check_offs_len(struct mtd_info *mtd,

/**
* nand_release_device - [GENERIC] release chip
- * @mtd: MTD device structure
+ * @chip: NAND chip object
*
* Release chip lock and wake up anyone waiting on the device.
*/
-static void nand_release_device(struct mtd_info *mtd)
+static void nand_release_device(struct nand_chip *chip)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
-
/* Release the controller and the chip */
spin_lock(&chip->controller->lock);
chip->controller->active = NULL;
@@ -321,7 +317,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs)
if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
ofs += mtd->erasesize - mtd->writesize;
do {
- res = nand_do_write_oob(mtd, ofs, &ops);
+ res = nand_do_write_oob(chip, ofs, &ops);
if (!ret)
ret = res;

@@ -355,7 +351,7 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)

/**
* nand_block_markbad_lowlevel - mark a block bad
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @ofs: offset from device start
*
* This function performs the generic NAND bad block marking steps (i.e., bad
@@ -372,9 +368,9 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
* Note that we retain the first error encountered in (2) or (3), finish the
* procedures, and dump the error in the end.
*/
-static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
+static int nand_block_markbad_lowlevel(struct nand_chip *chip, loff_t ofs)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
int res, ret = 0;

if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
@@ -387,9 +383,9 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
nand_erase_nand(chip, &einfo, 0);

/* Write bad block marker to OOB */
- nand_get_device(mtd, FL_WRITING);
+ nand_get_device(chip, FL_WRITING);
ret = nand_markbad_bbm(chip, ofs);
- nand_release_device(mtd);
+ nand_release_device(chip);
}

/* Mark block bad in BBT */
@@ -407,14 +403,13 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)

/**
* nand_check_wp - [GENERIC] check if the chip is write protected
- * @mtd: MTD device structure
+ * @chip: NAND chip object
*
* Check, if the device is write protected. The function expects, that the
* device is already selected.
*/
-static int nand_check_wp(struct mtd_info *mtd)
+static int nand_check_wp(struct nand_chip *chip)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
u8 status;
int ret;

@@ -449,17 +444,15 @@ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)

/**
* nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @ofs: offset from device start
* @allowbbt: 1, if its allowed to access the bbt area
*
* Check, if the block is bad. Either by reading the bad block table or
* calling of the scan function.
*/
-static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
+static int nand_block_checkbad(struct nand_chip *chip, loff_t ofs, int allowbbt)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
-
/* Return info from the table */
if (chip->bbt)
return nand_isbad_bbt(chip, ofs, allowbbt);
@@ -565,13 +558,11 @@ EXPORT_SYMBOL_GPL(nand_gpio_waitrdy);
/**
* panic_nand_get_device - [GENERIC] Get chip for selected access
* @chip: the nand chip descriptor
- * @mtd: MTD device structure
* @new_state: the state which is requested
*
* Used when in panic, no locks are taken.
*/
-static void panic_nand_get_device(struct nand_chip *chip,
- struct mtd_info *mtd, int new_state)
+static void panic_nand_get_device(struct nand_chip *chip, int new_state)
{
/* Hardware controller shared among independent devices */
chip->controller->active = chip;
@@ -580,15 +571,14 @@ static void panic_nand_get_device(struct nand_chip *chip,

/**
* nand_get_device - [GENERIC] Get chip for selected access
- * @mtd: MTD device structure
+ * @chip: NAND chip structure
* @new_state: the state which is requested
*
* Get the device and lock it for exclusive access
*/
static int
-nand_get_device(struct mtd_info *mtd, int new_state)
+nand_get_device(struct nand_chip *chip, int new_state)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
spinlock_t *lock = &chip->controller->lock;
wait_queue_head_t *wq = &chip->controller->wq;
DECLARE_WAITQUEUE(wait, current);
@@ -2955,15 +2945,15 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,

/**
* nand_transfer_oob - [INTERN] Transfer oob to client buffer
- * @mtd: mtd info structure
+ * @chip: NAND chip object
* @oob: oob destination address
* @ops: oob ops structure
* @len: size of oob to transfer
*/
-static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
+static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
struct mtd_oob_ops *ops, size_t len)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
int ret;

switch (ops->mode) {
@@ -3020,17 +3010,17 @@ static void nand_wait_readrdy(struct nand_chip *chip)

/**
* nand_do_read_ops - [INTERN] Read data with ECC
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @from: offset to read from
* @ops: oob ops structure
*
* Internal function. Called with chip held.
*/
-static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
+static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
struct mtd_oob_ops *ops)
{
int chipnr, page, realpage, col, bytes, aligned, oob_required;
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
int ret = 0;
uint32_t readlen = ops->len;
uint32_t oobreadlen = ops->ooblen;
@@ -3118,8 +3108,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
int toread = min(oobreadlen, max_oobsize);

if (toread) {
- oob = nand_transfer_oob(mtd,
- oob, ops, toread);
+ oob = nand_transfer_oob(chip, oob, ops,
+ toread);
oobreadlen -= toread;
}
}
@@ -3349,18 +3339,18 @@ static int nand_write_oob_syndrome(struct nand_chip *chip, int page)

/**
* nand_do_read_oob - [INTERN] NAND read out-of-band
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @from: offset to read from
* @ops: oob operations description structure
*
* NAND read out-of-band data from the spare area.
*/
-static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+static int nand_do_read_oob(struct nand_chip *chip, loff_t from,
struct mtd_oob_ops *ops)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
unsigned int max_bitflips = 0;
int page, realpage, chipnr;
- struct nand_chip *chip = mtd_to_nand(mtd);
struct mtd_ecc_stats stats;
int readlen = ops->ooblen;
int len;
@@ -3391,7 +3381,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
break;

len = min(len, readlen);
- buf = nand_transfer_oob(mtd, buf, ops, len);
+ buf = nand_transfer_oob(chip, buf, ops, len);

nand_wait_readrdy(chip);

@@ -3436,6 +3426,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
static int nand_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
+ struct nand_chip *chip = mtd_to_nand(mtd);
int ret;

ops->retlen = 0;
@@ -3445,14 +3436,14 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
ops->mode != MTD_OPS_RAW)
return -ENOTSUPP;

- nand_get_device(mtd, FL_READING);
+ nand_get_device(chip, FL_READING);

if (!ops->datbuf)
- ret = nand_do_read_oob(mtd, from, ops);
+ ret = nand_do_read_oob(chip, from, ops);
else
- ret = nand_do_read_ops(mtd, from, ops);
+ ret = nand_do_read_ops(chip, from, ops);

- nand_release_device(mtd);
+ nand_release_device(chip);
return ret;
}

@@ -3780,7 +3771,6 @@ static int nand_write_page_syndrome(struct nand_chip *chip, const uint8_t *buf,

/**
* nand_write_page - write one page
- * @mtd: MTD device structure
* @chip: NAND chip descriptor
* @offset: address offset within the page
* @data_len: length of actual data to be written
@@ -3789,10 +3779,11 @@ static int nand_write_page_syndrome(struct nand_chip *chip, const uint8_t *buf,
* @page: page number to write
* @raw: use _raw version of write_page
*/
-static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
- uint32_t offset, int data_len, const uint8_t *buf,
- int oob_required, int page, int raw)
+static int nand_write_page(struct nand_chip *chip, uint32_t offset,
+ int data_len, const uint8_t *buf, int oob_required,
+ int page, int raw)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
int status, subpage;

if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
@@ -3818,15 +3809,15 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,

/**
* nand_fill_oob - [INTERN] Transfer client buffer to oob
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @oob: oob data buffer
* @len: oob data write length
* @ops: oob ops structure
*/
-static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
+static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
struct mtd_oob_ops *ops)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
int ret;

/*
@@ -3858,17 +3849,17 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,

/**
* nand_do_write_ops - [INTERN] NAND write with ECC
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @to: offset to write to
* @ops: oob operations description structure
*
* NAND write with ECC.
*/
-static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
+static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
struct mtd_oob_ops *ops)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
int chipnr, realpage, page, column;
- struct nand_chip *chip = mtd_to_nand(mtd);
uint32_t writelen = ops->len;

uint32_t oobwritelen = ops->ooblen;
@@ -3896,7 +3887,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
chip->select_chip(chip, chipnr);

/* Check, if it is write protected */
- if (nand_check_wp(mtd)) {
+ if (nand_check_wp(chip)) {
ret = -EIO;
goto err_out;
}
@@ -3944,14 +3935,14 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,

if (unlikely(oob)) {
size_t len = min(oobwritelen, oobmaxlen);
- oob = nand_fill_oob(mtd, oob, len, ops);
+ oob = nand_fill_oob(chip, oob, len, ops);
oobwritelen -= len;
} else {
/* We still need to erase leftover OOB data */
memset(chip->oob_poi, 0xff, mtd->oobsize);
}

- ret = nand_write_page(mtd, chip, column, bytes, wbuf,
+ ret = nand_write_page(chip, column, bytes, wbuf,
oob_required, page,
(ops->mode == MTD_OPS_RAW));
if (ret)
@@ -4003,7 +3994,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
int ret;

/* Grab the device */
- panic_nand_get_device(chip, mtd, FL_WRITING);
+ panic_nand_get_device(chip, FL_WRITING);

chip->select_chip(chip, chipnr);

@@ -4015,7 +4006,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
ops.datbuf = (uint8_t *)buf;
ops.mode = MTD_OPS_PLACE_OOB;

- ret = nand_do_write_ops(mtd, to, &ops);
+ ret = nand_do_write_ops(chip, to, &ops);

*retlen = ops.retlen;
return ret;
@@ -4023,17 +4014,17 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,

/**
* nand_do_write_oob - [MTD Interface] NAND write out-of-band
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @to: offset to write to
* @ops: oob operation description structure
*
* NAND write out-of-band.
*/
-static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
+static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
struct mtd_oob_ops *ops)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
int chipnr, page, status, len;
- struct nand_chip *chip = mtd_to_nand(mtd);

pr_debug("%s: to = 0x%08x, len = %i\n",
__func__, (unsigned int)to, (int)ops->ooblen);
@@ -4063,7 +4054,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
page = (int)(to >> chip->page_shift);

/* Check, if it is write protected */
- if (nand_check_wp(mtd)) {
+ if (nand_check_wp(chip)) {
chip->select_chip(chip, -1);
return -EROFS;
}
@@ -4072,7 +4063,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
if (page == chip->pagebuf)
chip->pagebuf = -1;

- nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
+ nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);

if (ops->mode == MTD_OPS_RAW)
status = chip->ecc.write_oob_raw(chip, page & chip->pagemask);
@@ -4098,11 +4089,12 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
static int nand_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
+ struct nand_chip *chip = mtd_to_nand(mtd);
int ret = -ENOTSUPP;

ops->retlen = 0;

- nand_get_device(mtd, FL_WRITING);
+ nand_get_device(chip, FL_WRITING);

switch (ops->mode) {
case MTD_OPS_PLACE_OOB:
@@ -4115,12 +4107,12 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
}

if (!ops->datbuf)
- ret = nand_do_write_oob(mtd, to, ops);
+ ret = nand_do_write_oob(chip, to, ops);
else
- ret = nand_do_write_ops(mtd, to, ops);
+ ret = nand_do_write_ops(chip, to, ops);

out:
- nand_release_device(mtd);
+ nand_release_device(chip);
return ret;
}

@@ -4164,7 +4156,6 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
int allowbbt)
{
- struct mtd_info *mtd = nand_to_mtd(chip);
int page, status, pages_per_block, ret, chipnr;
loff_t len;

@@ -4172,11 +4163,11 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
__func__, (unsigned long long)instr->addr,
(unsigned long long)instr->len);

- if (check_offs_len(mtd, instr->addr, instr->len))
+ if (check_offs_len(chip, instr->addr, instr->len))
return -EINVAL;

/* Grab the lock and see if the device is available */
- nand_get_device(mtd, FL_ERASING);
+ nand_get_device(chip, FL_ERASING);

/* Shift to get first page */
page = (int)(instr->addr >> chip->page_shift);
@@ -4189,7 +4180,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
chip->select_chip(chip, chipnr);

/* Check, if it is write protected */
- if (nand_check_wp(mtd)) {
+ if (nand_check_wp(chip)) {
pr_debug("%s: device is write protected!\n",
__func__);
ret = -EIO;
@@ -4201,7 +4192,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,

while (len) {
/* Check if we have a bad block, we do not erase bad blocks! */
- if (nand_block_checkbad(mtd, ((loff_t) page) <<
+ if (nand_block_checkbad(chip, ((loff_t) page) <<
chip->page_shift, allowbbt)) {
pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
__func__, page);
@@ -4250,7 +4241,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,

/* Deselect and wake up anyone waiting on the device */
chip->select_chip(chip, -1);
- nand_release_device(mtd);
+ nand_release_device(chip);

/* Return more or less happy */
return ret;
@@ -4264,12 +4255,14 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
*/
static void nand_sync(struct mtd_info *mtd)
{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+
pr_debug("%s: called\n", __func__);

/* Grab the lock and see if the device is available */
- nand_get_device(mtd, FL_SYNCING);
+ nand_get_device(chip, FL_SYNCING);
/* Release it and go back */
- nand_release_device(mtd);
+ nand_release_device(chip);
}

/**
@@ -4284,13 +4277,13 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
int ret;

/* Select the NAND device */
- nand_get_device(mtd, FL_READING);
+ nand_get_device(chip, FL_READING);
chip->select_chip(chip, chipnr);

- ret = nand_block_checkbad(mtd, offs, 0);
+ ret = nand_block_checkbad(chip, offs, 0);

chip->select_chip(chip, -1);
- nand_release_device(mtd);
+ nand_release_device(chip);

return ret;
}
@@ -4312,7 +4305,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
return ret;
}

- return nand_block_markbad_lowlevel(mtd, ofs);
+ return nand_block_markbad_lowlevel(mtd_to_nand(mtd), ofs);
}

/**
@@ -4357,7 +4350,7 @@ static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
*/
static int nand_suspend(struct mtd_info *mtd)
{
- return nand_get_device(mtd, FL_PM_SUSPENDED);
+ return nand_get_device(mtd_to_nand(mtd), FL_PM_SUSPENDED);
}

/**
@@ -4369,7 +4362,7 @@ static void nand_resume(struct mtd_info *mtd)
struct nand_chip *chip = mtd_to_nand(mtd);

if (chip->state == FL_PM_SUSPENDED)
- nand_release_device(mtd);
+ nand_release_device(chip);
else
pr_err("%s called for a chip which is not in suspended state\n",
__func__);
@@ -4382,7 +4375,7 @@ static void nand_resume(struct mtd_info *mtd)
*/
static void nand_shutdown(struct mtd_info *mtd)
{
- nand_get_device(mtd, FL_PM_SUSPENDED);
+ nand_get_device(mtd_to_nand(mtd), FL_PM_SUSPENDED);
}

/* Set default functions */
@@ -5052,9 +5045,9 @@ static void nand_scan_ident_cleanup(struct nand_chip *chip)
kfree(chip->parameters.onfi);
}

-static int nand_set_ecc_soft_ops(struct mtd_info *mtd)
+static int nand_set_ecc_soft_ops(struct nand_chip *chip)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;

if (WARN_ON(ecc->mode != NAND_ECC_SOFT))
@@ -5410,9 +5403,9 @@ EXPORT_SYMBOL_GPL(nand_ecc_choose_conf);
* Requirement (2) ensures we can correct even when all bitflips are clumped
* in the same sector.
*/
-static bool nand_ecc_strength_good(struct mtd_info *mtd)
+static bool nand_ecc_strength_good(struct nand_chip *chip)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
int corr, ds_corr;

@@ -5577,7 +5570,7 @@ static int nand_scan_tail(struct nand_chip *chip)
ecc->algo = NAND_ECC_HAMMING;

case NAND_ECC_SOFT:
- ret = nand_set_ecc_soft_ops(mtd);
+ ret = nand_set_ecc_soft_ops(chip);
if (ret) {
ret = -EINVAL;
goto err_nand_manuf_cleanup;
@@ -5662,7 +5655,7 @@ static int nand_scan_tail(struct nand_chip *chip)
mtd->oobavail = ret;

/* ECC sanity check: warn if it's too weak */
- if (!nand_ecc_strength_good(mtd))
+ if (!nand_ecc_strength_good(chip))
pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
mtd->name);

diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index 98a826838b60..b5e3b54cc767 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -77,7 +77,7 @@
#define BBT_ENTRY_MASK 0x03
#define BBT_ENTRY_SHIFT 2

-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
+static int nand_update_bbt(struct nand_chip *chip, loff_t offs);

static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
{
@@ -160,7 +160,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)

/**
* read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @buf: temporary buffer
* @page: the starting page
* @num: the number of bbt descriptors to read
@@ -169,11 +169,11 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
*
* Read the bad block table starting from page.
*/
-static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
- struct nand_bbt_descr *td, int offs)
+static int read_bbt(struct nand_chip *this, uint8_t *buf, int page, int num,
+ struct nand_bbt_descr *td, int offs)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
int res, ret = 0, i, j, act = 0;
- struct nand_chip *this = mtd_to_nand(mtd);
size_t retlen, len, totlen;
loff_t from;
int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -253,7 +253,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,

/**
* read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @chip: read the table for a specific chip, -1 read all chips; applies only if
@@ -262,16 +262,17 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
* Read the bad block table for all chips starting at a given page. We assume
* that the bbt bits are in consecutive order.
*/
-static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
+static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
+ struct nand_bbt_descr *td, int chip)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int res = 0, i;

if (td->options & NAND_BBT_PERCHIP) {
int offs = 0;
for (i = 0; i < this->numchips; i++) {
if (chip == -1 || chip == i)
- res = read_bbt(mtd, buf, td->pages[i],
+ res = read_bbt(this, buf, td->pages[i],
this->chipsize >> this->bbt_erase_shift,
td, offs);
if (res)
@@ -279,7 +280,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
offs += this->chipsize >> this->bbt_erase_shift;
}
} else {
- res = read_bbt(mtd, buf, td->pages[0],
+ res = read_bbt(this, buf, td->pages[0],
mtd->size >> this->bbt_erase_shift, td, 0);
if (res)
return res;
@@ -288,9 +289,10 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
}

/* BBT marker is in the first page, no OOB */
-static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
- struct nand_bbt_descr *td)
+static int scan_read_data(struct nand_chip *this, uint8_t *buf, loff_t offs,
+ struct nand_bbt_descr *td)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
size_t retlen;
size_t len;

@@ -303,7 +305,7 @@ static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,

/**
* scan_read_oob - [GENERIC] Scan data+OOB region to buffer
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @offs: offset at which to scan
* @len: length of data region to read
@@ -312,9 +314,10 @@ static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
* page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest"
* ECC condition (error or bitflip). May quit on the first (non-ECC) error.
*/
-static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_oob(struct nand_chip *this, uint8_t *buf, loff_t offs,
size_t len)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
struct mtd_oob_ops ops;
int res, ret = 0;

@@ -342,19 +345,20 @@ static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
return ret;
}

-static int scan_read(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
- size_t len, struct nand_bbt_descr *td)
+static int scan_read(struct nand_chip *this, uint8_t *buf, loff_t offs,
+ size_t len, struct nand_bbt_descr *td)
{
if (td->options & NAND_BBT_NO_OOB)
- return scan_read_data(mtd, buf, offs, td);
+ return scan_read_data(this, buf, offs, td);
else
- return scan_read_oob(mtd, buf, offs, len);
+ return scan_read_oob(this, buf, offs, len);
}

/* Scan write data with oob to flash */
-static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
+static int scan_write_bbt(struct nand_chip *this, loff_t offs, size_t len,
uint8_t *buf, uint8_t *oob)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
struct mtd_oob_ops ops;

ops.mode = MTD_OPS_PLACE_OOB;
@@ -367,8 +371,9 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
return mtd_write_oob(mtd, offs, &ops);
}

-static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
+static u32 bbt_get_ver_offs(struct nand_chip *this, struct nand_bbt_descr *td)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
u32 ver_offs = td->veroffs;

if (!(td->options & NAND_BBT_NO_OOB))
@@ -378,7 +383,7 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)

/**
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
@@ -386,34 +391,35 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
* Read the bad block table(s) for all chips starting at a given page. We
* assume that the bbt bits are in consecutive order.
*/
-static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+static void read_abs_bbts(struct nand_chip *this, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);

/* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
- scan_read(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
- mtd->writesize, td);
- td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
+ scan_read(this, buf, (loff_t)td->pages[0] << this->page_shift,
+ mtd->writesize, td);
+ td->version[0] = buf[bbt_get_ver_offs(this, td)];
pr_info("Bad block table at page %d, version 0x%02X\n",
td->pages[0], td->version[0]);
}

/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
- scan_read(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
- mtd->writesize, md);
- md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
+ scan_read(this, buf, (loff_t)md->pages[0] << this->page_shift,
+ mtd->writesize, md);
+ md->version[0] = buf[bbt_get_ver_offs(this, md)];
pr_info("Bad block table at page %d, version 0x%02X\n",
md->pages[0], md->version[0]);
}
}

/* Scan a given block partially */
-static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
+static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd,
loff_t offs, uint8_t *buf, int numpages)
{
+ struct mtd_info *mtd = nand_to_mtd(this);
struct mtd_oob_ops ops;
int j, ret;

@@ -443,7 +449,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,

/**
* create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @bd: descriptor for the good/bad block search pattern
* @chip: create the table for a specific chip, -1 read all chips; applies only
@@ -452,10 +458,10 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
* Create a bad block table by scanning the device for the given good/bad block
* identify pattern.
*/
-static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
- struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct nand_chip *this, uint8_t *buf,
+ struct nand_bbt_descr *bd, int chip)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int i, numblocks, numpages;
int startblock;
loff_t from;
@@ -491,7 +497,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,

BUG_ON(bd->options & NAND_BBT_NO_OOB);

- ret = scan_block_fast(mtd, bd, from, buf, numpages);
+ ret = scan_block_fast(this, bd, from, buf, numpages);
if (ret < 0)
return ret;

@@ -509,7 +515,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,

/**
* search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @td: descriptor for the bad block table
*
@@ -522,9 +528,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
*
* The bbt ident pattern resides in the oob area of the first page in a block.
*/
-static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
+static int search_bbt(struct nand_chip *this, uint8_t *buf,
+ struct nand_bbt_descr *td)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int i, chips;
int startblock, block, dir;
int scanlen = mtd->writesize + mtd->oobsize;
@@ -561,11 +568,11 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
loff_t offs = (loff_t)actblock << this->bbt_erase_shift;

/* Read first page */
- scan_read(mtd, buf, offs, mtd->writesize, td);
+ scan_read(this, buf, offs, mtd->writesize, td);
if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
td->pages[i] = actblock << blocktopage;
if (td->options & NAND_BBT_VERSION) {
- offs = bbt_get_ver_offs(mtd, td);
+ offs = bbt_get_ver_offs(this, td);
td->version[i] = buf[offs];
}
break;
@@ -586,23 +593,23 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr

/**
* search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
*
* Search and read the bad block table(s).
*/
-static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
+static void search_read_bbts(struct nand_chip *this, uint8_t *buf,
struct nand_bbt_descr *td,
struct nand_bbt_descr *md)
{
/* Search the primary table */
- search_bbt(mtd, buf, td);
+ search_bbt(this, buf, td);

/* Search the mirror table */
if (md)
- search_bbt(mtd, buf, md);
+ search_bbt(this, buf, md);
}

/**
@@ -700,7 +707,7 @@ static void mark_bbt_block_bad(struct nand_chip *this,

/**
* write_bbt - [GENERIC] (Re)write the bad block table
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
@@ -708,11 +715,11 @@ static void mark_bbt_block_bad(struct nand_chip *this,
*
* (Re)write the bad block table.
*/
-static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
+static int write_bbt(struct nand_chip *this, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md,
int chipsel)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
struct erase_info einfo;
int i, res, chip = 0;
int bits, page, offs, numblocks, sft, sftmsk;
@@ -862,9 +869,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
continue;
}

- res = scan_write_bbt(mtd, to, len, buf,
- td->options & NAND_BBT_NO_OOB ? NULL :
- &buf[len]);
+ res = scan_write_bbt(this, to, len, buf,
+ td->options & NAND_BBT_NO_OOB ?
+ NULL : &buf[len]);
if (res < 0) {
pr_warn("nand_bbt: error while writing BBT block %d\n",
res);
@@ -887,22 +894,21 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,

/**
* nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd: MTD device structure
+ * @this: NAND chip object
* @bd: descriptor for the good/bad block search pattern
*
* The function creates a memory based bbt by scanning the device for
* manufacturer / software marked good / bad blocks.
*/
-static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static inline int nand_memory_bbt(struct nand_chip *this,
+ struct nand_bbt_descr *bd)
{
- struct nand_chip *this = mtd_to_nand(mtd);
-
- return create_bbt(mtd, this->data_buf, bd, -1);
+ return create_bbt(this, this->data_buf, bd, -1);
}

/**
* check_create - [GENERIC] create and write bbt(s) if necessary
- * @mtd: MTD device structure
+ * @this: the NAND device
* @buf: temporary buffer
* @bd: descriptor for the good/bad block search pattern
*
@@ -911,10 +917,10 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
* for the chip/device. Update is necessary if one of the tables is missing or
* the version nr. of one table is less than the other.
*/
-static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
+static int check_create(struct nand_chip *this, uint8_t *buf,
+ struct nand_bbt_descr *bd)
{
int i, chips, writeops, create, chipsel, res, res2;
- struct nand_chip *this = mtd_to_nand(mtd);
struct nand_bbt_descr *td = this->bbt_td;
struct nand_bbt_descr *md = this->bbt_md;
struct nand_bbt_descr *rd, *rd2;
@@ -971,7 +977,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc

/* Create the table in memory by scanning the chip(s) */
if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
- create_bbt(mtd, buf, bd, chipsel);
+ create_bbt(this, buf, bd, chipsel);

td->version[i] = 1;
if (md)
@@ -980,7 +986,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc

/* Read back first? */
if (rd) {
- res = read_abs_bbt(mtd, buf, rd, chipsel);
+ res = read_abs_bbt(this, buf, rd, chipsel);
if (mtd_is_eccerr(res)) {
/* Mark table as invalid */
rd->pages[i] = -1;
@@ -991,7 +997,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
}
/* If they weren't versioned, read both */
if (rd2) {
- res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
+ res2 = read_abs_bbt(this, buf, rd2, chipsel);
if (mtd_is_eccerr(res2)) {
/* Mark table as invalid */
rd2->pages[i] = -1;
@@ -1013,14 +1019,14 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc

/* Write the bad block table to the device? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
- res = write_bbt(mtd, buf, td, md, chipsel);
+ res = write_bbt(this, buf, td, md, chipsel);
if (res < 0)
return res;
}

/* Write the mirror bad block table to the device? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
- res = write_bbt(mtd, buf, md, td, chipsel);
+ res = write_bbt(this, buf, md, td, chipsel);
if (res < 0)
return res;
}
@@ -1030,15 +1036,15 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc

/**
* mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd: MTD device structure
+ * @this: the NAND device
* @td: bad block table descriptor
*
* The bad block table regions are marked as "bad" to prevent accidental
* erasures / writes. The regions are identified by the mark 0x02.
*/
-static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
+static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int i, j, chips, block, nrblocks, update;
uint8_t oldval;

@@ -1061,7 +1067,7 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
if ((oldval != BBT_BLOCK_RESERVED) &&
td->reserved_block_code)
- nand_update_bbt(mtd, (loff_t)block <<
+ nand_update_bbt(this, (loff_t)block <<
this->bbt_erase_shift);
continue;
}
@@ -1083,22 +1089,22 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
* bbts. This should only happen once.
*/
if (update && td->reserved_block_code)
- nand_update_bbt(mtd, (loff_t)(block - 1) <<
+ nand_update_bbt(this, (loff_t)(block - 1) <<
this->bbt_erase_shift);
}
}

/**
* verify_bbt_descr - verify the bad block description
- * @mtd: MTD device structure
+ * @this: the NAND device
* @bd: the table to verify
*
* This functions performs a few sanity checks on the bad block description
* table.
*/
-static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
u32 pattern_len;
u32 bits;
u32 table_size;
@@ -1138,7 +1144,7 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)

/**
* nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd: MTD device structure
+ * @this: the NAND device
* @bd: descriptor for the good/bad block search pattern
*
* The function checks, if a bad block table(s) is/are already available. If
@@ -1148,9 +1154,9 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
* The bad block table memory is allocated here. It must be freed by calling
* the nand_free_bbt function.
*/
-static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int len, res;
uint8_t *buf;
struct nand_bbt_descr *td = this->bbt_td;
@@ -1170,14 +1176,14 @@ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
* memory based bad block table.
*/
if (!td) {
- if ((res = nand_memory_bbt(mtd, bd))) {
+ if ((res = nand_memory_bbt(this, bd))) {
pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
goto err;
}
return 0;
}
- verify_bbt_descr(mtd, td);
- verify_bbt_descr(mtd, md);
+ verify_bbt_descr(this, td);
+ verify_bbt_descr(this, md);

/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
@@ -1190,20 +1196,20 @@ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)

/* Is the bbt at a given page? */
if (td->options & NAND_BBT_ABSPAGE) {
- read_abs_bbts(mtd, buf, td, md);
+ read_abs_bbts(this, buf, td, md);
} else {
/* Search the bad block table using a pattern in oob */
- search_read_bbts(mtd, buf, td, md);
+ search_read_bbts(this, buf, td, md);
}

- res = check_create(mtd, buf, bd);
+ res = check_create(this, buf, bd);
if (res)
goto err;

/* Prevent the bbt regions from erasing / writing */
- mark_bbt_region(mtd, td);
+ mark_bbt_region(this, td);
if (md)
- mark_bbt_region(mtd, md);
+ mark_bbt_region(this, md);

vfree(buf);
return 0;
@@ -1216,14 +1222,14 @@ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)

/**
* nand_update_bbt - update bad block table(s)
- * @mtd: MTD device structure
+ * @this: the NAND device
* @offs: the offset of the newly marked block
*
* The function updates the bad block table(s).
*/
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_update_bbt(struct nand_chip *this, loff_t offs)
{
- struct nand_chip *this = mtd_to_nand(mtd);
+ struct mtd_info *mtd = nand_to_mtd(this);
int len, res = 0;
int chip, chipsel;
uint8_t *buf;
@@ -1255,13 +1261,13 @@ static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)

/* Write the bad block table to the device? */
if (td->options & NAND_BBT_WRITE) {
- res = write_bbt(mtd, buf, td, md, chipsel);
+ res = write_bbt(this, buf, td, md, chipsel);
if (res < 0)
goto out;
}
/* Write the mirror bad block table to the device? */
if (md && (md->options & NAND_BBT_WRITE)) {
- res = write_bbt(mtd, buf, md, td, chipsel);
+ res = write_bbt(this, buf, md, td, chipsel);
}

out:
@@ -1382,7 +1388,7 @@ int nand_create_bbt(struct nand_chip *this)
return ret;
}

- return nand_scan_bbt(nand_to_mtd(this), this->badblock_pattern);
+ return nand_scan_bbt(this, this->badblock_pattern);
}
EXPORT_SYMBOL(nand_create_bbt);

@@ -1433,7 +1439,6 @@ int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt)
*/
int nand_markbad_bbt(struct nand_chip *this, loff_t offs)
{
- struct mtd_info *mtd = nand_to_mtd(this);
int block, ret = 0;

block = (int)(offs >> this->bbt_erase_shift);
@@ -1443,7 +1448,7 @@ int nand_markbad_bbt(struct nand_chip *this, loff_t offs)

/* Update flash-based bad block table */
if (this->bbt_options & NAND_BBT_USE_FLASH)
- ret = nand_update_bbt(mtd, offs);
+ ret = nand_update_bbt(this, offs);

return ret;
}
diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index c5ddc86cd98c..bf0304c4a640 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -165,15 +165,14 @@ static void nand_read_buf16(struct nand_chip *chip, uint8_t *buf, int len)

/**
* panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @timeo: Timeout
*
* Helper function for nand_wait_ready used when needing to wait in interrupt
* context.
*/
-static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
+static void panic_nand_wait_ready(struct nand_chip *chip, unsigned long timeo)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
int i;

/* Wait for the device to get ready */
@@ -193,11 +192,10 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
*/
void nand_wait_ready(struct nand_chip *chip)
{
- struct mtd_info *mtd = nand_to_mtd(chip);
unsigned long timeo = 400;

if (in_interrupt() || oops_in_progress)
- return panic_nand_wait_ready(mtd, timeo);
+ return panic_nand_wait_ready(chip, timeo);

/* Wait until command is processed or timeout occurs */
timeo = jiffies + msecs_to_jiffies(timeo);
@@ -214,14 +212,13 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);

/**
* nand_wait_status_ready - [GENERIC] Wait for the ready status after commands.
- * @mtd: MTD device structure
+ * @chip: NAND chip object
* @timeo: Timeout in ms
*
* Wait for status ready (i.e. command done) or timeout.
*/
-static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
+static void nand_wait_status_ready(struct nand_chip *chip, unsigned long timeo)
{
- register struct nand_chip *chip = mtd_to_nand(mtd);
int ret;

timeo = jiffies + msecs_to_jiffies(timeo);
@@ -321,7 +318,7 @@ static void nand_command(struct nand_chip *chip, unsigned int command,
chip->legacy.cmd_ctrl(chip, NAND_CMD_NONE,
NAND_NCE | NAND_CTRL_CHANGE);
/* EZ-NAND can take upto 250ms as per ONFi v4.0 */
- nand_wait_status_ready(mtd, 250);
+ nand_wait_status_ready(chip, 250);
return;

/* This applies to read commands */
@@ -458,7 +455,7 @@ static void nand_command_lp(struct nand_chip *chip, unsigned int command,
chip->legacy.cmd_ctrl(chip, NAND_CMD_NONE,
NAND_NCE | NAND_CTRL_CHANGE);
/* EZ-NAND can take upto 250ms as per ONFi v4.0 */
- nand_wait_status_ready(mtd, 250);
+ nand_wait_status_ready(chip, 250);
return;

case NAND_CMD_RNDOUT:
@@ -525,7 +522,6 @@ EXPORT_SYMBOL(nand_get_set_features_notsupp);

/**
* nand_wait - [DEFAULT] wait until the command is done
- * @mtd: MTD device structure
* @chip: NAND chip structure
*
* Wait for command done. This applies to erase and program only.
--
2.17.1
Miquel Raynal
2018-11-18 20:47:25 UTC
Permalink
Hi Boris,
Hello,
After the sanitization of the raw NAND API, here is a smaller
patchset continuing in this direction.
Patch 1 is just a follow-up on the "stop passing mtd_info objects
around" patches, except this times it takes care of internal functions.
There's still a lot of sanitization to do in drivers in order to get
rid of those mtd params, but I'll leave that to driver maintainers.
Patch 2 is trying to get rid of 3 forward declarations that are not
really needed.
Patch 3 is getting rid of useless test in nand_legacy_set_defaults().
Patch 4 is making nand_exec_op() private, so that NAND controller
drivers are not tempted to use it.
Patch 5 is getting rid of an unused flag that has been around for quite
some time.
Patches 6 to 11 are doing various cleanups/fixes/improvements in the
ams-delta driver.
Patches 12 to 20 are deprecating the ->select_chip() hook which should
now be replaced by internal target/die selection logic directly called
from the ->exec_op() and ecc.read/write_xxx() implementations. The
rational behind this change is that modern controller now take care of
asserting/deasserting the CS pin on a per-operation basis, and if we
ever want to implement advanced queuing logic (instead of the basic
serialization we currently have) we'll have to attach a CS line to the
operation we want to execute.
Finally, patches 21 and 22 are moving the controller specific methods
to nand_controller_ops.
As usual, let me know what you think of those changes.
Regards,
Boris
- Patch the ams-delta driver
- Fix the bug reported by Janusz
- Fix a bug reported by kbuild bots
mtd: rawnand: Stop passing mtd_info objects to internal functions
mtd: rawnand: Reorganize code to avoid forward declarations
mtd: rawnand: legacy: Drop useless test in nand_legacy_set_defaults()
mtd: rawnand: Move nand_exec_op() to internal.h
mtd: rawnand: Remove unused NAND_CONTROLLER_ALLOC flag
mtd: rawnand: ams-delta: Allow this driver to be compiled when
COMPILE_TEST=y
mtd: rawnand: ams-delta: Add an SPDX tag to replace the license text
mtd: rawnand: ams-delta: Fix various coding style issues
mtd: rawnand: ams-delta: cleanup ams_delta_init() error path
mtd: rawnand: ams-delta: Check mtd_device_register() return code
mtd: rawnand: ams-delta: Explicitly inherit from nand_controller
mtd: rawnand: Add nand_[de]select_target() helpers
mtd: rawnand: Pass the CS line to be selected in struct nand_operation
mtd: rawnand: Make ->select_chip() optional when ->exec_op() is
implemented
mtd: rawnand: fsmc: Stop implementing ->select_chip()
mtd: rawnand: marvell: Stop implementing ->select_chip()
mtd: rawnand: tegra: Stop implementing ->select_chip()
mtd: rawnand: vf610: Stop implementing ->select_chip()
mtd: rawnand: ams-delta: Stop implementing ->select_chip()
mtd: rawnand: Deprecate the ->select_chip() hook
mtd: rawnand: Move the ->exec_op() method to nand_controller_ops
mtd: rawnand: Move ->setup_data_interface() to nand_controller_ops
drivers/mtd/nand/raw/Kconfig | 2 +-
drivers/mtd/nand/raw/ams-delta.c | 95 ++-
drivers/mtd/nand/raw/atmel/nand-controller.c | 9 +-
drivers/mtd/nand/raw/au1550nd.c | 2 +-
.../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c | 2 +-
drivers/mtd/nand/raw/cafe_nand.c | 2 +-
drivers/mtd/nand/raw/davinci_nand.c | 2 +-
drivers/mtd/nand/raw/denali.c | 5 +-
drivers/mtd/nand/raw/diskonchip.c | 4 +-
drivers/mtd/nand/raw/fsl_elbc_nand.c | 2 +-
drivers/mtd/nand/raw/fsl_ifc_nand.c | 2 +-
drivers/mtd/nand/raw/fsl_upm.c | 2 +-
drivers/mtd/nand/raw/fsmc_nand.c | 32 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 27 +-
drivers/mtd/nand/raw/hisi504_nand.c | 2 +-
drivers/mtd/nand/raw/internals.h | 33 +
drivers/mtd/nand/raw/jz4740_nand.c | 6 +-
drivers/mtd/nand/raw/jz4780_nand.c | 2 +-
drivers/mtd/nand/raw/marvell_nand.c | 32 +-
drivers/mtd/nand/raw/mpc5121_nfc.c | 4 +-
drivers/mtd/nand/raw/mtk_nand.c | 4 +-
drivers/mtd/nand/raw/mxc_nand.c | 14 +-
drivers/mtd/nand/raw/nand_base.c | 743 +++++++++---------
drivers/mtd/nand/raw/nand_bbt.c | 285 +++----
drivers/mtd/nand/raw/nand_hynix.c | 8 +-
drivers/mtd/nand/raw/nand_legacy.c | 35 +-
drivers/mtd/nand/raw/ndfc.c | 2 +-
drivers/mtd/nand/raw/plat_nand.c | 2 +-
drivers/mtd/nand/raw/qcom_nandc.c | 2 +-
drivers/mtd/nand/raw/r852.c | 4 +-
drivers/mtd/nand/raw/s3c2410.c | 7 +-
drivers/mtd/nand/raw/sh_flctl.c | 2 +-
drivers/mtd/nand/raw/sunxi_nand.c | 4 +-
drivers/mtd/nand/raw/tango_nand.c | 4 +-
drivers/mtd/nand/raw/tegra_nand.c | 32 +-
drivers/mtd/nand/raw/vf610_nfc.c | 38 +-
drivers/mtd/nand/raw/xway_nand.c | 2 +-
include/linux/mtd/rawnand.h | 150 ++--
38 files changed, 853 insertions(+), 752 deletions(-)
Series applied to nand/next.


Thanks,
Miquèl

Loading...