[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>
This commit is contained in:
		
					parent
					
						
							
								f96880d1e8
							
						
					
				
			
			
				commit
				
					
						c4a9f88daf
					
				
			
		
					 2 changed files with 7 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ typedef enum {
 | 
			
		|||
	FL_POINT,
 | 
			
		||||
	FL_XIP_WHILE_ERASING,
 | 
			
		||||
	FL_XIP_WHILE_WRITING,
 | 
			
		||||
	FL_SHUTDOWN,
 | 
			
		||||
	FL_UNKNOWN
 | 
			
		||||
} flstate_t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue