aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-10-19 21:11:40 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-10-19 21:11:40 -0400
commit8dd851de8184bb39c4ea86de20a0ed2496e6eb0d (patch)
treec391ac32f289e335628a00d0e9cc4f55acfccb27 /drivers/mtd/nand
parent5467fb025537eb92313fd3a557b2051cb41ba5e8 (diff)
[MTD NAND] OLPC CAFÉ driver update
- Fix OOB handling, bad block table marker placement - Some cleanups, enable runtime-optional debugging - Allow BBT stuff to be skipped Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/cafe_nand.c135
1 files changed, 99 insertions, 36 deletions
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 8d7a795a9478..60cb019b1406 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -5,7 +5,7 @@
5 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org> 5 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
6 */ 6 */
7 7
8//#define DEBUG 8#define DEBUG
9 9
10#include <linux/device.h> 10#include <linux/device.h>
11#undef DEBUG 11#undef DEBUG
@@ -53,15 +53,24 @@ struct cafe_priv {
53static int usedma = 1; 53static int usedma = 1;
54module_param(usedma, int, 0644); 54module_param(usedma, int, 0644);
55 55
56static int skipbbt = 0;
57module_param(skipbbt, int, 0644);
58
59static int debug = 0;
60module_param(debug, int, 0644);
61
62#define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
63
64
56static int cafe_device_ready(struct mtd_info *mtd) 65static int cafe_device_ready(struct mtd_info *mtd)
57{ 66{
58 struct cafe_priv *cafe = mtd->priv; 67 struct cafe_priv *cafe = mtd->priv;
59 int result = !!(readl(cafe->mmio + CAFE_NAND_STATUS) | 0x40000000); 68 int result = !!(readl(cafe->mmio + CAFE_NAND_STATUS) | 0x40000000);
60 69
61 uint32_t irqs = readl(cafe->mmio + 0x10); 70 uint32_t irqs = readl(cafe->mmio + CAFE_NAND_IRQ);
62 writel(irqs, cafe->mmio+0x10); 71 writel(irqs, cafe->mmio+CAFE_NAND_IRQ);
63 dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n", 72 cafe_dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n",
64 result?"":" not", irqs, readl(cafe->mmio + 0x10), 73 result?"":" not", irqs, readl(cafe->mmio + CAFE_NAND_IRQ),
65 readl(cafe->mmio + 0x3008), readl(cafe->mmio + 0x300c)); 74 readl(cafe->mmio + 0x3008), readl(cafe->mmio + 0x300c));
66 return result; 75 return result;
67} 76}
@@ -77,7 +86,7 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
77 memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA + cafe->datalen, buf, len); 86 memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA + cafe->datalen, buf, len);
78 cafe->datalen += len; 87 cafe->datalen += len;
79 88
80 dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n", 89 cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n",
81 len, cafe->datalen); 90 len, cafe->datalen);
82} 91}
83 92
@@ -90,7 +99,7 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
90 else 99 else
91 memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA + cafe->datalen, len); 100 memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA + cafe->datalen, len);
92 101
93 dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n", 102 cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n",
94 len, cafe->datalen); 103 len, cafe->datalen);
95 cafe->datalen += len; 104 cafe->datalen += len;
96} 105}
@@ -101,7 +110,7 @@ static uint8_t cafe_read_byte(struct mtd_info *mtd)
101 uint8_t d; 110 uint8_t d;
102 111
103 cafe_read_buf(mtd, &d, 1); 112 cafe_read_buf(mtd, &d, 1);
104 dev_dbg(&cafe->pdev->dev, "Read %02x\n", d); 113 cafe_dev_dbg(&cafe->pdev->dev, "Read %02x\n", d);
105 114
106 return d; 115 return d;
107} 116}
@@ -115,14 +124,14 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
115 uint32_t doneint = 0x80000000; 124 uint32_t doneint = 0x80000000;
116 int i; 125 int i;
117 126
118 dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n", 127 cafe_dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
119 command, column, page_addr); 128 command, column, page_addr);
120 129
121 if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) { 130 if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) {
122 /* Second half of a command we already calculated */ 131 /* Second half of a command we already calculated */
123 writel(cafe->ctl2 | 0x100 | command, cafe->mmio + 0x04); 132 writel(cafe->ctl2 | 0x100 | command, cafe->mmio + 0x04);
124 ctl1 = cafe->ctl1; 133 ctl1 = cafe->ctl1;
125 dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n", 134 cafe_dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
126 cafe->ctl1, cafe->nr_data); 135 cafe->ctl1, cafe->nr_data);
127 goto do_command; 136 goto do_command;
128 } 137 }
@@ -163,7 +172,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
163 if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) { 172 if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
164 ctl1 |= (1<<26); /* rd */ 173 ctl1 |= (1<<26); /* rd */
165 /* Always 5 bytes, for now */ 174 /* Always 5 bytes, for now */
166 cafe->datalen = 5; 175 cafe->datalen = 4;
167 /* And one address cycle -- even for STATUS, since the controller doesn't work without */ 176 /* And one address cycle -- even for STATUS, since the controller doesn't work without */
168 adrbytes = 1; 177 adrbytes = 1;
169 } else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || 178 } else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
@@ -183,7 +192,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
183 deals with them both at once, later */ 192 deals with them both at once, later */
184 cafe->ctl1 = ctl1; 193 cafe->ctl1 = ctl1;
185 cafe->ctl2 = 0; 194 cafe->ctl2 = 0;
186 dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n", 195 cafe_dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n",
187 cafe->ctl1, cafe->datalen); 196 cafe->ctl1, cafe->datalen);
188 return; 197 return;
189 } 198 }
@@ -194,13 +203,14 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
194 writel(cafe->ctl2 | 0x100 | NAND_CMD_READSTART, cafe->mmio + CAFE_NAND_CTRL2); 203 writel(cafe->ctl2 | 0x100 | NAND_CMD_READSTART, cafe->mmio + CAFE_NAND_CTRL2);
195 204
196 do_command: 205 do_command:
197 if (cafe->datalen == 2112) 206 // ECC on read only works if we ...
198 cafe->datalen = 2062; 207 // if (cafe->datalen == 2112)
199 dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n", 208 // cafe->datalen = 2062;
209 cafe_dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
200 cafe->datalen, ctl1, readl(cafe->mmio+CAFE_NAND_CTRL2)); 210 cafe->datalen, ctl1, readl(cafe->mmio+CAFE_NAND_CTRL2));
201 /* NB: The datasheet lies -- we really should be subtracting 1 here */ 211 /* NB: The datasheet lies -- we really should be subtracting 1 here */
202 writel(cafe->datalen, cafe->mmio + CAFE_NAND_DATA_LEN); 212 writel(cafe->datalen, cafe->mmio + CAFE_NAND_DATA_LEN);
203 writel(0x90000000, cafe->mmio + 0x10); 213 writel(0x90000000, cafe->mmio + CAFE_NAND_IRQ);
204 if (usedma && (ctl1 & (3<<25))) { 214 if (usedma && (ctl1 & (3<<25))) {
205 uint32_t dmactl = 0xc0000000 + cafe->datalen; 215 uint32_t dmactl = 0xc0000000 + cafe->datalen;
206 /* If WR or RD bits set, set up DMA */ 216 /* If WR or RD bits set, set up DMA */
@@ -230,20 +240,20 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
230 ndelay(100); 240 ndelay(100);
231 241
232 if (1) { 242 if (1) {
233 int c = 50000; 243 int c = 500000;
234 uint32_t irqs; 244 uint32_t irqs;
235 245
236 while (c--) { 246 while (c--) {
237 irqs = readl(cafe->mmio + 0x10); 247 irqs = readl(cafe->mmio + CAFE_NAND_IRQ);
238 if (irqs & doneint) 248 if (irqs & doneint)
239 break; 249 break;
240 udelay(1); 250 udelay(1);
241 if (!(c & 1000)) 251 if (!(c % 100000))
242 dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs); 252 cafe_dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs);
243 cpu_relax(); 253 cpu_relax();
244 } 254 }
245 writel(doneint, cafe->mmio + 0x10); 255 writel(doneint, cafe->mmio + CAFE_NAND_IRQ);
246 dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n", command, 50000-c, irqs, readl(cafe->mmio + 0x10)); 256 cafe_dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n", command, 50000-c, irqs, readl(cafe->mmio + CAFE_NAND_IRQ));
247 } 257 }
248 258
249 259
@@ -276,18 +286,18 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
276static void cafe_select_chip(struct mtd_info *mtd, int chipnr) 286static void cafe_select_chip(struct mtd_info *mtd, int chipnr)
277{ 287{
278 //struct cafe_priv *cafe = mtd->priv; 288 //struct cafe_priv *cafe = mtd->priv;
279 // dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); 289 // cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
280} 290}
281static int cafe_nand_interrupt(int irq, void *id, struct pt_regs *regs) 291static int cafe_nand_interrupt(int irq, void *id, struct pt_regs *regs)
282{ 292{
283 struct mtd_info *mtd = id; 293 struct mtd_info *mtd = id;
284 struct cafe_priv *cafe = mtd->priv; 294 struct cafe_priv *cafe = mtd->priv;
285 uint32_t irqs = readl(cafe->mmio + 0x10); 295 uint32_t irqs = readl(cafe->mmio + CAFE_NAND_IRQ);
286 writel(irqs & ~0x90000000, cafe->mmio + 0x10); 296 writel(irqs & ~0x90000000, cafe->mmio + CAFE_NAND_IRQ);
287 if (!irqs) 297 if (!irqs)
288 return IRQ_NONE; 298 return IRQ_NONE;
289 299
290 dev_dbg(&cafe->pdev->dev, "irq, bits %x (%x)\n", irqs, readl(cafe->mmio + 0x10)); 300 cafe_dev_dbg(&cafe->pdev->dev, "irq, bits %x (%x)\n", irqs, readl(cafe->mmio + CAFE_NAND_IRQ));
291 return IRQ_HANDLED; 301 return IRQ_HANDLED;
292} 302}
293 303
@@ -335,7 +345,7 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
335 345
336 WARN_ON(chip->oob_poi != chip->buffers->oobrbuf); 346 WARN_ON(chip->oob_poi != chip->buffers->oobrbuf);
337 347
338 dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", readl(cafe->mmio + 0x3c), readl(cafe->mmio + 0x50)); 348 cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", readl(cafe->mmio + 0x3c), readl(cafe->mmio + 0x50));
339 349
340 chip->read_buf(mtd, buf, mtd->writesize); 350 chip->read_buf(mtd, buf, mtd->writesize);
341 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); 351 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -343,7 +353,44 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
343 return 0; 353 return 0;
344} 354}
345 355
346static char foo[14]; 356static struct nand_ecclayout cafe_oobinfo_2048 = {
357 .eccbytes = 14,
358 .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
359 .oobfree = {{14, 50}}
360};
361
362/* Ick. The BBT code really ought to be able to work this bit out
363 for itself from the above */
364static uint8_t cafe_bbt_pattern[] = {'B', 'b', 't', '0' };
365static uint8_t cafe_mirror_pattern[] = {'1', 't', 'b', 'B' };
366
367static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
368 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
369 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
370 .offs = 14,
371 .len = 4,
372 .veroffs = 18,
373 .maxblocks = 4,
374 .pattern = cafe_bbt_pattern
375};
376
377static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = {
378 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
379 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
380 .offs = 14,
381 .len = 4,
382 .veroffs = 18,
383 .maxblocks = 4,
384 .pattern = cafe_mirror_pattern
385};
386
387static struct nand_ecclayout cafe_oobinfo_512 = {
388 .eccbytes = 14,
389 .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
390 .oobfree = {{14, 2}}
391};
392
393
347static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, 394static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
348 struct nand_chip *chip, const uint8_t *buf) 395 struct nand_chip *chip, const uint8_t *buf)
349{ 396{
@@ -352,8 +399,7 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
352 WARN_ON(chip->oob_poi != chip->buffers->oobwbuf); 399 WARN_ON(chip->oob_poi != chip->buffers->oobwbuf);
353 400
354 chip->write_buf(mtd, buf, mtd->writesize); 401 chip->write_buf(mtd, buf, mtd->writesize);
355 chip->write_buf(mtd, foo, 14); 402 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
356 // chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
357 403
358 /* Set up ECC autogeneration */ 404 /* Set up ECC autogeneration */
359 cafe->ctl2 |= (1<<27) | (1<<30); 405 cafe->ctl2 |= (1<<27) | (1<<30);
@@ -410,6 +456,10 @@ static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
410 return 0; 456 return 0;
411} 457}
412 458
459static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
460{
461 return 0;
462}
413 463
414static int __devinit cafe_nand_probe(struct pci_dev *pdev, 464static int __devinit cafe_nand_probe(struct pci_dev *pdev,
415 const struct pci_device_id *ent) 465 const struct pci_device_id *ent)
@@ -461,6 +511,11 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
461 511
462 /* Enable the following for a flash based bad block table */ 512 /* Enable the following for a flash based bad block table */
463 cafe->nand.options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR | NAND_OWN_BUFFERS; 513 cafe->nand.options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR | NAND_OWN_BUFFERS;
514
515 if (skipbbt) {
516 cafe->nand.options |= NAND_SKIP_BBTSCAN;
517 cafe->nand.block_bad = cafe_nand_block_bad;
518 }
464 519
465 /* Timings from Marvell's test code (not verified or calculated by us) */ 520 /* Timings from Marvell's test code (not verified or calculated by us) */
466 writel(0xffffffff, cafe->mmio + CAFE_NAND_IRQ_MASK); 521 writel(0xffffffff, cafe->mmio + CAFE_NAND_IRQ_MASK);
@@ -473,7 +528,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
473 writel(0xffffffff, cafe->mmio + CAFE_NAND_TIMING2); 528 writel(0xffffffff, cafe->mmio + CAFE_NAND_TIMING2);
474 writel(0xffffffff, cafe->mmio + CAFE_NAND_TIMING3); 529 writel(0xffffffff, cafe->mmio + CAFE_NAND_TIMING3);
475#endif 530#endif
476 writel(0xdfffffff, cafe->mmio + 0x14); 531 writel(0xffffffff, cafe->mmio + CAFE_NAND_IRQ_MASK);
477 err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd); 532 err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd);
478 if (err) { 533 if (err) {
479 dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); 534 dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq);
@@ -498,18 +553,18 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
498 writel((cafe->dmaaddr >> 16) >> 16, cafe->mmio + 0x48); 553 writel((cafe->dmaaddr >> 16) >> 16, cafe->mmio + 0x48);
499 else 554 else
500 writel(0, cafe->mmio + 0x48); 555 writel(0, cafe->mmio + 0x48);
501 dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n", 556 cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n",
502 readl(cafe->mmio+0x44), cafe->dmabuf); 557 readl(cafe->mmio+0x44), cafe->dmabuf);
503 558
504 /* Enable NAND IRQ in global IRQ mask register */ 559 /* Enable NAND IRQ in global IRQ mask register */
505 writel(0x80000007, cafe->mmio + 0x300c); 560 writel(0x80000007, cafe->mmio + 0x300c);
506 dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", 561 cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
507 readl(cafe->mmio + 0x3004), readl(cafe->mmio + 0x300c)); 562 readl(cafe->mmio + 0x3004), readl(cafe->mmio + 0x300c));
508#endif 563#endif
509#if 1 564#if 1
510 mtd->writesize=2048; 565 mtd->writesize=2048;
511 mtd->oobsize = 0x40; 566 mtd->oobsize = 0x40;
512 memset(cafe->dmabuf, 0xa5, 2112); 567 memset(cafe->dmabuf, 0x5a, 2112);
513 cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1); 568 cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1);
514 cafe->nand.read_byte(mtd); 569 cafe->nand.read_byte(mtd);
515 cafe->nand.read_byte(mtd); 570 cafe->nand.read_byte(mtd);
@@ -528,7 +583,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
528#if 0 583#if 0
529 writel(0x84600070, cafe->mmio); 584 writel(0x84600070, cafe->mmio);
530 udelay(10); 585 udelay(10);
531 dev_dbg(&cafe->pdev->dev, "Status %x\n", readl(cafe->mmio + 0x30)); 586 cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", readl(cafe->mmio + 0x30));
532#endif 587#endif
533 /* Scan to find existance of the device */ 588 /* Scan to find existance of the device */
534 if (nand_scan_ident(mtd, 1)) { 589 if (nand_scan_ident(mtd, 1)) {
@@ -545,6 +600,9 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
545 cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; 600 cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
546 cafe->nand.ecc.size = mtd->writesize; 601 cafe->nand.ecc.size = mtd->writesize;
547 cafe->nand.ecc.bytes = 14; 602 cafe->nand.ecc.bytes = 14;
603 cafe->nand.ecc.layout = &cafe_oobinfo_2048;
604 cafe->nand.bbt_td = &cafe_bbt_main_descr_2048;
605 cafe->nand.bbt_md = &cafe_bbt_mirror_descr_2048;
548 cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; 606 cafe->nand.ecc.hwctl = (void *)cafe_nand_bug;
549 cafe->nand.ecc.calculate = (void *)cafe_nand_bug; 607 cafe->nand.ecc.calculate = (void *)cafe_nand_bug;
550 cafe->nand.ecc.correct = (void *)cafe_nand_bug; 608 cafe->nand.ecc.correct = (void *)cafe_nand_bug;
@@ -564,7 +622,6 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
564 if (err) 622 if (err)
565 goto out_irq; 623 goto out_irq;
566 624
567
568 pci_set_drvdata(pdev, mtd); 625 pci_set_drvdata(pdev, mtd);
569 add_mtd_device(mtd); 626 add_mtd_device(mtd);
570 goto out; 627 goto out;
@@ -633,3 +690,9 @@ MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip");
633 690
634/* Correct ECC for 2048 bytes of 0xff: 691/* Correct ECC for 2048 bytes of 0xff:
635 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */ 692 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */
693
694/* dwmw2's B-test board, in case of completely screwing it:
695Bad eraseblock 2394 at 0x12b40000
696Bad eraseblock 2627 at 0x14860000
697Bad eraseblock 3349 at 0x1a2a0000
698*/