summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch54
1 files changed, 54 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch b/target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch
new file mode 100644
index 000000000..f7cc07bcd
--- /dev/null
+++ b/target/linux/brcm47xx/patches-3.6/550-ssb-set-the-pmu-watchdog-if-available.patch
@@ -0,0 +1,54 @@
+--- a/drivers/ssb/driver_chipcommon.c
++++ b/drivers/ssb/driver_chipcommon.c
+@@ -288,6 +288,24 @@ static u32 ssb_chipco_alp_clock(struct s
+ return 20000000;
+ }
+
++static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)
++{
++ u32 nb;
++
++ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
++ if (cc->dev->id.revision < 26)
++ nb = 16;
++ else
++ nb = (cc->dev->id.revision >= 37) ? 32 : 24;
++ } else {
++ nb = 28;
++ }
++ if (nb == 32)
++ return 0xffffffff;
++ else
++ return (1 << nb) - 1;
++}
++
+ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
+ {
+ if (!cc->dev)
+@@ -405,8 +423,24 @@ void ssb_chipco_timing_init(struct ssb_c
+ /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
+ void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
+ {
+- /* instant NMI */
+- chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
++ u32 maxt;
++ enum ssb_clkmode clkmode;
++
++ maxt = ssb_chipco_watchdog_get_max_timer(cc);
++ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
++ if (ticks == 1)
++ ticks = 2;
++ else if (ticks > maxt)
++ ticks = maxt;
++ chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);
++ } else {
++ clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;
++ ssb_chipco_set_clockmode(cc, clkmode);
++ if (ticks > maxt)
++ ticks = maxt;
++ /* instant NMI */
++ chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
++ }
+ }
+
+ void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)