diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 17 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 25 | ||||
-rw-r--r-- | include/linux/kernel.h | 2 | ||||
-rw-r--r-- | kernel/panic.c | 58 |
5 files changed, 37 insertions, 68 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index d529b1363e95..873b68090098 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -915,9 +915,6 @@ and is between 256 and 4096 characters. It is defined in the file | |||
915 | controller | 915 | controller |
916 | i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX | 916 | i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX |
917 | controllers | 917 | controllers |
918 | i8042.panicblink= | ||
919 | [HW] Frequency with which keyboard LEDs should blink | ||
920 | when kernel panics (default is 0.5 sec) | ||
921 | i8042.reset [HW] Reset the controller during init and cleanup | 918 | i8042.reset [HW] Reset the controller during init and cleanup |
922 | i8042.unlock [HW] Unlock (ignore) the keylock | 919 | i8042.unlock [HW] Unlock (ignore) the keylock |
923 | 920 | ||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 9e39faa283b9..deaabe86741d 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c | |||
@@ -90,24 +90,17 @@ | |||
90 | static struct pcf50633 *gta02_pcf; | 90 | static struct pcf50633 *gta02_pcf; |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * This gets called every 1ms when we paniced. | 93 | * This gets called frequently when we paniced. |
94 | */ | 94 | */ |
95 | 95 | ||
96 | static long gta02_panic_blink(long count) | 96 | static long gta02_panic_blink(int state) |
97 | { | 97 | { |
98 | long delay = 0; | 98 | long delay = 0; |
99 | static long last_blink; | 99 | char led; |
100 | static char led; | ||
101 | 100 | ||
102 | /* Fast blink: 200ms period. */ | 101 | led = (state) ? 1 : 0; |
103 | if (count - last_blink < 100) | ||
104 | return 0; | ||
105 | |||
106 | led ^= 1; | ||
107 | gpio_direction_output(GTA02_GPIO_AUX_LED, led); | 102 | gpio_direction_output(GTA02_GPIO_AUX_LED, led); |
108 | 103 | ||
109 | last_blink = count; | ||
110 | |||
111 | return delay; | 104 | return delay; |
112 | } | 105 | } |
113 | 106 | ||
@@ -556,7 +549,7 @@ static void gta02_poweroff(void) | |||
556 | 549 | ||
557 | static void __init gta02_machine_init(void) | 550 | static void __init gta02_machine_init(void) |
558 | { | 551 | { |
559 | /* Set the panic callback to make AUX LED blink at ~5Hz. */ | 552 | /* Set the panic callback to turn AUX LED on or off. */ |
560 | panic_blink = gta02_panic_blink; | 553 | panic_blink = gta02_panic_blink; |
561 | 554 | ||
562 | s3c_pm_init(); | 555 | s3c_pm_init(); |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 258b98b9d7c2..46e4ba0b9246 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -61,10 +61,6 @@ static bool i8042_noloop; | |||
61 | module_param_named(noloop, i8042_noloop, bool, 0); | 61 | module_param_named(noloop, i8042_noloop, bool, 0); |
62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | 62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); |
63 | 63 | ||
64 | static unsigned int i8042_blink_frequency = 500; | ||
65 | module_param_named(panicblink, i8042_blink_frequency, uint, 0600); | ||
66 | MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); | ||
67 | |||
68 | #ifdef CONFIG_X86 | 64 | #ifdef CONFIG_X86 |
69 | static bool i8042_dritek; | 65 | static bool i8042_dritek; |
70 | module_param_named(dritek, i8042_dritek, bool, 0); | 66 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -1030,8 +1026,8 @@ static void i8042_controller_reset(void) | |||
1030 | 1026 | ||
1031 | 1027 | ||
1032 | /* | 1028 | /* |
1033 | * i8042_panic_blink() will flash the keyboard LEDs and is called when | 1029 | * i8042_panic_blink() will turn the keyboard LEDs on or off and is called |
1034 | * kernel panics. Flashing LEDs is useful for users running X who may | 1030 | * when kernel panics. Flashing LEDs is useful for users running X who may |
1035 | * not see the console and will help distingushing panics from "real" | 1031 | * not see the console and will help distingushing panics from "real" |
1036 | * lockups. | 1032 | * lockups. |
1037 | * | 1033 | * |
@@ -1041,22 +1037,12 @@ static void i8042_controller_reset(void) | |||
1041 | 1037 | ||
1042 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) | 1038 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) |
1043 | 1039 | ||
1044 | static long i8042_panic_blink(long count) | 1040 | static long i8042_panic_blink(int state) |
1045 | { | 1041 | { |
1046 | long delay = 0; | 1042 | long delay = 0; |
1047 | static long last_blink; | 1043 | char led; |
1048 | static char led; | ||
1049 | |||
1050 | /* | ||
1051 | * We expect frequency to be about 1/2s. KDB uses about 1s. | ||
1052 | * Make sure they are different. | ||
1053 | */ | ||
1054 | if (!i8042_blink_frequency) | ||
1055 | return 0; | ||
1056 | if (count - last_blink < i8042_blink_frequency) | ||
1057 | return 0; | ||
1058 | 1044 | ||
1059 | led ^= 0x01 | 0x04; | 1045 | led = (state) ? 0x01 | 0x04 : 0; |
1060 | while (i8042_read_status() & I8042_STR_IBF) | 1046 | while (i8042_read_status() & I8042_STR_IBF) |
1061 | DELAY; | 1047 | DELAY; |
1062 | dbg("%02x -> i8042 (panic blink)", 0xed); | 1048 | dbg("%02x -> i8042 (panic blink)", 0xed); |
@@ -1069,7 +1055,6 @@ static long i8042_panic_blink(long count) | |||
1069 | dbg("%02x -> i8042 (panic blink)", led); | 1055 | dbg("%02x -> i8042 (panic blink)", led); |
1070 | i8042_write_data(led); | 1056 | i8042_write_data(led); |
1071 | DELAY; | 1057 | DELAY; |
1072 | last_blink = count; | ||
1073 | return delay; | 1058 | return delay; |
1074 | } | 1059 | } |
1075 | 1060 | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5b57236dfbd0..452833d67b21 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -177,7 +177,7 @@ struct va_format { | |||
177 | }; | 177 | }; |
178 | 178 | ||
179 | extern struct atomic_notifier_head panic_notifier_list; | 179 | extern struct atomic_notifier_head panic_notifier_list; |
180 | extern long (*panic_blink)(long time); | 180 | extern long (*panic_blink)(int state); |
181 | NORET_TYPE void panic(const char * fmt, ...) | 181 | NORET_TYPE void panic(const char * fmt, ...) |
182 | __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; | 182 | __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; |
183 | extern void oops_enter(void); | 183 | extern void oops_enter(void); |
diff --git a/kernel/panic.c b/kernel/panic.c index 3b16cd93fa7d..3e9037ae10e1 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -24,6 +24,9 @@ | |||
24 | #include <linux/nmi.h> | 24 | #include <linux/nmi.h> |
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | 26 | ||
27 | #define PANIC_TIMER_STEP 100 | ||
28 | #define PANIC_BLINK_SPD 18 | ||
29 | |||
27 | int panic_on_oops; | 30 | int panic_on_oops; |
28 | static unsigned long tainted_mask; | 31 | static unsigned long tainted_mask; |
29 | static int pause_on_oops; | 32 | static int pause_on_oops; |
@@ -36,36 +39,15 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list); | |||
36 | 39 | ||
37 | EXPORT_SYMBOL(panic_notifier_list); | 40 | EXPORT_SYMBOL(panic_notifier_list); |
38 | 41 | ||
39 | /* Returns how long it waited in ms */ | 42 | static long no_blink(int state) |
40 | long (*panic_blink)(long time); | ||
41 | EXPORT_SYMBOL(panic_blink); | ||
42 | |||
43 | static void panic_blink_one_second(void) | ||
44 | { | 43 | { |
45 | static long i = 0, end; | 44 | return 0; |
46 | |||
47 | if (panic_blink) { | ||
48 | end = i + MSEC_PER_SEC; | ||
49 | |||
50 | while (i < end) { | ||
51 | i += panic_blink(i); | ||
52 | mdelay(1); | ||
53 | i++; | ||
54 | } | ||
55 | } else { | ||
56 | /* | ||
57 | * When running under a hypervisor a small mdelay may get | ||
58 | * rounded up to the hypervisor timeslice. For example, with | ||
59 | * a 1ms in 10ms hypervisor timeslice we might inflate a | ||
60 | * mdelay(1) loop by 10x. | ||
61 | * | ||
62 | * If we have nothing to blink, spin on 1 second calls to | ||
63 | * mdelay to avoid this. | ||
64 | */ | ||
65 | mdelay(MSEC_PER_SEC); | ||
66 | } | ||
67 | } | 45 | } |
68 | 46 | ||
47 | /* Returns how long it waited in ms */ | ||
48 | long (*panic_blink)(int state); | ||
49 | EXPORT_SYMBOL(panic_blink); | ||
50 | |||
69 | /** | 51 | /** |
70 | * panic - halt the system | 52 | * panic - halt the system |
71 | * @fmt: The text string to print | 53 | * @fmt: The text string to print |
@@ -78,7 +60,8 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
78 | { | 60 | { |
79 | static char buf[1024]; | 61 | static char buf[1024]; |
80 | va_list args; | 62 | va_list args; |
81 | long i; | 63 | long i, i_next = 0; |
64 | int state = 0; | ||
82 | 65 | ||
83 | /* | 66 | /* |
84 | * It's possible to come here directly from a panic-assertion and | 67 | * It's possible to come here directly from a panic-assertion and |
@@ -117,6 +100,9 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
117 | 100 | ||
118 | bust_spinlocks(0); | 101 | bust_spinlocks(0); |
119 | 102 | ||
103 | if (!panic_blink) | ||
104 | panic_blink = no_blink; | ||
105 | |||
120 | if (panic_timeout > 0) { | 106 | if (panic_timeout > 0) { |
121 | /* | 107 | /* |
122 | * Delay timeout seconds before rebooting the machine. | 108 | * Delay timeout seconds before rebooting the machine. |
@@ -124,9 +110,13 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
124 | */ | 110 | */ |
125 | printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); | 111 | printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); |
126 | 112 | ||
127 | for (i = 0; i < panic_timeout; i++) { | 113 | for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) { |
128 | touch_nmi_watchdog(); | 114 | touch_nmi_watchdog(); |
129 | panic_blink_one_second(); | 115 | if (i >= i_next) { |
116 | i += panic_blink(state ^= 1); | ||
117 | i_next = i + 3600 / PANIC_BLINK_SPD; | ||
118 | } | ||
119 | mdelay(PANIC_TIMER_STEP); | ||
130 | } | 120 | } |
131 | /* | 121 | /* |
132 | * This will not be a clean reboot, with everything | 122 | * This will not be a clean reboot, with everything |
@@ -152,9 +142,13 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
152 | } | 142 | } |
153 | #endif | 143 | #endif |
154 | local_irq_enable(); | 144 | local_irq_enable(); |
155 | while (1) { | 145 | for (i = 0; ; i += PANIC_TIMER_STEP) { |
156 | touch_softlockup_watchdog(); | 146 | touch_softlockup_watchdog(); |
157 | panic_blink_one_second(); | 147 | if (i >= i_next) { |
148 | i += panic_blink(state ^= 1); | ||
149 | i_next = i + 3600 / PANIC_BLINK_SPD; | ||
150 | } | ||
151 | mdelay(PANIC_TIMER_STEP); | ||
158 | } | 152 | } |
159 | } | 153 | } |
160 | 154 | ||