Commit d6517c4c192b04016e2fbf12322bc6bd00f23835
1 parent
dbd3c7e1bf
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
CRISv32: Better handling of watchdog bite
Don't enter watchdog handling if we're already in watchdog handling. Also some minor formatting tweaks. Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Showing 1 changed file with 17 additions and 11 deletions Side-by-side Diff
arch/cris/arch-v32/kernel/time.c
... | ... | @@ -57,7 +57,6 @@ |
57 | 57 | } |
58 | 58 | arch_initcall(etrax_init_cont_rotime); |
59 | 59 | |
60 | - | |
61 | 60 | unsigned long timer_regs[NR_CPUS] = |
62 | 61 | { |
63 | 62 | regi_timer0, |
... | ... | @@ -69,9 +68,8 @@ |
69 | 68 | extern int set_rtc_mmss(unsigned long nowtime); |
70 | 69 | |
71 | 70 | #ifdef CONFIG_CPU_FREQ |
72 | -static int | |
73 | -cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, | |
74 | - void *data); | |
71 | +static int cris_time_freq_notifier(struct notifier_block *nb, | |
72 | + unsigned long val, void *data); | |
75 | 73 | |
76 | 74 | static struct notifier_block cris_time_freq_notifier_block = { |
77 | 75 | .notifier_call = cris_time_freq_notifier, |
... | ... | @@ -88,7 +86,6 @@ |
88 | 86 | return ns; |
89 | 87 | } |
90 | 88 | |
91 | - | |
92 | 89 | /* From timer MDS describing the hardware watchdog: |
93 | 90 | * 4.3.1 Watchdog Operation |
94 | 91 | * The watchdog timer is an 8-bit timer with a configurable start value. |
95 | 92 | |
... | ... | @@ -110,11 +107,18 @@ |
110 | 107 | * is used though, so set this really low. */ |
111 | 108 | #define WATCHDOG_MIN_FREE_PAGES 8 |
112 | 109 | |
110 | +/* for reliable NICE_DOGGY behaviour */ | |
111 | +static int bite_in_progress; | |
112 | + | |
113 | 113 | void reset_watchdog(void) |
114 | 114 | { |
115 | 115 | #if defined(CONFIG_ETRAX_WATCHDOG) |
116 | 116 | reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; |
117 | 117 | |
118 | +#if defined(CONFIG_ETRAX_WATCHDOG_NICE_DOGGY) | |
119 | + if (unlikely(bite_in_progress)) | |
120 | + return; | |
121 | +#endif | |
118 | 122 | /* Only keep watchdog happy as long as we have memory left! */ |
119 | 123 | if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { |
120 | 124 | /* Reset the watchdog with the inverse of the old key */ |
121 | 125 | |
... | ... | @@ -149,7 +153,9 @@ |
149 | 153 | #if defined(CONFIG_ETRAX_WATCHDOG) |
150 | 154 | extern int cause_of_death; |
151 | 155 | |
156 | + nmi_enter(); | |
152 | 157 | oops_in_progress = 1; |
158 | + bite_in_progress = 1; | |
153 | 159 | printk(KERN_WARNING "Watchdog bite\n"); |
154 | 160 | |
155 | 161 | /* Check if forced restart or unexpected watchdog */ |
... | ... | @@ -171,6 +177,7 @@ |
171 | 177 | printk(KERN_WARNING "Oops: bitten by watchdog\n"); |
172 | 178 | show_registers(regs); |
173 | 179 | oops_in_progress = 0; |
180 | + printk("\n"); /* Flush mtdoops. */ | |
174 | 181 | #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
175 | 182 | reset_watchdog(); |
176 | 183 | #endif |
... | ... | @@ -203,7 +210,7 @@ |
203 | 210 | /* Reset watchdog otherwise it resets us! */ |
204 | 211 | reset_watchdog(); |
205 | 212 | |
206 | - /* Update statistics. */ | |
213 | + /* Update statistics. */ | |
207 | 214 | update_process_times(user_mode(regs)); |
208 | 215 | |
209 | 216 | cris_do_profile(regs); /* Save profiling information */ |
... | ... | @@ -214,7 +221,7 @@ |
214 | 221 | |
215 | 222 | /* Call the real timer interrupt handler */ |
216 | 223 | xtime_update(1); |
217 | - return IRQ_HANDLED; | |
224 | + return IRQ_HANDLED; | |
218 | 225 | } |
219 | 226 | |
220 | 227 | /* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */ |
221 | 228 | |
... | ... | @@ -294,14 +301,13 @@ |
294 | 301 | |
295 | 302 | #ifdef CONFIG_CPU_FREQ |
296 | 303 | cpufreq_register_notifier(&cris_time_freq_notifier_block, |
297 | - CPUFREQ_TRANSITION_NOTIFIER); | |
304 | + CPUFREQ_TRANSITION_NOTIFIER); | |
298 | 305 | #endif |
299 | 306 | } |
300 | 307 | |
301 | 308 | #ifdef CONFIG_CPU_FREQ |
302 | -static int | |
303 | -cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, | |
304 | - void *data) | |
309 | +static int cris_time_freq_notifier(struct notifier_block *nb, | |
310 | + unsigned long val, void *data) | |
305 | 311 | { |
306 | 312 | struct cpufreq_freqs *freqs = data; |
307 | 313 | if (val == CPUFREQ_POSTCHANGE) { |