diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-2.6.36')
| -rw-r--r-- | target/linux/brcm47xx/patches-2.6.36/900-bcm47xx_wdt-noprescale.patch | 89 | 
1 files changed, 89 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-2.6.36/900-bcm47xx_wdt-noprescale.patch b/target/linux/brcm47xx/patches-2.6.36/900-bcm47xx_wdt-noprescale.patch new file mode 100644 index 000000000..6bc2b12eb --- /dev/null +++ b/target/linux/brcm47xx/patches-2.6.36/900-bcm47xx_wdt-noprescale.patch @@ -0,0 +1,89 @@ +--- a/drivers/watchdog/bcm47xx_wdt.c ++++ b/drivers/watchdog/bcm47xx_wdt.c +@@ -31,6 +31,7 @@ +  + #define WDT_DEFAULT_TIME	30	/* seconds */ + #define WDT_MAX_TIME		255	/* seconds */ ++#define WDT_SHIFT		15	/* 32.768 KHz on cores with slow WDT clock */ +  + static int wdt_time = WDT_DEFAULT_TIME; + static int nowayout = WATCHDOG_NOWAYOUT; +@@ -50,11 +51,11 @@ static unsigned long bcm47xx_wdt_busy; + static char expect_release; + static struct timer_list wdt_timer; + static atomic_t ticks; ++static int needs_sw_scale; +  +-static inline void bcm47xx_wdt_hw_start(void) ++static inline void bcm47xx_wdt_hw_start(u32 ticks) + { +-	/* this is 2,5s on 100Mhz clock  and 2s on 133 Mhz */ +-	ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff); ++ 	ssb_watchdog_timer_set(&ssb_bcm47xx, ticks); + } +  + static inline int bcm47xx_wdt_hw_stop(void) +@@ -65,33 +66,34 @@ static inline int bcm47xx_wdt_hw_stop(vo + static void bcm47xx_timer_tick(unsigned long unused) + { + 	if (!atomic_dec_and_test(&ticks)) { +-		bcm47xx_wdt_hw_start(); ++		/* This is 2,5s on 100Mhz clock and 2s on 133 Mhz */ ++		bcm47xx_wdt_hw_start(0xfffffff); + 		mod_timer(&wdt_timer, jiffies + HZ); + 	} else { +-		printk(KERN_CRIT DRV_NAME "Watchdog will fire soon!!!\n"); ++		printk(KERN_CRIT DRV_NAME ": Watchdog will fire soon!!!\n"); + 	} + } +  +-static inline void bcm47xx_wdt_pet(void) ++static void bcm47xx_wdt_pet(void) + { +-	atomic_set(&ticks, wdt_time); ++	if(needs_sw_scale) ++		atomic_set(&ticks, wdt_time); ++	else ++		bcm47xx_wdt_hw_start(wdt_time << WDT_SHIFT); + } +  + static void bcm47xx_wdt_start(void) + { + 	bcm47xx_wdt_pet(); +-	bcm47xx_timer_tick(0); +-} +- +-static void bcm47xx_wdt_pause(void) +-{ +-	del_timer_sync(&wdt_timer); +-	bcm47xx_wdt_hw_stop(); ++	if(needs_sw_scale) ++		bcm47xx_timer_tick(0); + } +  + static void bcm47xx_wdt_stop(void) + { +-	bcm47xx_wdt_pause(); ++	if(needs_sw_scale) ++		del_timer_sync(&wdt_timer); ++	bcm47xx_wdt_hw_stop(); + } +  + static int bcm47xx_wdt_settimeout(int new_time) +@@ -243,7 +245,15 @@ static int __init bcm47xx_wdt_init(void) + 	if (bcm47xx_wdt_hw_stop() < 0) + 		return -ENODEV; +  +-	setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L); ++	/* FIXME Other cores */ ++	if(ssb_bcm47xx.chip_id == 0x5354) { ++		/* Slow WDT clock, no pre-scaling */ ++		needs_sw_scale = 0; ++	} else { ++		/* Fast WDT clock, needs software pre-scaling */ ++		needs_sw_scale = 1; ++		setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L); ++	} +  + 	if (bcm47xx_wdt_settimeout(wdt_time)) { + 		bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);  | 
