diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 02305a2adca7..a4d8d2e62e9e 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Derived from drivers/mtd/nand/spia.c | 6 | * Derived from drivers/mtd/nand/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: rtc_from4.c,v 1.7 2004/11/04 12:53:10 gleixner Exp $ | 9 | * $Id: rtc_from4.c,v 1.8 2005/01/17 19:44:36 dmarlin Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -89,7 +89,7 @@ static struct mtd_info *rtc_from4_mtd = NULL; | |||
89 | /* | 89 | /* |
90 | * Module stuff | 90 | * Module stuff |
91 | */ | 91 | */ |
92 | static void __iomem *rtc_from4_fio_base = P2SEGADDR(RTC_FROM4_FIO_BASE); | 92 | static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); |
93 | 93 | ||
94 | const static struct mtd_partition partition_info[] = { | 94 | const static struct mtd_partition partition_info[] = { |
95 | { | 95 | { |
@@ -286,6 +286,40 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd) | |||
286 | 286 | ||
287 | } | 287 | } |
288 | 288 | ||
289 | |||
290 | /* | ||
291 | * deplete - code to perform device recovery in case there was a power loss | ||
292 | * @mtd: MTD device structure | ||
293 | * @chip: Chip to select (0 == slot 3, 1 == slot 4) | ||
294 | * | ||
295 | * If there was a sudden loss of power during an erase operation, a | ||
296 | * "device recovery" operation must be performed when power is restored | ||
297 | * to ensure correct operation. This routine performs the required steps | ||
298 | * for the requested chip. | ||
299 | * | ||
300 | * See page 86 of the data sheet for details. | ||
301 | * | ||
302 | */ | ||
303 | static void deplete(struct mtd_info *mtd, int chip) | ||
304 | { | ||
305 | struct nand_chip *this = mtd->priv; | ||
306 | |||
307 | /* wait until device is ready */ | ||
308 | while (!this->dev_ready(mtd)); | ||
309 | |||
310 | this->select_chip(mtd, chip); | ||
311 | |||
312 | /* Send the commands for device recovery, phase 1 */ | ||
313 | this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); | ||
314 | this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); | ||
315 | |||
316 | /* Send the commands for device recovery, phase 2 */ | ||
317 | this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004); | ||
318 | this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); | ||
319 | |||
320 | } | ||
321 | |||
322 | |||
289 | #ifdef RTC_FROM4_HWECC | 323 | #ifdef RTC_FROM4_HWECC |
290 | /* | 324 | /* |
291 | * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function | 325 | * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function |
@@ -374,7 +408,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha | |||
374 | { | 408 | { |
375 | int i, j, res; | 409 | int i, j, res; |
376 | unsigned short status; | 410 | unsigned short status; |
377 | uint16_t par[6], syn[6], tmp; | 411 | uint16_t par[6], syn[6]; |
378 | uint8_t ecc[8]; | 412 | uint8_t ecc[8]; |
379 | volatile unsigned short *rs_ecc; | 413 | volatile unsigned short *rs_ecc; |
380 | 414 | ||
@@ -416,7 +450,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha | |||
416 | } | 450 | } |
417 | 451 | ||
418 | /* Let the library code do its magic.*/ | 452 | /* Let the library code do its magic.*/ |
419 | res = decode_rs8(rs_decoder, buf, par, 512, syn, 0, NULL, 0xff, NULL); | 453 | res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); |
420 | if (res > 0) { | 454 | if (res > 0) { |
421 | DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " | 455 | DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " |
422 | "ECC corrected %d errors on read\n", res); | 456 | "ECC corrected %d errors on read\n", res); |
@@ -432,6 +466,7 @@ int __init rtc_from4_init (void) | |||
432 | { | 466 | { |
433 | struct nand_chip *this; | 467 | struct nand_chip *this; |
434 | unsigned short bcr1, bcr2, wcr2; | 468 | unsigned short bcr1, bcr2, wcr2; |
469 | int i; | ||
435 | 470 | ||
436 | /* Allocate memory for MTD device structure and private data */ | 471 | /* Allocate memory for MTD device structure and private data */ |
437 | rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), | 472 | rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), |
@@ -504,6 +539,11 @@ int __init rtc_from4_init (void) | |||
504 | return -ENXIO; | 539 | return -ENXIO; |
505 | } | 540 | } |
506 | 541 | ||
542 | /* Perform 'device recovery' for each chip in case there was a power loss. */ | ||
543 | for (i=0; i < this->numchips; i++) { | ||
544 | deplete(rtc_from4_mtd, i); | ||
545 | } | ||
546 | |||
507 | /* Register the partitions */ | 547 | /* Register the partitions */ |
508 | add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); | 548 | add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); |
509 | 549 | ||