brcm47xx: add initial support for devices with bcma bus.
[openwrt/staging/mkresin.git] / 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_active_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_active_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);