Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4a9f88d authored by Kevin Hao's avatar Kevin Hao Committed by David Woodhouse
Browse files

[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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent f96880d1
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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
@@ -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);
@@ -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);
	}
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ typedef enum {
	FL_POINT,
	FL_XIP_WHILE_ERASING,
	FL_XIP_WHILE_WRITING,
	FL_SHUTDOWN,
	FL_UNKNOWN
} flstate_t;