Commit 49c50b97 authored by Brian Norris's avatar Brian Norris

mtd: nand: refactor erase_cmd() to return chip status

The nand_chip::erase_cmd callback previously served a dual purpose; for
one, it allowed a per-flash-chip override, so that AG-AND devices could
use a different erase command than other NAND. These AND devices were
dropped in commit 14c65786 (mtd: nand:
remove AG-AND support). On the other hand, some drivers (denali and
doc-g4) need to use this sort of callback to implement
controller-specific erase operations.

To make the latter operation easier for some drivers (e.g., ST's new BCH
NAND driver), it helps if the command dispatch and wait functions can be
lumped together, rather than called separately.

This patch does two things:
 1. Pull the call to chip->waitfunc() into chip->erase_cmd(), and return
    the status from this callback
 2. Rename erase_cmd() to just erase(), since this callback does a
    little more than just send a command
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
Tested-by: default avatarLee Jones <lee.jones@linaro.org>
parent 35fc5195
...@@ -1233,7 +1233,7 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) ...@@ -1233,7 +1233,7 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
return status; return status;
} }
static void denali_erase(struct mtd_info *mtd, int page) static int denali_erase(struct mtd_info *mtd, int page)
{ {
struct denali_nand_info *denali = mtd_to_denali(mtd); struct denali_nand_info *denali = mtd_to_denali(mtd);
...@@ -1250,8 +1250,7 @@ static void denali_erase(struct mtd_info *mtd, int page) ...@@ -1250,8 +1250,7 @@ static void denali_erase(struct mtd_info *mtd, int page)
irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP | irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP |
INTR_STATUS__ERASE_FAIL); INTR_STATUS__ERASE_FAIL);
denali->status = (irq_status & INTR_STATUS__ERASE_FAIL) ? return (irq_status & INTR_STATUS__ERASE_FAIL) ? NAND_STATUS_FAIL : PASS;
NAND_STATUS_FAIL : PASS;
} }
static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
...@@ -1584,7 +1583,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1584,7 +1583,7 @@ int denali_init(struct denali_nand_info *denali)
denali->nand.ecc.write_page_raw = denali_write_page_raw; denali->nand.ecc.write_page_raw = denali_write_page_raw;
denali->nand.ecc.read_oob = denali_read_oob; denali->nand.ecc.read_oob = denali_read_oob;
denali->nand.ecc.write_oob = denali_write_oob; denali->nand.ecc.write_oob = denali_write_oob;
denali->nand.erase_cmd = denali_erase; denali->nand.erase = denali_erase;
if (nand_scan_tail(&denali->mtd)) { if (nand_scan_tail(&denali->mtd)) {
ret = -ENXIO; ret = -ENXIO;
......
...@@ -872,7 +872,7 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, ...@@ -872,7 +872,7 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
return 0; return 0;
} }
static void docg4_erase_block(struct mtd_info *mtd, int page) static int docg4_erase_block(struct mtd_info *mtd, int page)
{ {
struct nand_chip *nand = mtd->priv; struct nand_chip *nand = mtd->priv;
struct docg4_priv *doc = nand->priv; struct docg4_priv *doc = nand->priv;
...@@ -916,6 +916,8 @@ static void docg4_erase_block(struct mtd_info *mtd, int page) ...@@ -916,6 +916,8 @@ static void docg4_erase_block(struct mtd_info *mtd, int page)
write_nop(docptr); write_nop(docptr);
poll_status(doc); poll_status(doc);
write_nop(docptr); write_nop(docptr);
return nand->waitfunc(mtd, nand);
} }
static int write_page(struct mtd_info *mtd, struct nand_chip *nand, static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
...@@ -1236,7 +1238,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) ...@@ -1236,7 +1238,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
nand->block_markbad = docg4_block_markbad; nand->block_markbad = docg4_block_markbad;
nand->read_buf = docg4_read_buf; nand->read_buf = docg4_read_buf;
nand->write_buf = docg4_write_buf16; nand->write_buf = docg4_write_buf16;
nand->erase_cmd = docg4_erase_block; nand->erase = docg4_erase_block;
nand->ecc.read_page = docg4_read_page; nand->ecc.read_page = docg4_read_page;
nand->ecc.write_page = docg4_write_page; nand->ecc.write_page = docg4_write_page;
nand->ecc.read_page_raw = docg4_read_page_raw; nand->ecc.read_page_raw = docg4_read_page_raw;
......
...@@ -2617,18 +2617,20 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, ...@@ -2617,18 +2617,20 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
} }
/** /**
* single_erase_cmd - [GENERIC] NAND standard block erase command function * single_erase - [GENERIC] NAND standard block erase command function
* @mtd: MTD device structure * @mtd: MTD device structure
* @page: the page address of the block which will be erased * @page: the page address of the block which will be erased
* *
* Standard erase command for NAND chips. * Standard erase command for NAND chips. Returns NAND status.
*/ */
static void single_erase_cmd(struct mtd_info *mtd, int page) static int single_erase(struct mtd_info *mtd, int page)
{ {
struct nand_chip *chip = mtd->priv; struct nand_chip *chip = mtd->priv;
/* Send commands to erase a block */ /* Send commands to erase a block */
chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
return chip->waitfunc(mtd, chip);
} }
/** /**
...@@ -2709,9 +2711,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, ...@@ -2709,9 +2711,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
(page + pages_per_block)) (page + pages_per_block))
chip->pagebuf = -1; chip->pagebuf = -1;
chip->erase_cmd(mtd, page & chip->pagemask); status = chip->erase(mtd, page & chip->pagemask);
status = chip->waitfunc(mtd, chip);
/* /*
* See if operation failed and additional status checks are * See if operation failed and additional status checks are
...@@ -3684,7 +3684,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, ...@@ -3684,7 +3684,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
} }
chip->badblockbits = 8; chip->badblockbits = 8;
chip->erase_cmd = single_erase_cmd; chip->erase = single_erase;
/* Do not replace user supplied command function! */ /* Do not replace user supplied command function! */
if (mtd->writesize > 512 && chip->cmdfunc == nand_command) if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
......
...@@ -552,8 +552,7 @@ struct nand_buffers { ...@@ -552,8 +552,7 @@ struct nand_buffers {
* @ecc: [BOARDSPECIFIC] ECC control structure * @ecc: [BOARDSPECIFIC] ECC control structure
* @buffers: buffer structure for read/write * @buffers: buffer structure for read/write
* @hwcontrol: platform-specific hardware control structure * @hwcontrol: platform-specific hardware control structure
* @erase_cmd: [INTERN] erase command write function, selectable due * @erase: [REPLACEABLE] erase function
* to AND support.
* @scan_bbt: [REPLACEABLE] function to scan bad block table * @scan_bbt: [REPLACEABLE] function to scan bad block table
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
* data from array to read regs (tR). * data from array to read regs (tR).
...@@ -637,7 +636,7 @@ struct nand_chip { ...@@ -637,7 +636,7 @@ struct nand_chip {
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
int page_addr); int page_addr);
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this); int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
void (*erase_cmd)(struct mtd_info *mtd, int page); int (*erase)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd); int (*scan_bbt)(struct mtd_info *mtd);
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
int status, int page); int status, int page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment