diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2006-09-25 12:08:04 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@infradead.org> | 2006-09-25 12:08:04 -0400 |
| commit | 4bf63fcb83dc761853f69a77b15e47712689020b (patch) | |
| tree | 6afae2f5f45eed231967f05e1f0a887136756211 | |
| parent | 3b85c3211ebde263a86c8cd3c7277fdd2e440310 (diff) | |
[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>
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 35 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 2 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 6 |
3 files changed, 26 insertions, 17 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 492ff9d1a35c..e1e81a9543e8 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -767,8 +767,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 767 | int eccbytes = chip->ecc.bytes; | 767 | int eccbytes = chip->ecc.bytes; |
| 768 | int eccsteps = chip->ecc.steps; | 768 | int eccsteps = chip->ecc.steps; |
| 769 | uint8_t *p = buf; | 769 | uint8_t *p = buf; |
| 770 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 770 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
| 771 | uint8_t *ecc_code = chip->buffers.ecccode; | 771 | uint8_t *ecc_code = chip->buffers->ecccode; |
| 772 | int *eccpos = chip->ecc.layout->eccpos; | 772 | int *eccpos = chip->ecc.layout->eccpos; |
| 773 | 773 | ||
| 774 | nand_read_page_raw(mtd, chip, buf); | 774 | 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, | |||
| 809 | int eccbytes = chip->ecc.bytes; | 809 | int eccbytes = chip->ecc.bytes; |
| 810 | int eccsteps = chip->ecc.steps; | 810 | int eccsteps = chip->ecc.steps; |
| 811 | uint8_t *p = buf; | 811 | uint8_t *p = buf; |
| 812 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 812 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
| 813 | uint8_t *ecc_code = chip->buffers.ecccode; | 813 | uint8_t *ecc_code = chip->buffers->ecccode; |
| 814 | int *eccpos = chip->ecc.layout->eccpos; | 814 | int *eccpos = chip->ecc.layout->eccpos; |
| 815 | 815 | ||
| 816 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | 816 | 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, | |||
| 971 | page = realpage & chip->pagemask; | 971 | page = realpage & chip->pagemask; |
| 972 | 972 | ||
| 973 | col = (int)(from & (mtd->writesize - 1)); | 973 | col = (int)(from & (mtd->writesize - 1)); |
| 974 | chip->oob_poi = chip->buffers.oobrbuf; | 974 | chip->oob_poi = chip->buffers->oobrbuf; |
| 975 | 975 | ||
| 976 | buf = ops->datbuf; | 976 | buf = ops->datbuf; |
| 977 | oob = ops->oobbuf; | 977 | oob = ops->oobbuf; |
| @@ -982,7 +982,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 982 | 982 | ||
| 983 | /* Is the current page in the buffer ? */ | 983 | /* Is the current page in the buffer ? */ |
| 984 | if (realpage != chip->pagebuf || oob) { | 984 | if (realpage != chip->pagebuf || oob) { |
| 985 | bufpoi = aligned ? buf : chip->buffers.databuf; | 985 | bufpoi = aligned ? buf : chip->buffers->databuf; |
| 986 | 986 | ||
| 987 | if (likely(sndcmd)) { | 987 | if (likely(sndcmd)) { |
| 988 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | 988 | 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, | |||
| 997 | /* Transfer not aligned data */ | 997 | /* Transfer not aligned data */ |
| 998 | if (!aligned) { | 998 | if (!aligned) { |
| 999 | chip->pagebuf = realpage; | 999 | chip->pagebuf = realpage; |
| 1000 | memcpy(buf, chip->buffers.databuf + col, bytes); | 1000 | memcpy(buf, chip->buffers->databuf + col, bytes); |
| 1001 | } | 1001 | } |
| 1002 | 1002 | ||
| 1003 | buf += bytes; | 1003 | buf += bytes; |
| @@ -1024,7 +1024,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1024 | nand_wait_ready(mtd); | 1024 | nand_wait_ready(mtd); |
| 1025 | } | 1025 | } |
| 1026 | } else { | 1026 | } else { |
| 1027 | memcpy(buf, chip->buffers.databuf + col, bytes); | 1027 | memcpy(buf, chip->buffers->databuf + col, bytes); |
| 1028 | buf += bytes; | 1028 | buf += bytes; |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| @@ -1267,7 +1267,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
| 1267 | realpage = (int)(from >> chip->page_shift); | 1267 | realpage = (int)(from >> chip->page_shift); |
| 1268 | page = realpage & chip->pagemask; | 1268 | page = realpage & chip->pagemask; |
| 1269 | 1269 | ||
| 1270 | chip->oob_poi = chip->buffers.oobrbuf; | 1270 | chip->oob_poi = chip->buffers->oobrbuf; |
| 1271 | 1271 | ||
| 1272 | while(1) { | 1272 | while(1) { |
| 1273 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); | 1273 | 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, | |||
| 1392 | int i, eccsize = chip->ecc.size; | 1392 | int i, eccsize = chip->ecc.size; |
| 1393 | int eccbytes = chip->ecc.bytes; | 1393 | int eccbytes = chip->ecc.bytes; |
| 1394 | int eccsteps = chip->ecc.steps; | 1394 | int eccsteps = chip->ecc.steps; |
| 1395 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 1395 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
| 1396 | const uint8_t *p = buf; | 1396 | const uint8_t *p = buf; |
| 1397 | int *eccpos = chip->ecc.layout->eccpos; | 1397 | int *eccpos = chip->ecc.layout->eccpos; |
| 1398 | 1398 | ||
| @@ -1418,7 +1418,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1418 | int i, eccsize = chip->ecc.size; | 1418 | int i, eccsize = chip->ecc.size; |
| 1419 | int eccbytes = chip->ecc.bytes; | 1419 | int eccbytes = chip->ecc.bytes; |
| 1420 | int eccsteps = chip->ecc.steps; | 1420 | int eccsteps = chip->ecc.steps; |
| 1421 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 1421 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
| 1422 | const uint8_t *p = buf; | 1422 | const uint8_t *p = buf; |
| 1423 | int *eccpos = chip->ecc.layout->eccpos; | 1423 | int *eccpos = chip->ecc.layout->eccpos; |
| 1424 | 1424 | ||
| @@ -1628,7 +1628,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
| 1628 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) | 1628 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) |
| 1629 | chip->pagebuf = -1; | 1629 | chip->pagebuf = -1; |
| 1630 | 1630 | ||
| 1631 | chip->oob_poi = chip->buffers.oobwbuf; | 1631 | chip->oob_poi = chip->buffers->oobwbuf; |
| 1632 | 1632 | ||
| 1633 | while(1) { | 1633 | while(1) { |
| 1634 | int cached = writelen > bytes && page != blockmask; | 1634 | int cached = writelen > bytes && page != blockmask; |
| @@ -1746,7 +1746,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
| 1746 | if (page == chip->pagebuf) | 1746 | if (page == chip->pagebuf) |
| 1747 | chip->pagebuf = -1; | 1747 | chip->pagebuf = -1; |
| 1748 | 1748 | ||
| 1749 | chip->oob_poi = chip->buffers.oobwbuf; | 1749 | chip->oob_poi = chip->buffers->oobwbuf; |
| 1750 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 1750 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
| 1751 | nand_fill_oob(chip, ops->oobbuf, ops); | 1751 | nand_fill_oob(chip, ops->oobbuf, ops); |
| 1752 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); | 1752 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); |
| @@ -2354,8 +2354,13 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
| 2354 | int i; | 2354 | int i; |
| 2355 | struct nand_chip *chip = mtd->priv; | 2355 | struct nand_chip *chip = mtd->priv; |
| 2356 | 2356 | ||
| 2357 | if (!(chip->options & NAND_OWN_BUFFERS)) | ||
| 2358 | chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); | ||
| 2359 | if (!chip->buffers) | ||
| 2360 | return -ENOMEM; | ||
| 2361 | |||
| 2357 | /* Preset the internal oob write buffer */ | 2362 | /* Preset the internal oob write buffer */ |
| 2358 | memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize); | 2363 | memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize); |
| 2359 | 2364 | ||
| 2360 | /* | 2365 | /* |
| 2361 | * If no default placement scheme is given, select an appropriate one | 2366 | * If no default placement scheme is given, select an appropriate one |
| @@ -2559,6 +2564,8 @@ void nand_release(struct mtd_info *mtd) | |||
| 2559 | 2564 | ||
| 2560 | /* Free bad block table memory */ | 2565 | /* Free bad block table memory */ |
| 2561 | kfree(chip->bbt); | 2566 | kfree(chip->bbt); |
| 2567 | if (!(chip->options & NAND_OWN_BUFFERS)) | ||
| 2568 | kfree(chip->buffers); | ||
| 2562 | } | 2569 | } |
| 2563 | 2570 | ||
| 2564 | EXPORT_SYMBOL_GPL(nand_scan); | 2571 | EXPORT_SYMBOL_GPL(nand_scan); |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index a612c4ea8194..9402653eb09b 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
| @@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b | |||
| 759 | struct nand_chip *this = mtd->priv; | 759 | struct nand_chip *this = mtd->priv; |
| 760 | 760 | ||
| 761 | bd->options &= ~NAND_BBT_SCANEMPTY; | 761 | bd->options &= ~NAND_BBT_SCANEMPTY; |
| 762 | return create_bbt(mtd, this->buffers.databuf, bd, -1); | 762 | return create_bbt(mtd, this->buffers->databuf, bd, -1); |
| 763 | } | 763 | } |
| 764 | 764 | ||
| 765 | /** | 765 | /** |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 88d690d79d77..cd4fe9ae8622 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
| @@ -183,7 +183,9 @@ typedef enum { | |||
| 183 | #define NAND_USE_FLASH_BBT 0x00010000 | 183 | #define NAND_USE_FLASH_BBT 0x00010000 |
| 184 | /* This option skips the bbt scan during initialization. */ | 184 | /* This option skips the bbt scan during initialization. */ |
| 185 | #define NAND_SKIP_BBTSCAN 0x00020000 | 185 | #define NAND_SKIP_BBTSCAN 0x00020000 |
| 186 | 186 | /* This option is defined if the board driver allocates its own buffers | |
| 187 | (e.g. because it needs them DMA-coherent */ | ||
| 188 | #define NAND_OWN_BUFFERS 0x00040000 | ||
| 187 | /* Options set by nand scan */ | 189 | /* Options set by nand scan */ |
| 188 | /* Nand scan has allocated controller struct */ | 190 | /* Nand scan has allocated controller struct */ |
| 189 | #define NAND_CONTROLLER_ALLOC 0x80000000 | 191 | #define NAND_CONTROLLER_ALLOC 0x80000000 |
| @@ -385,7 +387,7 @@ struct nand_chip { | |||
| 385 | struct nand_ecclayout *ecclayout; | 387 | struct nand_ecclayout *ecclayout; |
| 386 | 388 | ||
| 387 | struct nand_ecc_ctrl ecc; | 389 | struct nand_ecc_ctrl ecc; |
| 388 | struct nand_buffers buffers; | 390 | struct nand_buffers *buffers; |
| 389 | struct nand_hw_control hwcontrol; | 391 | struct nand_hw_control hwcontrol; |
| 390 | 392 | ||
| 391 | struct mtd_oob_ops ops; | 393 | struct mtd_oob_ops ops; |
