diff options
author | Kevin Hao <haokexin@gmail.com> | 2007-10-02 16:56:04 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 09:36:18 -0400 |
commit | c4a9f88daf6c382fedde4cdddef0b30f1d0a20db (patch) | |
tree | d2a3b5a336d55ce7c584eff43429662fb2c4c25d /drivers/mtd/chips | |
parent | f96880d1e859e3937eb691da8293700b8eec17b3 (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>
Diffstat (limited to 'drivers/mtd/chips')
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 9 |
1 files changed, 6 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 | } |