Commit d6517c4c192b04016e2fbf12322bc6bd00f23835

Authored by Jesper Nilsson
1 parent dbd3c7e1bf

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) {