Root/target/linux/brcm47xx/patches-3.0/900-bcm47xx_wdt-noprescale.patch

1--- a/drivers/watchdog/bcm47xx_wdt.c
2+++ b/drivers/watchdog/bcm47xx_wdt.c
3@@ -31,6 +31,7 @@
4 
5 #define WDT_DEFAULT_TIME 30 /* seconds */
6 #define WDT_MAX_TIME 255 /* seconds */
7+#define WDT_SHIFT 15 /* 32.768 KHz on cores with slow WDT clock */
8 
9 static int wdt_time = WDT_DEFAULT_TIME;
10 static int nowayout = WATCHDOG_NOWAYOUT;
11@@ -50,20 +51,20 @@ static unsigned long bcm47xx_wdt_busy;
12 static char expect_release;
13 static struct timer_list wdt_timer;
14 static atomic_t ticks;
15+static int needs_sw_scale;
16 
17-static inline void bcm47xx_wdt_hw_start(void)
18+static inline void bcm47xx_wdt_hw_start(u32 ticks)
19 {
20- /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
21     switch (bcm47xx_bus_type) {
22 #ifdef CONFIG_BCM47XX_SSB
23     case BCM47XX_BUS_TYPE_SSB:
24- ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
25+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, ticks);
26         break;
27 #endif
28 #ifdef CONFIG_BCM47XX_BCMA
29     case BCM47XX_BUS_TYPE_BCMA:
30         bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
31- 0xfffffff);
32+ ticks);
33         break;
34 #endif
35     }
36@@ -88,33 +89,34 @@ static inline int bcm47xx_wdt_hw_stop(vo
37 static void bcm47xx_timer_tick(unsigned long unused)
38 {
39     if (!atomic_dec_and_test(&ticks)) {
40- bcm47xx_wdt_hw_start();
41+ /* This is 2,5s on 100Mhz clock and 2s on 133 Mhz */
42+ bcm47xx_wdt_hw_start(0xfffffff);
43         mod_timer(&wdt_timer, jiffies + HZ);
44     } else {
45- printk(KERN_CRIT DRV_NAME "Watchdog will fire soon!!!\n");
46+ printk(KERN_CRIT DRV_NAME ": Watchdog will fire soon!!!\n");
47     }
48 }
49 
50-static inline void bcm47xx_wdt_pet(void)
51+static void bcm47xx_wdt_pet(void)
52 {
53- atomic_set(&ticks, wdt_time);
54+ if(needs_sw_scale)
55+ atomic_set(&ticks, wdt_time);
56+ else
57+ bcm47xx_wdt_hw_start(wdt_time << WDT_SHIFT);
58 }
59 
60 static void bcm47xx_wdt_start(void)
61 {
62     bcm47xx_wdt_pet();
63- bcm47xx_timer_tick(0);
64-}
65-
66-static void bcm47xx_wdt_pause(void)
67-{
68- del_timer_sync(&wdt_timer);
69- bcm47xx_wdt_hw_stop();
70+ if(needs_sw_scale)
71+ bcm47xx_timer_tick(0);
72 }
73 
74 static void bcm47xx_wdt_stop(void)
75 {
76- bcm47xx_wdt_pause();
77+ if(needs_sw_scale)
78+ del_timer_sync(&wdt_timer);
79+ bcm47xx_wdt_hw_stop();
80 }
81 
82 static int bcm47xx_wdt_settimeout(int new_time)
83@@ -266,7 +268,20 @@ static int __init bcm47xx_wdt_init(void)
84     if (bcm47xx_wdt_hw_stop() < 0)
85         return -ENODEV;
86 
87- setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
88+ /* FIXME Other cores */
89+#ifdef BCM47XX_BUS_TYPE_BCMA
90+ if(bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
91+ bcm47xx_bus.ssb.chip_id == 0x5354) {
92+ /* Slow WDT clock, no pre-scaling */
93+ needs_sw_scale = 0;
94+ } else {
95+#endif
96+ /* Fast WDT clock, needs software pre-scaling */
97+ needs_sw_scale = 1;
98+ setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
99+#ifdef BCM47XX_BUS_TYPE_BCMA
100+ }
101+#endif
102 
103     if (bcm47xx_wdt_settimeout(wdt_time)) {
104         bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
105

Archive Download this file



interactive