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; |