[MTD NAND] Allocate chip->buffers separately to allow it to be overridden
In particular, the board driver might need it to be DMAable. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
parent
3b85c3211e
commit
4bf63fcb83
|
@ -767,8 +767,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
int eccbytes = chip->ecc.bytes;
|
int eccbytes = chip->ecc.bytes;
|
||||||
int eccsteps = chip->ecc.steps;
|
int eccsteps = chip->ecc.steps;
|
||||||
uint8_t *p = buf;
|
uint8_t *p = buf;
|
||||||
uint8_t *ecc_calc = chip->buffers.ecccalc;
|
uint8_t *ecc_calc = chip->buffers->ecccalc;
|
||||||
uint8_t *ecc_code = chip->buffers.ecccode;
|
uint8_t *ecc_code = chip->buffers->ecccode;
|
||||||
int *eccpos = chip->ecc.layout->eccpos;
|
int *eccpos = chip->ecc.layout->eccpos;
|
||||||
|
|
||||||
nand_read_page_raw(mtd, chip, buf);
|
nand_read_page_raw(mtd, chip, buf);
|
||||||
|
@ -809,8 +809,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
int eccbytes = chip->ecc.bytes;
|
int eccbytes = chip->ecc.bytes;
|
||||||
int eccsteps = chip->ecc.steps;
|
int eccsteps = chip->ecc.steps;
|
||||||
uint8_t *p = buf;
|
uint8_t *p = buf;
|
||||||
uint8_t *ecc_calc = chip->buffers.ecccalc;
|
uint8_t *ecc_calc = chip->buffers->ecccalc;
|
||||||
uint8_t *ecc_code = chip->buffers.ecccode;
|
uint8_t *ecc_code = chip->buffers->ecccode;
|
||||||
int *eccpos = chip->ecc.layout->eccpos;
|
int *eccpos = chip->ecc.layout->eccpos;
|
||||||
|
|
||||||
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||||
|
@ -971,7 +971,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
|
||||||
page = realpage & chip->pagemask;
|
page = realpage & chip->pagemask;
|
||||||
|
|
||||||
col = (int)(from & (mtd->writesize - 1));
|
col = (int)(from & (mtd->writesize - 1));
|
||||||
chip->oob_poi = chip->buffers.oobrbuf;
|
chip->oob_poi = chip->buffers->oobrbuf;
|
||||||
|
|
||||||
buf = ops->datbuf;
|
buf = ops->datbuf;
|
||||||
oob = ops->oobbuf;
|
oob = ops->oobbuf;
|
||||||
|
@ -982,7 +982,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
|
||||||
|
|
||||||
/* Is the current page in the buffer ? */
|
/* Is the current page in the buffer ? */
|
||||||
if (realpage != chip->pagebuf || oob) {
|
if (realpage != chip->pagebuf || oob) {
|
||||||
bufpoi = aligned ? buf : chip->buffers.databuf;
|
bufpoi = aligned ? buf : chip->buffers->databuf;
|
||||||
|
|
||||||
if (likely(sndcmd)) {
|
if (likely(sndcmd)) {
|
||||||
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
|
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
|
||||||
|
@ -997,7 +997,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
|
||||||
/* Transfer not aligned data */
|
/* Transfer not aligned data */
|
||||||
if (!aligned) {
|
if (!aligned) {
|
||||||
chip->pagebuf = realpage;
|
chip->pagebuf = realpage;
|
||||||
memcpy(buf, chip->buffers.databuf + col, bytes);
|
memcpy(buf, chip->buffers->databuf + col, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += bytes;
|
buf += bytes;
|
||||||
|
@ -1024,7 +1024,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
|
||||||
nand_wait_ready(mtd);
|
nand_wait_ready(mtd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(buf, chip->buffers.databuf + col, bytes);
|
memcpy(buf, chip->buffers->databuf + col, bytes);
|
||||||
buf += bytes;
|
buf += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,7 +1267,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
|
||||||
realpage = (int)(from >> chip->page_shift);
|
realpage = (int)(from >> chip->page_shift);
|
||||||
page = realpage & chip->pagemask;
|
page = realpage & chip->pagemask;
|
||||||
|
|
||||||
chip->oob_poi = chip->buffers.oobrbuf;
|
chip->oob_poi = chip->buffers->oobrbuf;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
|
sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
|
||||||
|
@ -1392,7 +1392,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
int i, eccsize = chip->ecc.size;
|
int i, eccsize = chip->ecc.size;
|
||||||
int eccbytes = chip->ecc.bytes;
|
int eccbytes = chip->ecc.bytes;
|
||||||
int eccsteps = chip->ecc.steps;
|
int eccsteps = chip->ecc.steps;
|
||||||
uint8_t *ecc_calc = chip->buffers.ecccalc;
|
uint8_t *ecc_calc = chip->buffers->ecccalc;
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = buf;
|
||||||
int *eccpos = chip->ecc.layout->eccpos;
|
int *eccpos = chip->ecc.layout->eccpos;
|
||||||
|
|
||||||
|
@ -1418,7 +1418,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
int i, eccsize = chip->ecc.size;
|
int i, eccsize = chip->ecc.size;
|
||||||
int eccbytes = chip->ecc.bytes;
|
int eccbytes = chip->ecc.bytes;
|
||||||
int eccsteps = chip->ecc.steps;
|
int eccsteps = chip->ecc.steps;
|
||||||
uint8_t *ecc_calc = chip->buffers.ecccalc;
|
uint8_t *ecc_calc = chip->buffers->ecccalc;
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = buf;
|
||||||
int *eccpos = chip->ecc.layout->eccpos;
|
int *eccpos = chip->ecc.layout->eccpos;
|
||||||
|
|
||||||
|
@ -1628,7 +1628,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
|
||||||
(chip->pagebuf << chip->page_shift) < (to + ops->len))
|
(chip->pagebuf << chip->page_shift) < (to + ops->len))
|
||||||
chip->pagebuf = -1;
|
chip->pagebuf = -1;
|
||||||
|
|
||||||
chip->oob_poi = chip->buffers.oobwbuf;
|
chip->oob_poi = chip->buffers->oobwbuf;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
int cached = writelen > bytes && page != blockmask;
|
int cached = writelen > bytes && page != blockmask;
|
||||||
|
@ -1746,7 +1746,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
|
||||||
if (page == chip->pagebuf)
|
if (page == chip->pagebuf)
|
||||||
chip->pagebuf = -1;
|
chip->pagebuf = -1;
|
||||||
|
|
||||||
chip->oob_poi = chip->buffers.oobwbuf;
|
chip->oob_poi = chip->buffers->oobwbuf;
|
||||||
memset(chip->oob_poi, 0xff, mtd->oobsize);
|
memset(chip->oob_poi, 0xff, mtd->oobsize);
|
||||||
nand_fill_oob(chip, ops->oobbuf, ops);
|
nand_fill_oob(chip, ops->oobbuf, ops);
|
||||||
status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
|
status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
|
||||||
|
@ -2354,8 +2354,13 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||||
int i;
|
int i;
|
||||||
struct nand_chip *chip = mtd->priv;
|
struct nand_chip *chip = mtd->priv;
|
||||||
|
|
||||||
|
if (!(chip->options & NAND_OWN_BUFFERS))
|
||||||
|
chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
|
||||||
|
if (!chip->buffers)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Preset the internal oob write buffer */
|
/* Preset the internal oob write buffer */
|
||||||
memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
|
memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no default placement scheme is given, select an appropriate one
|
* If no default placement scheme is given, select an appropriate one
|
||||||
|
@ -2559,6 +2564,8 @@ void nand_release(struct mtd_info *mtd)
|
||||||
|
|
||||||
/* Free bad block table memory */
|
/* Free bad block table memory */
|
||||||
kfree(chip->bbt);
|
kfree(chip->bbt);
|
||||||
|
if (!(chip->options & NAND_OWN_BUFFERS))
|
||||||
|
kfree(chip->buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(nand_scan);
|
EXPORT_SYMBOL_GPL(nand_scan);
|
||||||
|
|
|
@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
|
||||||
struct nand_chip *this = mtd->priv;
|
struct nand_chip *this = mtd->priv;
|
||||||
|
|
||||||
bd->options &= ~NAND_BBT_SCANEMPTY;
|
bd->options &= ~NAND_BBT_SCANEMPTY;
|
||||||
return create_bbt(mtd, this->buffers.databuf, bd, -1);
|
return create_bbt(mtd, this->buffers->databuf, bd, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -183,7 +183,9 @@ typedef enum {
|
||||||
#define NAND_USE_FLASH_BBT 0x00010000
|
#define NAND_USE_FLASH_BBT 0x00010000
|
||||||
/* This option skips the bbt scan during initialization. */
|
/* This option skips the bbt scan during initialization. */
|
||||||
#define NAND_SKIP_BBTSCAN 0x00020000
|
#define NAND_SKIP_BBTSCAN 0x00020000
|
||||||
|
/* This option is defined if the board driver allocates its own buffers
|
||||||
|
(e.g. because it needs them DMA-coherent */
|
||||||
|
#define NAND_OWN_BUFFERS 0x00040000
|
||||||
/* Options set by nand scan */
|
/* Options set by nand scan */
|
||||||
/* Nand scan has allocated controller struct */
|
/* Nand scan has allocated controller struct */
|
||||||
#define NAND_CONTROLLER_ALLOC 0x80000000
|
#define NAND_CONTROLLER_ALLOC 0x80000000
|
||||||
|
@ -385,7 +387,7 @@ struct nand_chip {
|
||||||
struct nand_ecclayout *ecclayout;
|
struct nand_ecclayout *ecclayout;
|
||||||
|
|
||||||
struct nand_ecc_ctrl ecc;
|
struct nand_ecc_ctrl ecc;
|
||||||
struct nand_buffers buffers;
|
struct nand_buffers *buffers;
|
||||||
struct nand_hw_control hwcontrol;
|
struct nand_hw_control hwcontrol;
|
||||||
|
|
||||||
struct mtd_oob_ops ops;
|
struct mtd_oob_ops ops;
|
||||||
|
|
Loading…
Reference in New Issue