brcm47xx: update watchdog driver
[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)