Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+17 -11
+17 -11
arch/cris/arch-v32/kernel/time.c
··· 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, ··· 68 69 extern int set_rtc_mmss(unsigned long nowtime); 69 70 70 71 #ifdef CONFIG_CPU_FREQ 71 - static int 72 - cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, 73 - void *data); 72 + static int cris_time_freq_notifier(struct notifier_block *nb, 73 + unsigned long val, void *data); 74 74 75 75 static struct notifier_block cris_time_freq_notifier_block = { 76 76 .notifier_call = cris_time_freq_notifier, ··· 85 87 ns = (TIMER0_DIV - data) * 10; 86 88 return ns; 87 89 } 88 - 89 90 90 91 /* From timer MDS describing the hardware watchdog: 91 92 * 4.3.1 Watchdog Operation ··· 107 110 * is used though, so set this really low. */ 108 111 #define WATCHDOG_MIN_FREE_PAGES 8 109 112 113 + /* for reliable NICE_DOGGY behaviour */ 114 + static int bite_in_progress; 115 + 110 116 void reset_watchdog(void) 111 117 { 112 118 #if defined(CONFIG_ETRAX_WATCHDOG) 113 119 reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; 114 120 121 + #if defined(CONFIG_ETRAX_WATCHDOG_NICE_DOGGY) 122 + if (unlikely(bite_in_progress)) 123 + return; 124 + #endif 115 125 /* Only keep watchdog happy as long as we have memory left! */ 116 126 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { 117 127 /* Reset the watchdog with the inverse of the old key */ ··· 153 149 #if defined(CONFIG_ETRAX_WATCHDOG) 154 150 extern int cause_of_death; 155 151 152 + nmi_enter(); 156 153 oops_in_progress = 1; 154 + bite_in_progress = 1; 157 155 printk(KERN_WARNING "Watchdog bite\n"); 158 156 159 157 /* Check if forced restart or unexpected watchdog */ ··· 177 171 printk(KERN_WARNING "Oops: bitten by watchdog\n"); 178 172 show_registers(regs); 179 173 oops_in_progress = 0; 174 + printk("\n"); /* Flush mtdoops. */ 180 175 #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 181 176 reset_watchdog(); 182 177 #endif ··· 210 203 /* Reset watchdog otherwise it resets us! */ 211 204 reset_watchdog(); 212 205 213 - /* Update statistics. */ 206 + /* Update statistics. */ 214 207 update_process_times(user_mode(regs)); 215 208 216 209 cris_do_profile(regs); /* Save profiling information */ ··· 221 214 222 215 /* Call the real timer interrupt handler */ 223 216 xtime_update(1); 224 - return IRQ_HANDLED; 217 + return IRQ_HANDLED; 225 218 } 226 219 227 220 /* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */ ··· 301 294 302 295 #ifdef CONFIG_CPU_FREQ 303 296 cpufreq_register_notifier(&cris_time_freq_notifier_block, 304 - CPUFREQ_TRANSITION_NOTIFIER); 297 + CPUFREQ_TRANSITION_NOTIFIER); 305 298 #endif 306 299 } 307 300 308 301 #ifdef CONFIG_CPU_FREQ 309 - static int 310 - cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, 311 - void *data) 302 + static int cris_time_freq_notifier(struct notifier_block *nb, 303 + unsigned long val, void *data) 312 304 { 313 305 struct cpufreq_freqs *freqs = data; 314 306 if (val == CPUFREQ_POSTCHANGE) {