brcm47xx: update watchdog driver
[openwrt/openwrt.git] / target / linux / brcm47xx / patches-3.6 / 546-bcma-set-the-pmu-watchdog-if-available.patch
1 --- a/drivers/bcma/driver_chipcommon.c
2 +++ b/drivers/bcma/driver_chipcommon.c
3 @@ -31,6 +31,28 @@ static u32 bcma_chipco_alp_clock(struct
4 return 20000000;
5 }
6
7 +static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
8 +{
9 + struct bcma_bus *bus = cc->core->bus;
10 + u32 nb;
11 +
12 + if (cc->capabilities & BCMA_CC_CAP_PMU) {
13 + if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
14 + nb = 32;
15 + else if (cc->core->id.rev < 26)
16 + nb = 16;
17 + else
18 + nb = (cc->core->id.rev >= 37) ? 32 : 24;
19 + } else {
20 + nb = 28;
21 + }
22 + if (nb == 32)
23 + return 0xffffffff;
24 + else
25 + return (1 << nb) - 1;
26 +}
27 +
28 +
29 void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
30 {
31 if (cc->early_setup_done)
32 @@ -87,8 +109,23 @@ void bcma_core_chipcommon_init(struct bc
33 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
34 void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
35 {
36 - /* instant NMI */
37 - bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
38 + u32 maxt;
39 + enum bcma_clkmode clkmode;
40 +
41 + maxt = bcma_chipco_watchdog_get_max_timer(cc);
42 + if (cc->capabilities & BCMA_CC_CAP_PMU) {
43 + if (ticks == 1)
44 + ticks = 2;
45 + else if (ticks > maxt)
46 + ticks = maxt;
47 + bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
48 + } else {
49 + clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC;
50 + bcma_core_set_clockmode(cc->core, clkmode);
51 + if (ticks > maxt)
52 + ticks = maxt;
53 + bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
54 + }
55 }
56
57 void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)