aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-09-25 12:08:04 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-09-25 12:08:04 -0400
commit4bf63fcb83dc761853f69a77b15e47712689020b (patch)
tree6afae2f5f45eed231967f05e1f0a887136756211
parent3b85c3211ebde263a86c8cd3c7277fdd2e440310 (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.c35
-rw-r--r--drivers/mtd/nand/nand_bbt.c2
-rw-r--r--include/linux/mtd/nand.h6
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
2564EXPORT_SYMBOL_GPL(nand_scan); 2571EXPORT_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;