diff -urN linux-2.6.16-panel-0.9.4/drivers/char/panel.c linux-2.6.16-panel-0.9.5/drivers/char/panel.c --- linux-2.6.16-panel-0.9.4/drivers/char/panel.c 2006-12-18 19:14:41 +0100 +++ linux-2.6.16-panel-0.9.5/drivers/char/panel.c 2006-12-18 19:30:57 +0100 @@ -67,6 +67,10 @@ * 2005/05/20 : 0.9.4 * - first working port on kernel 2.6 * + * 2006/12/18 : 0.9.5 + * - fixed a long standing bug in 2.6 causing panics during reboot/kexec + * if the LCD was enabled but not initialized due to lack of parport. + * * FIXME: * - the initialization/deinitialization process is very dirty and should * be rewritten. It may even be buggy. @@ -113,7 +117,7 @@ #define KEYPAD_MINOR 185 #define SMARTCARD_MINOR 186 -#define PANEL_VERSION "0.9.3" +#define PANEL_VERSION "0.9.5" #define LCD_MAXBYTES 256 /* max burst write */ @@ -489,6 +493,8 @@ static int keypad_type = -1; static int smartcard_enabled = -1; +static int lcd_initialized, keypad_initialized, smartcard_initialized; + static int light_tempo = 0; static char lcd_must_clear = 0; @@ -1265,7 +1271,7 @@ /* public function usable from the kernel for any purpose */ void panel_lcd_print(char *s) { - if (lcd_enabled) + if (lcd_enabled && lcd_initialized) lcd_write(NULL, s, strlen(s), NULL); } @@ -1384,6 +1390,11 @@ pin_to_bits(lcd_cl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_CL], lcd_bits[LCD_PORT_C][LCD_BIT_CL]); pin_to_bits(lcd_da_pin, lcd_bits[LCD_PORT_D][LCD_BIT_DA], lcd_bits[LCD_PORT_C][LCD_BIT_DA]); + /* before this line, we must NOT send anything to the display. + * Since lcd_init_display() needs to write data, we have to + * enable mark the LCD initialized just before. + */ + lcd_initialized = 1; lcd_init_display(); /* display a short message */ @@ -1685,24 +1696,30 @@ } static void panel_scan_timer(void) { - if (spin_trylock(&pprt_lock)) { - phys_scan_contacts(); - spin_unlock(&pprt_lock); /* no need for the parport anymore */ - } + if ((keypad_enabled && keypad_initialized) + || (smartcard_enabled && smartcard_enabled)) { - if (!inputs_stable || phys_curr != phys_prev) { - panel_process_inputs(); - } + if (spin_trylock(&pprt_lock)) { + phys_scan_contacts(); + spin_unlock(&pprt_lock); /* no need for the parport anymore */ + } - if (keypressed) { - if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) - lcd_backlight(1); - light_tempo = FLASH_LIGHT_TEMPO; + if (!inputs_stable || phys_curr != phys_prev) { + panel_process_inputs(); + } } - else if (light_tempo > 0) { - light_tempo--; - if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) - lcd_backlight(0); + + if (lcd_enabled && lcd_initialized) { + if (keypressed) { + if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) + lcd_backlight(1); + light_tempo = FLASH_LIGHT_TEMPO; + } + else if (light_tempo > 0) { + light_tempo--; + if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) + lcd_backlight(0); + } } mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME); @@ -1946,6 +1963,7 @@ } init_scan_timer(); + keypad_initialized = 1; } @@ -1954,6 +1972,7 @@ panel_bind_callback(SMARTCARD_LOGICAL_DETECTOR, &smartcard_insert, 0, &smartcard_remove, 0); init_scan_timer(); + smartcard_enabled = 1; } @@ -2066,7 +2085,7 @@ #endif /* !MODULE */ static int panel_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (lcd_enabled) { + if (lcd_enabled && lcd_initialized) { switch(code) { case SYS_DOWN: panel_lcd_print("\x0cReloading\nSystem...\x1b[Lc\x1b[Lb\x1b[L+"); @@ -2147,15 +2166,15 @@ return; } - if (smartcard_enabled) { + if (smartcard_enabled && smartcard_initialized) { misc_deregister( &smartcard_dev ); } - if (keypad_enabled) { + if (keypad_enabled && keypad_initialized) { misc_deregister( &keypad_dev ); } - if (lcd_enabled) { + if (lcd_enabled && lcd_initialized) { misc_deregister( &lcd_dev ); }