aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/sh_flctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/sh_flctl.c')
-rw-r--r--drivers/mtd/nand/sh_flctl.c327
1 files changed, 181 insertions, 146 deletions
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index aa9b8a5e0b8f..4fbfe96e37a1 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -24,10 +24,12 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/interrupt.h>
27#include <linux/io.h> 28#include <linux/io.h>
28#include <linux/platform_device.h> 29#include <linux/platform_device.h>
29#include <linux/pm_runtime.h> 30#include <linux/pm_runtime.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/string.h>
31 33
32#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
33#include <linux/mtd/nand.h> 35#include <linux/mtd/nand.h>
@@ -43,11 +45,17 @@ static struct nand_ecclayout flctl_4secc_oob_16 = {
43}; 45};
44 46
45static struct nand_ecclayout flctl_4secc_oob_64 = { 47static struct nand_ecclayout flctl_4secc_oob_64 = {
46 .eccbytes = 10, 48 .eccbytes = 4 * 10,
47 .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57}, 49 .eccpos = {
50 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
51 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
52 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
53 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
48 .oobfree = { 54 .oobfree = {
49 {.offset = 60, 55 {.offset = 2, .length = 4},
50 . length = 4} }, 56 {.offset = 16, .length = 6},
57 {.offset = 32, .length = 6},
58 {.offset = 48, .length = 6} },
51}; 59};
52 60
53static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 61static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -61,15 +69,15 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
61 69
62static struct nand_bbt_descr flctl_4secc_largepage = { 70static struct nand_bbt_descr flctl_4secc_largepage = {
63 .options = NAND_BBT_SCAN2NDPAGE, 71 .options = NAND_BBT_SCAN2NDPAGE,
64 .offs = 58, 72 .offs = 0,
65 .len = 2, 73 .len = 2,
66 .pattern = scan_ff_pattern, 74 .pattern = scan_ff_pattern,
67}; 75};
68 76
69static void empty_fifo(struct sh_flctl *flctl) 77static void empty_fifo(struct sh_flctl *flctl)
70{ 78{
71 writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */ 79 writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl));
72 writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */ 80 writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
73} 81}
74 82
75static void start_translation(struct sh_flctl *flctl) 83static void start_translation(struct sh_flctl *flctl)
@@ -158,27 +166,56 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
158 timeout_error(flctl, __func__); 166 timeout_error(flctl, __func__);
159} 167}
160 168
161static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number) 169static enum flctl_ecc_res_t wait_recfifo_ready
170 (struct sh_flctl *flctl, int sector_number)
162{ 171{
163 uint32_t timeout = LOOP_TIMEOUT_MAX; 172 uint32_t timeout = LOOP_TIMEOUT_MAX;
164 int checked[4];
165 void __iomem *ecc_reg[4]; 173 void __iomem *ecc_reg[4];
166 int i; 174 int i;
175 int state = FL_SUCCESS;
167 uint32_t data, size; 176 uint32_t data, size;
168 177
169 memset(checked, 0, sizeof(checked)); 178 /*
170 179 * First this loops checks in FLDTCNTR if we are ready to read out the
180 * oob data. This is the case if either all went fine without errors or
181 * if the bottom part of the loop corrected the errors or marked them as
182 * uncorrectable and the controller is given time to push the data into
183 * the FIFO.
184 */
171 while (timeout--) { 185 while (timeout--) {
186 /* check if all is ok and we can read out the OOB */
172 size = readl(FLDTCNTR(flctl)) >> 24; 187 size = readl(FLDTCNTR(flctl)) >> 24;
173 if (size & 0xFF) 188 if ((size & 0xFF) == 4)
174 return 0; /* success */ 189 return state;
190
191 /* check if a correction code has been calculated */
192 if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) {
193 /*
194 * either we wait for the fifo to be filled or a
195 * correction pattern is being generated
196 */
197 udelay(1);
198 continue;
199 }
175 200
176 if (readl(FL4ECCCR(flctl)) & _4ECCFA) 201 /* check for an uncorrectable error */
177 return 1; /* can't correct */ 202 if (readl(FL4ECCCR(flctl)) & _4ECCFA) {
203 /* check if we face a non-empty page */
204 for (i = 0; i < 512; i++) {
205 if (flctl->done_buff[i] != 0xff) {
206 state = FL_ERROR; /* can't correct */
207 break;
208 }
209 }
178 210
179 udelay(1); 211 if (state == FL_SUCCESS)
180 if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) 212 dev_dbg(&flctl->pdev->dev,
213 "reading empty sector %d, ecc error ignored\n",
214 sector_number);
215
216 writel(0, FL4ECCCR(flctl));
181 continue; 217 continue;
218 }
182 219
183 /* start error correction */ 220 /* start error correction */
184 ecc_reg[0] = FL4ECCRESULT0(flctl); 221 ecc_reg[0] = FL4ECCRESULT0(flctl);
@@ -187,28 +224,26 @@ static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
187 ecc_reg[3] = FL4ECCRESULT3(flctl); 224 ecc_reg[3] = FL4ECCRESULT3(flctl);
188 225
189 for (i = 0; i < 3; i++) { 226 for (i = 0; i < 3; i++) {
227 uint8_t org;
228 int index;
229
190 data = readl(ecc_reg[i]); 230 data = readl(ecc_reg[i]);
191 if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
192 uint8_t org;
193 int index;
194
195 if (flctl->page_size)
196 index = (512 * sector_number) +
197 (data >> 16);
198 else
199 index = data >> 16;
200
201 org = flctl->done_buff[index];
202 flctl->done_buff[index] = org ^ (data & 0xFF);
203 checked[i] = 1;
204 }
205 }
206 231
232 if (flctl->page_size)
233 index = (512 * sector_number) +
234 (data >> 16);
235 else
236 index = data >> 16;
237
238 org = flctl->done_buff[index];
239 flctl->done_buff[index] = org ^ (data & 0xFF);
240 }
241 state = FL_REPAIRABLE;
207 writel(0, FL4ECCCR(flctl)); 242 writel(0, FL4ECCCR(flctl));
208 } 243 }
209 244
210 timeout_error(flctl, __func__); 245 timeout_error(flctl, __func__);
211 return 1; /* timeout */ 246 return FL_TIMEOUT; /* timeout */
212} 247}
213 248
214static void wait_wecfifo_ready(struct sh_flctl *flctl) 249static void wait_wecfifo_ready(struct sh_flctl *flctl)
@@ -241,31 +276,33 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
241{ 276{
242 int i, len_4align; 277 int i, len_4align;
243 unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; 278 unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
244 void *fifo_addr = (void *)FLDTFIFO(flctl);
245 279
246 len_4align = (rlen + 3) / 4; 280 len_4align = (rlen + 3) / 4;
247 281
248 for (i = 0; i < len_4align; i++) { 282 for (i = 0; i < len_4align; i++) {
249 wait_rfifo_ready(flctl); 283 wait_rfifo_ready(flctl);
250 buf[i] = readl(fifo_addr); 284 buf[i] = readl(FLDTFIFO(flctl));
251 buf[i] = be32_to_cpu(buf[i]); 285 buf[i] = be32_to_cpu(buf[i]);
252 } 286 }
253} 287}
254 288
255static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector) 289static enum flctl_ecc_res_t read_ecfiforeg
290 (struct sh_flctl *flctl, uint8_t *buff, int sector)
256{ 291{
257 int i; 292 int i;
293 enum flctl_ecc_res_t res;
258 unsigned long *ecc_buf = (unsigned long *)buff; 294 unsigned long *ecc_buf = (unsigned long *)buff;
259 void *fifo_addr = (void *)FLECFIFO(flctl);
260 295
261 for (i = 0; i < 4; i++) { 296 res = wait_recfifo_ready(flctl , sector);
262 if (wait_recfifo_ready(flctl , sector)) 297
263 return 1; 298 if (res != FL_ERROR) {
264 ecc_buf[i] = readl(fifo_addr); 299 for (i = 0; i < 4; i++) {
265 ecc_buf[i] = be32_to_cpu(ecc_buf[i]); 300 ecc_buf[i] = readl(FLECFIFO(flctl));
301 ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
302 }
266 } 303 }
267 304
268 return 0; 305 return res;
269} 306}
270 307
271static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) 308static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
@@ -281,6 +318,18 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
281 } 318 }
282} 319}
283 320
321static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
322{
323 int i, len_4align;
324 unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
325
326 len_4align = (rlen + 3) / 4;
327 for (i = 0; i < len_4align; i++) {
328 wait_wecfifo_ready(flctl);
329 writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
330 }
331}
332
284static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) 333static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
285{ 334{
286 struct sh_flctl *flctl = mtd_to_flctl(mtd); 335 struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -346,73 +395,65 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
346static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, 395static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
347 uint8_t *buf, int oob_required, int page) 396 uint8_t *buf, int oob_required, int page)
348{ 397{
349 int i, eccsize = chip->ecc.size; 398 chip->read_buf(mtd, buf, mtd->writesize);
350 int eccbytes = chip->ecc.bytes; 399 if (oob_required)
351 int eccsteps = chip->ecc.steps; 400 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
352 uint8_t *p = buf;
353 struct sh_flctl *flctl = mtd_to_flctl(mtd);
354
355 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
356 chip->read_buf(mtd, p, eccsize);
357
358 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
359 if (flctl->hwecc_cant_correct[i])
360 mtd->ecc_stats.failed++;
361 else
362 mtd->ecc_stats.corrected += 0; /* FIXME */
363 }
364
365 return 0; 401 return 0;
366} 402}
367 403
368static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, 404static int flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
369 const uint8_t *buf, int oob_required) 405 const uint8_t *buf, int oob_required)
370{ 406{
371 int i, eccsize = chip->ecc.size; 407 chip->write_buf(mtd, buf, mtd->writesize);
372 int eccbytes = chip->ecc.bytes; 408 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
373 int eccsteps = chip->ecc.steps; 409 return 0;
374 const uint8_t *p = buf;
375
376 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
377 chip->write_buf(mtd, p, eccsize);
378} 410}
379 411
380static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) 412static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
381{ 413{
382 struct sh_flctl *flctl = mtd_to_flctl(mtd); 414 struct sh_flctl *flctl = mtd_to_flctl(mtd);
383 int sector, page_sectors; 415 int sector, page_sectors;
416 enum flctl_ecc_res_t ecc_result;
384 417
385 if (flctl->page_size) 418 page_sectors = flctl->page_size ? 4 : 1;
386 page_sectors = 4;
387 else
388 page_sectors = 1;
389
390 writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
391 FLCMNCR(flctl));
392 419
393 set_cmd_regs(mtd, NAND_CMD_READ0, 420 set_cmd_regs(mtd, NAND_CMD_READ0,
394 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); 421 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
395 422
396 for (sector = 0; sector < page_sectors; sector++) { 423 writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
397 int ret; 424 FLCMNCR(flctl));
425 writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
426 writel(page_addr << 2, FLADR(flctl));
398 427
399 empty_fifo(flctl); 428 empty_fifo(flctl);
400 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl)); 429 start_translation(flctl);
401 writel(page_addr << 2 | sector, FLADR(flctl));
402 430
403 start_translation(flctl); 431 for (sector = 0; sector < page_sectors; sector++) {
404 read_fiforeg(flctl, 512, 512 * sector); 432 read_fiforeg(flctl, 512, 512 * sector);
405 433
406 ret = read_ecfiforeg(flctl, 434 ecc_result = read_ecfiforeg(flctl,
407 &flctl->done_buff[mtd->writesize + 16 * sector], 435 &flctl->done_buff[mtd->writesize + 16 * sector],
408 sector); 436 sector);
409 437
410 if (ret) 438 switch (ecc_result) {
411 flctl->hwecc_cant_correct[sector] = 1; 439 case FL_REPAIRABLE:
412 440 dev_info(&flctl->pdev->dev,
413 writel(0x0, FL4ECCCR(flctl)); 441 "applied ecc on page 0x%x", page_addr);
414 wait_completion(flctl); 442 flctl->mtd.ecc_stats.corrected++;
443 break;
444 case FL_ERROR:
445 dev_warn(&flctl->pdev->dev,
446 "page 0x%x contains corrupted data\n",
447 page_addr);
448 flctl->mtd.ecc_stats.failed++;
449 break;
450 default:
451 ;
452 }
415 } 453 }
454
455 wait_completion(flctl);
456
416 writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT), 457 writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
417 FLCMNCR(flctl)); 458 FLCMNCR(flctl));
418} 459}
@@ -420,30 +461,20 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
420static void execmd_read_oob(struct mtd_info *mtd, int page_addr) 461static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
421{ 462{
422 struct sh_flctl *flctl = mtd_to_flctl(mtd); 463 struct sh_flctl *flctl = mtd_to_flctl(mtd);
464 int page_sectors = flctl->page_size ? 4 : 1;
465 int i;
423 466
424 set_cmd_regs(mtd, NAND_CMD_READ0, 467 set_cmd_regs(mtd, NAND_CMD_READ0,
425 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); 468 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
426 469
427 empty_fifo(flctl); 470 empty_fifo(flctl);
428 if (flctl->page_size) {
429 int i;
430 /* In case that the page size is 2k */
431 for (i = 0; i < 16 * 3; i++)
432 flctl->done_buff[i] = 0xFF;
433
434 set_addr(mtd, 3 * 528 + 512, page_addr);
435 writel(16, FLDTCNTR(flctl));
436 471
437 start_translation(flctl); 472 for (i = 0; i < page_sectors; i++) {
438 read_fiforeg(flctl, 16, 16 * 3); 473 set_addr(mtd, (512 + 16) * i + 512 , page_addr);
439 wait_completion(flctl);
440 } else {
441 /* In case that the page size is 512b */
442 set_addr(mtd, 512, page_addr);
443 writel(16, FLDTCNTR(flctl)); 474 writel(16, FLDTCNTR(flctl));
444 475
445 start_translation(flctl); 476 start_translation(flctl);
446 read_fiforeg(flctl, 16, 0); 477 read_fiforeg(flctl, 16, 16 * i);
447 wait_completion(flctl); 478 wait_completion(flctl);
448 } 479 }
449} 480}
@@ -451,34 +482,26 @@ static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
451static void execmd_write_page_sector(struct mtd_info *mtd) 482static void execmd_write_page_sector(struct mtd_info *mtd)
452{ 483{
453 struct sh_flctl *flctl = mtd_to_flctl(mtd); 484 struct sh_flctl *flctl = mtd_to_flctl(mtd);
454 int i, page_addr = flctl->seqin_page_addr; 485 int page_addr = flctl->seqin_page_addr;
455 int sector, page_sectors; 486 int sector, page_sectors;
456 487
457 if (flctl->page_size) 488 page_sectors = flctl->page_size ? 4 : 1;
458 page_sectors = 4;
459 else
460 page_sectors = 1;
461
462 writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
463 489
464 set_cmd_regs(mtd, NAND_CMD_PAGEPROG, 490 set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
465 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); 491 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
466 492
467 for (sector = 0; sector < page_sectors; sector++) { 493 empty_fifo(flctl);
468 empty_fifo(flctl); 494 writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
469 writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl)); 495 writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
470 writel(page_addr << 2 | sector, FLADR(flctl)); 496 writel(page_addr << 2, FLADR(flctl));
497 start_translation(flctl);
471 498
472 start_translation(flctl); 499 for (sector = 0; sector < page_sectors; sector++) {
473 write_fiforeg(flctl, 512, 512 * sector); 500 write_fiforeg(flctl, 512, 512 * sector);
474 501 write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector);
475 for (i = 0; i < 4; i++) {
476 wait_wecfifo_ready(flctl); /* wait for write ready */
477 writel(0xFFFFFFFF, FLECFIFO(flctl));
478 }
479 wait_completion(flctl);
480 } 502 }
481 503
504 wait_completion(flctl);
482 writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl)); 505 writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
483} 506}
484 507
@@ -488,18 +511,12 @@ static void execmd_write_oob(struct mtd_info *mtd)
488 int page_addr = flctl->seqin_page_addr; 511 int page_addr = flctl->seqin_page_addr;
489 int sector, page_sectors; 512 int sector, page_sectors;
490 513
491 if (flctl->page_size) { 514 page_sectors = flctl->page_size ? 4 : 1;
492 sector = 3;
493 page_sectors = 4;
494 } else {
495 sector = 0;
496 page_sectors = 1;
497 }
498 515
499 set_cmd_regs(mtd, NAND_CMD_PAGEPROG, 516 set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
500 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); 517 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
501 518
502 for (; sector < page_sectors; sector++) { 519 for (sector = 0; sector < page_sectors; sector++) {
503 empty_fifo(flctl); 520 empty_fifo(flctl);
504 set_addr(mtd, sector * 528 + 512, page_addr); 521 set_addr(mtd, sector * 528 + 512, page_addr);
505 writel(16, FLDTCNTR(flctl)); /* set read size */ 522 writel(16, FLDTCNTR(flctl)); /* set read size */
@@ -731,10 +748,9 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
731static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 748static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
732{ 749{
733 struct sh_flctl *flctl = mtd_to_flctl(mtd); 750 struct sh_flctl *flctl = mtd_to_flctl(mtd);
734 int i, index = flctl->index; 751 int index = flctl->index;
735 752
736 for (i = 0; i < len; i++) 753 memcpy(&flctl->done_buff[index], buf, len);
737 flctl->done_buff[index + i] = buf[i];
738 flctl->index += len; 754 flctl->index += len;
739} 755}
740 756
@@ -763,20 +779,11 @@ static uint16_t flctl_read_word(struct mtd_info *mtd)
763 779
764static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 780static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
765{ 781{
766 int i; 782 struct sh_flctl *flctl = mtd_to_flctl(mtd);
767 783 int index = flctl->index;
768 for (i = 0; i < len; i++)
769 buf[i] = flctl_read_byte(mtd);
770}
771
772static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
773{
774 int i;
775 784
776 for (i = 0; i < len; i++) 785 memcpy(buf, &flctl->done_buff[index], len);
777 if (buf[i] != flctl_read_byte(mtd)) 786 flctl->index += len;
778 return -EFAULT;
779 return 0;
780} 787}
781 788
782static int flctl_chip_init_tail(struct mtd_info *mtd) 789static int flctl_chip_init_tail(struct mtd_info *mtd)
@@ -831,7 +838,7 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
831 chip->ecc.mode = NAND_ECC_HW; 838 chip->ecc.mode = NAND_ECC_HW;
832 839
833 /* 4 symbols ECC enabled */ 840 /* 4 symbols ECC enabled */
834 flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02; 841 flctl->flcmncr_base |= _4ECCEN;
835 } else { 842 } else {
836 chip->ecc.mode = NAND_ECC_SOFT; 843 chip->ecc.mode = NAND_ECC_SOFT;
837 } 844 }
@@ -839,6 +846,16 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
839 return 0; 846 return 0;
840} 847}
841 848
849static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
850{
851 struct sh_flctl *flctl = dev_id;
852
853 dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl)));
854 writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
855
856 return IRQ_HANDLED;
857}
858
842static int __devinit flctl_probe(struct platform_device *pdev) 859static int __devinit flctl_probe(struct platform_device *pdev)
843{ 860{
844 struct resource *res; 861 struct resource *res;
@@ -847,6 +864,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
847 struct nand_chip *nand; 864 struct nand_chip *nand;
848 struct sh_flctl_platform_data *pdata; 865 struct sh_flctl_platform_data *pdata;
849 int ret = -ENXIO; 866 int ret = -ENXIO;
867 int irq;
850 868
851 pdata = pdev->dev.platform_data; 869 pdata = pdev->dev.platform_data;
852 if (pdata == NULL) { 870 if (pdata == NULL) {
@@ -872,14 +890,27 @@ static int __devinit flctl_probe(struct platform_device *pdev)
872 goto err_iomap; 890 goto err_iomap;
873 } 891 }
874 892
893 irq = platform_get_irq(pdev, 0);
894 if (irq < 0) {
895 dev_err(&pdev->dev, "failed to get flste irq data\n");
896 goto err_flste;
897 }
898
899 ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
900 if (ret) {
901 dev_err(&pdev->dev, "request interrupt failed.\n");
902 goto err_flste;
903 }
904
875 platform_set_drvdata(pdev, flctl); 905 platform_set_drvdata(pdev, flctl);
876 flctl_mtd = &flctl->mtd; 906 flctl_mtd = &flctl->mtd;
877 nand = &flctl->chip; 907 nand = &flctl->chip;
878 flctl_mtd->priv = nand; 908 flctl_mtd->priv = nand;
879 flctl->pdev = pdev; 909 flctl->pdev = pdev;
880 flctl->flcmncr_base = pdata->flcmncr_val;
881 flctl->hwecc = pdata->has_hwecc; 910 flctl->hwecc = pdata->has_hwecc;
882 flctl->holden = pdata->use_holden; 911 flctl->holden = pdata->use_holden;
912 flctl->flcmncr_base = pdata->flcmncr_val;
913 flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE;
883 914
884 /* Set address of hardware control function */ 915 /* Set address of hardware control function */
885 /* 20 us command delay time */ 916 /* 20 us command delay time */
@@ -888,7 +919,6 @@ static int __devinit flctl_probe(struct platform_device *pdev)
888 nand->read_byte = flctl_read_byte; 919 nand->read_byte = flctl_read_byte;
889 nand->write_buf = flctl_write_buf; 920 nand->write_buf = flctl_write_buf;
890 nand->read_buf = flctl_read_buf; 921 nand->read_buf = flctl_read_buf;
891 nand->verify_buf = flctl_verify_buf;
892 nand->select_chip = flctl_select_chip; 922 nand->select_chip = flctl_select_chip;
893 nand->cmdfunc = flctl_cmdfunc; 923 nand->cmdfunc = flctl_cmdfunc;
894 924
@@ -918,6 +948,9 @@ static int __devinit flctl_probe(struct platform_device *pdev)
918 948
919err_chip: 949err_chip:
920 pm_runtime_disable(&pdev->dev); 950 pm_runtime_disable(&pdev->dev);
951 free_irq(irq, flctl);
952err_flste:
953 iounmap(flctl->reg);
921err_iomap: 954err_iomap:
922 kfree(flctl); 955 kfree(flctl);
923 return ret; 956 return ret;
@@ -929,6 +962,8 @@ static int __devexit flctl_remove(struct platform_device *pdev)
929 962
930 nand_release(&flctl->mtd); 963 nand_release(&flctl->mtd);
931 pm_runtime_disable(&pdev->dev); 964 pm_runtime_disable(&pdev->dev);
965 free_irq(platform_get_irq(pdev, 0), flctl);
966 iounmap(flctl->reg);
932 kfree(flctl); 967 kfree(flctl);
933 968
934 return 0; 969 return 0;