diff -urN a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt 2010-05-17 06:17:36.000000000 +0900 +++ b/Documentation/kernel-parameters.txt 2010-05-19 07:22:27.000000000 +0900 @@ -900,9 +900,6 @@ controller i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX controllers - i8042.panicblink= - [HW] Frequency with which keyboard LEDs should blink - when kernel panics (default is 0.5 sec) i8042.reset [HW] Reset the controller during init and cleanup i8042.unlock [HW] Unlock (ignore) the keylock diff -urN a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c --- a/arch/arm/mach-s3c2440/mach-gta02.c 2010-05-17 06:17:36.000000000 +0900 +++ b/arch/arm/mach-s3c2440/mach-gta02.c 2010-05-19 07:22:27.000000000 +0900 @@ -90,24 +90,17 @@ static struct pcf50633 *gta02_pcf; /* - * This gets called every 1ms when we paniced. + * This gets called frequently when we paniced. */ -static long gta02_panic_blink(long count) +static long gta02_panic_blink(int state) { long delay = 0; - static long last_blink; - static char led; + char led; - /* Fast blink: 200ms period. */ - if (count - last_blink < 100) - return 0; - - led ^= 1; + led = (state) ? 1 : 0; gpio_direction_output(GTA02_GPIO_AUX_LED, led); - last_blink = count; - return delay; } @@ -614,7 +607,7 @@ static void __init gta02_machine_init(void) { - /* Set the panic callback to make AUX LED blink at ~5Hz. */ + /* Set the panic callback to turn AUX LED on or off. */ panic_blink = gta02_panic_blink; s3c_pm_init(); diff -urN a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c --- a/drivers/input/serio/i8042.c 2010-05-17 06:17:36.000000000 +0900 +++ b/drivers/input/serio/i8042.c 2010-05-19 07:22:27.000000000 +0900 @@ -61,10 +61,6 @@ module_param_named(noloop, i8042_noloop, bool, 0); MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); -static unsigned int i8042_blink_frequency = 500; -module_param_named(panicblink, i8042_blink_frequency, uint, 0600); -MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); - #ifdef CONFIG_X86 static bool i8042_dritek; module_param_named(dritek, i8042_dritek, bool, 0); @@ -1032,8 +1028,8 @@ /* - * i8042_panic_blink() will flash the keyboard LEDs and is called when - * kernel panics. Flashing LEDs is useful for users running X who may + * i8042_panic_blink() will turn the keyboard LEDs on or off and is called + * when kernel panics. Flashing LEDs is useful for users running X who may * not see the console and will help distingushing panics from "real" * lockups. * @@ -1043,22 +1039,12 @@ #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) -static long i8042_panic_blink(long count) +static long i8042_panic_blink(int state) { long delay = 0; - static long last_blink; - static char led; - - /* - * We expect frequency to be about 1/2s. KDB uses about 1s. - * Make sure they are different. - */ - if (!i8042_blink_frequency) - return 0; - if (count - last_blink < i8042_blink_frequency) - return 0; + char led; - led ^= 0x01 | 0x04; + led = (state) ? 0x01 | 0x04 : 0; while (i8042_read_status() & I8042_STR_IBF) DELAY; dbg("%02x -> i8042 (panic blink)", 0xed); @@ -1071,7 +1057,6 @@ dbg("%02x -> i8042 (panic blink)", led); i8042_write_data(led); DELAY; - last_blink = count; return delay; } diff -urN a/include/linux/kernel.h b/include/linux/kernel.h --- a/include/linux/kernel.h 2010-05-17 06:17:36.000000000 +0900 +++ b/include/linux/kernel.h 2010-05-19 07:22:27.000000000 +0900 @@ -170,7 +170,7 @@ #endif extern struct atomic_notifier_head panic_notifier_list; -extern long (*panic_blink)(long time); +extern long (*panic_blink)(int state); NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; extern void oops_enter(void); diff -urN a/kernel/panic.c b/kernel/panic.c --- a/kernel/panic.c 2010-05-17 06:17:36.000000000 +0900 +++ b/kernel/panic.c 2010-05-19 07:22:27.000000000 +0900 @@ -24,6 +24,9 @@ #include #include +#define PANIC_TIMER_STEP 100 +#define PANIC_BLINK_SPD 18 + int panic_on_oops; static unsigned long tainted_mask; static int pause_on_oops; @@ -36,36 +39,15 @@ EXPORT_SYMBOL(panic_notifier_list); -/* Returns how long it waited in ms */ -long (*panic_blink)(long time); -EXPORT_SYMBOL(panic_blink); - -static void panic_blink_one_second(void) +static long no_blink(int state) { - static long i = 0, end; - - if (panic_blink) { - end = i + MSEC_PER_SEC; - - while (i < end) { - i += panic_blink(i); - mdelay(1); - i++; - } - } else { - /* - * When running under a hypervisor a small mdelay may get - * rounded up to the hypervisor timeslice. For example, with - * a 1ms in 10ms hypervisor timeslice we might inflate a - * mdelay(1) loop by 10x. - * - * If we have nothing to blink, spin on 1 second calls to - * mdelay to avoid this. - */ - mdelay(MSEC_PER_SEC); - } + return 0; } +/* Returns how long it waited in ms */ +long (*panic_blink)(int state); +EXPORT_SYMBOL(panic_blink); + /** * panic - halt the system * @fmt: The text string to print @@ -78,7 +60,8 @@ { static char buf[1024]; va_list args; - long i; + long i, i_next = 0; + int state = 0; /* * It's possible to come here directly from a panic-assertion and @@ -116,6 +99,9 @@ bust_spinlocks(0); + if (!panic_blink) + panic_blink = no_blink; + if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. @@ -123,9 +109,13 @@ */ printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); - for (i = 0; i < panic_timeout; i++) { + for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) { touch_nmi_watchdog(); - panic_blink_one_second(); + if (i >= i_next) { + i += panic_blink(state ^= 1); + i_next = i + 3600 / PANIC_BLINK_SPD; + } + mdelay(PANIC_TIMER_STEP); } /* * This will not be a clean reboot, with everything @@ -151,9 +141,13 @@ } #endif local_irq_enable(); - while (1) { + for (i = 0; ; i += PANIC_TIMER_STEP) { touch_softlockup_watchdog(); - panic_blink_one_second(); + if (i >= i_next) { + i += panic_blink(state ^= 1); + i_next = i + 3600 / PANIC_BLINK_SPD; + } + mdelay(PANIC_TIMER_STEP); } }