aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt3
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c17
-rw-r--r--drivers/input/serio/i8042.c25
-rw-r--r--include/linux/kernel.h2
-rw-r--r--kernel/panic.c58
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 @@
90static struct pcf50633 *gta02_pcf; 90static 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
96static long gta02_panic_blink(long count) 96static 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
557static void __init gta02_machine_init(void) 550static 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;
61module_param_named(noloop, i8042_noloop, bool, 0); 61module_param_named(noloop, i8042_noloop, bool, 0);
62MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); 62MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port");
63 63
64static unsigned int i8042_blink_frequency = 500;
65module_param_named(panicblink, i8042_blink_frequency, uint, 0600);
66MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics");
67
68#ifdef CONFIG_X86 64#ifdef CONFIG_X86
69static bool i8042_dritek; 65static bool i8042_dritek;
70module_param_named(dritek, i8042_dritek, bool, 0); 66module_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
1044static long i8042_panic_blink(long count) 1040static 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
179extern struct atomic_notifier_head panic_notifier_list; 179extern struct atomic_notifier_head panic_notifier_list;
180extern long (*panic_blink)(long time); 180extern long (*panic_blink)(int state);
181NORET_TYPE void panic(const char * fmt, ...) 181NORET_TYPE void panic(const char * fmt, ...)
182 __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; 182 __attribute__ ((NORET_AND format (printf, 1, 2))) __cold;
183extern void oops_enter(void); 183extern 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
27int panic_on_oops; 30int panic_on_oops;
28static unsigned long tainted_mask; 31static unsigned long tainted_mask;
29static int pause_on_oops; 32static int pause_on_oops;
@@ -36,36 +39,15 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
36 39
37EXPORT_SYMBOL(panic_notifier_list); 40EXPORT_SYMBOL(panic_notifier_list);
38 41
39/* Returns how long it waited in ms */ 42static long no_blink(int state)
40long (*panic_blink)(long time);
41EXPORT_SYMBOL(panic_blink);
42
43static 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 */
48long (*panic_blink)(int state);
49EXPORT_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