Skip to content

Commit

Permalink
[MTD] [NOR] fix ctrl-alt-del can't reboot for intel flash bug
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kevin Hao authored and David Woodhouse committed Oct 13, 2007
1 parent f96880d commit c4a9f88
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/mtd/chips/cfi_cmdset_0001.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
resettime:
timeo = jiffies + HZ;
retry:
if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) {
if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
/*
* OK. We have possibility for contension on the write/erase
* operations which are global to the real chip and not per
Expand Down Expand Up @@ -798,6 +798,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
if (mode == FL_READY && chip->oldstate == FL_READY)
return 0;

case FL_SHUTDOWN:
/* The machine is rebooting now,so no one can get chip anymore */
return -EIO;
default:
sleep:
set_current_state(TASK_UNINTERRUPTIBLE);
Expand Down Expand Up @@ -2409,10 +2412,10 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
and switch to array mode so any bootloader in
flash is accessible for soft reboot. */
spin_lock(chip->mutex);
ret = get_chip(map, chip, chip->start, FL_SYNCING);
ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
if (!ret) {
map_write(map, CMD(0xff), chip->start);
chip->state = FL_READY;
chip->state = FL_SHUTDOWN;
}
spin_unlock(chip->mutex);
}
Expand Down
1 change: 1 addition & 0 deletions include/linux/mtd/flashchip.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef enum {
FL_POINT,
FL_XIP_WHILE_ERASING,
FL_XIP_WHILE_WRITING,
FL_SHUTDOWN,
FL_UNKNOWN
} flstate_t;

Expand Down

0 comments on commit c4a9f88

Please sign in to comment.