aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2007-10-02 16:56:04 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-10-13 09:36:18 -0400
commitc4a9f88daf6c382fedde4cdddef0b30f1d0a20db (patch)
treed2a3b5a336d55ce7c584eff43429662fb2c4c25d
parentf96880d1e859e3937eb691da8293700b8eec17b3 (diff)
[MTD] [NOR] fix ctrl-alt-del can't reboot for intel flash bug
When we press ctrl-alt-del,kernel_restart_prepare will invoke cfi_intelext_reboot which will set flash to read array mode, but later when device_shutdown is invoked which may put current work queue to sleep and other process may be scheduled to running and programming flash in not FL_READY mode again. So we can't boot up if this flash is used for bootloader. Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c9
-rw-r--r--include/linux/mtd/flashchip.h1
2 files changed, 7 insertions, 3 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index c655e971c158..3aa3dca56ae6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -653,7 +653,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
653 resettime: 653 resettime:
654 timeo = jiffies + HZ; 654 timeo = jiffies + HZ;
655 retry: 655 retry:
656 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) { 656 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
657 /* 657 /*
658 * OK. We have possibility for contension on the write/erase 658 * OK. We have possibility for contension on the write/erase
659 * operations which are global to the real chip and not per 659 * operations which are global to the real chip and not per
@@ -798,6 +798,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
798 if (mode == FL_READY && chip->oldstate == FL_READY) 798 if (mode == FL_READY && chip->oldstate == FL_READY)
799 return 0; 799 return 0;
800 800
801 case FL_SHUTDOWN:
802 /* The machine is rebooting now,so no one can get chip anymore */
803 return -EIO;
801 default: 804 default:
802 sleep: 805 sleep:
803 set_current_state(TASK_UNINTERRUPTIBLE); 806 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -2409,10 +2412,10 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
2409 and switch to array mode so any bootloader in 2412 and switch to array mode so any bootloader in
2410 flash is accessible for soft reboot. */ 2413 flash is accessible for soft reboot. */
2411 spin_lock(chip->mutex); 2414 spin_lock(chip->mutex);
2412 ret = get_chip(map, chip, chip->start, FL_SYNCING); 2415 ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
2413 if (!ret) { 2416 if (!ret) {
2414 map_write(map, CMD(0xff), chip->start); 2417 map_write(map, CMD(0xff), chip->start);
2415 chip->state = FL_READY; 2418 chip->state = FL_SHUTDOWN;
2416 } 2419 }
2417 spin_unlock(chip->mutex); 2420 spin_unlock(chip->mutex);
2418 } 2421 }
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index a293a3b78e05..39e7d2a1be9a 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -40,6 +40,7 @@ typedef enum {
40 FL_POINT, 40 FL_POINT,
41 FL_XIP_WHILE_ERASING, 41 FL_XIP_WHILE_ERASING,
42 FL_XIP_WHILE_WRITING, 42 FL_XIP_WHILE_WRITING,
43 FL_SHUTDOWN,
43 FL_UNKNOWN 44 FL_UNKNOWN
44} flstate_t; 45} flstate_t;
45 46