aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/rtc_from4.c48
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 */
92static void __iomem *rtc_from4_fio_base = P2SEGADDR(RTC_FROM4_FIO_BASE); 92static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
93 93
94const static struct mtd_partition partition_info[] = { 94const 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 */
303static 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