diff options
author | Vitaly Wool <vwool@ru.mvista.com> | 2005-09-15 09:58:53 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 15:43:45 -0500 |
commit | 962034f43937d02a1c18e802a6641aed0a266ac5 (patch) | |
tree | d1e1f2fe4f45614f7714bc117fc55c4d5d9ee982 | |
parent | 9c517e6c801aab0f8de8f9c67bfc16ea13d72971 (diff) |
[MTD] NAND: Add suspend/resume functionality
The changes introduced allow to suspend/resume NAND flash.
A new state (FL_PM_SUSPENDED) is introduced, as well as
routines for mtd->suspend and mtd->resume to put the flash in
suspended state from software pov.
Signed-off-by: Vitaly Wool <vwool@ru.mvista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 46 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 3 |
2 files changed, 42 insertions, 7 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index cdf108619344..4e22317397e8 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -46,6 +46,8 @@ | |||
46 | * perform extra error status checks on erase and write failures. This required | 46 | * perform extra error status checks on erase and write failures. This required |
47 | * adding a wrapper function for nand_read_ecc. | 47 | * adding a wrapper function for nand_read_ecc. |
48 | * | 48 | * |
49 | * 08-20-2005 vwool: suspend/resume added | ||
50 | * | ||
49 | * Credits: | 51 | * Credits: |
50 | * David Woodhouse for adding multichip support | 52 | * David Woodhouse for adding multichip support |
51 | * | 53 | * |
@@ -59,7 +61,7 @@ | |||
59 | * The AG-AND chips have nice features for speed improvement, | 61 | * The AG-AND chips have nice features for speed improvement, |
60 | * which are not supported yet. Read / program 4 pages in one go. | 62 | * which are not supported yet. Read / program 4 pages in one go. |
61 | * | 63 | * |
62 | * $Id: nand_base.c,v 1.148 2005/08/04 17:14:48 gleixner Exp $ | 64 | * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $ |
63 | * | 65 | * |
64 | * This program is free software; you can redistribute it and/or modify | 66 | * This program is free software; you can redistribute it and/or modify |
65 | * it under the terms of the GNU General Public License version 2 as | 67 | * it under the terms of the GNU General Public License version 2 as |
@@ -153,7 +155,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int | |||
153 | #define nand_verify_pages(...) (0) | 155 | #define nand_verify_pages(...) (0) |
154 | #endif | 156 | #endif |
155 | 157 | ||
156 | static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); | 158 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); |
157 | 159 | ||
158 | /** | 160 | /** |
159 | * nand_release_device - [GENERIC] release chip | 161 | * nand_release_device - [GENERIC] release chip |
@@ -756,7 +758,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
756 | * | 758 | * |
757 | * Get the device and lock it for exclusive access | 759 | * Get the device and lock it for exclusive access |
758 | */ | 760 | */ |
759 | static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) | 761 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) |
760 | { | 762 | { |
761 | struct nand_chip *active; | 763 | struct nand_chip *active; |
762 | spinlock_t *lock; | 764 | spinlock_t *lock; |
@@ -779,7 +781,11 @@ retry: | |||
779 | if (active == this && this->state == FL_READY) { | 781 | if (active == this && this->state == FL_READY) { |
780 | this->state = new_state; | 782 | this->state = new_state; |
781 | spin_unlock(lock); | 783 | spin_unlock(lock); |
782 | return; | 784 | return 0; |
785 | } | ||
786 | if (new_state == FL_PM_SUSPENDED) { | ||
787 | spin_unlock(lock); | ||
788 | return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; | ||
783 | } | 789 | } |
784 | set_current_state(TASK_UNINTERRUPTIBLE); | 790 | set_current_state(TASK_UNINTERRUPTIBLE); |
785 | add_wait_queue(wq, &wait); | 791 | add_wait_queue(wq, &wait); |
@@ -2285,6 +2291,34 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) | |||
2285 | } | 2291 | } |
2286 | 2292 | ||
2287 | /** | 2293 | /** |
2294 | * nand_suspend - [MTD Interface] Suspend the NAND flash | ||
2295 | * @mtd: MTD device structure | ||
2296 | */ | ||
2297 | static int nand_suspend(struct mtd_info *mtd) | ||
2298 | { | ||
2299 | struct nand_chip *this = mtd->priv; | ||
2300 | |||
2301 | return nand_get_device (this, mtd, FL_PM_SUSPENDED); | ||
2302 | } | ||
2303 | |||
2304 | /** | ||
2305 | * nand_resume - [MTD Interface] Resume the NAND flash | ||
2306 | * @mtd: MTD device structure | ||
2307 | */ | ||
2308 | static void nand_resume(struct mtd_info *mtd) | ||
2309 | { | ||
2310 | struct nand_chip *this = mtd->priv; | ||
2311 | |||
2312 | if (this->state == FL_PM_SUSPENDED) | ||
2313 | nand_release_device(mtd); | ||
2314 | else | ||
2315 | printk(KERN_ERR "resume() called for the chip which is not " | ||
2316 | "in suspended state\n"); | ||
2317 | |||
2318 | } | ||
2319 | |||
2320 | |||
2321 | /** | ||
2288 | * nand_scan - [NAND Interface] Scan for the NAND device | 2322 | * nand_scan - [NAND Interface] Scan for the NAND device |
2289 | * @mtd: MTD device structure | 2323 | * @mtd: MTD device structure |
2290 | * @maxchips: Number of chips to scan for | 2324 | * @maxchips: Number of chips to scan for |
@@ -2643,8 +2677,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2643 | mtd->sync = nand_sync; | 2677 | mtd->sync = nand_sync; |
2644 | mtd->lock = NULL; | 2678 | mtd->lock = NULL; |
2645 | mtd->unlock = NULL; | 2679 | mtd->unlock = NULL; |
2646 | mtd->suspend = NULL; | 2680 | mtd->suspend = nand_suspend; |
2647 | mtd->resume = NULL; | 2681 | mtd->resume = nand_resume; |
2648 | mtd->block_isbad = nand_block_isbad; | 2682 | mtd->block_isbad = nand_block_isbad; |
2649 | mtd->block_markbad = nand_block_markbad; | 2683 | mtd->block_markbad = nand_block_markbad; |
2650 | 2684 | ||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9b5b76217584..2d36413b2f94 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * Steven J. Hill <sjhill@realitydiluted.com> | 5 | * Steven J. Hill <sjhill@realitydiluted.com> |
6 | * Thomas Gleixner <tglx@linutronix.de> | 6 | * Thomas Gleixner <tglx@linutronix.de> |
7 | * | 7 | * |
8 | * $Id: nand.h,v 1.73 2005/05/31 19:39:17 gleixner Exp $ | 8 | * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool Exp $ |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -244,6 +244,7 @@ typedef enum { | |||
244 | FL_ERASING, | 244 | FL_ERASING, |
245 | FL_SYNCING, | 245 | FL_SYNCING, |
246 | FL_CACHEDPRG, | 246 | FL_CACHEDPRG, |
247 | FL_PM_SUSPENDED, | ||
247 | } nand_state_t; | 248 | } nand_state_t; |
248 | 249 | ||
249 | /* Keep gcc happy */ | 250 | /* Keep gcc happy */ |