Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ssb: set the PMU watchdog if available

Some ssb based devices have a PMU and the PMU watchdog register should
be used instead of the register in the chip common part, if the device
has a PMU. This patch also calculates the maximal number the watchdog
could be set to.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Hauke Mehrtens and committed by
John W. Linville
26107309 f924e1e9

+36 -2
+36 -2
drivers/ssb/driver_chipcommon.c
··· 288 288 return 20000000; 289 289 } 290 290 291 + static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc) 292 + { 293 + u32 nb; 294 + 295 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { 296 + if (cc->dev->id.revision < 26) 297 + nb = 16; 298 + else 299 + nb = (cc->dev->id.revision >= 37) ? 32 : 24; 300 + } else { 301 + nb = 28; 302 + } 303 + if (nb == 32) 304 + return 0xffffffff; 305 + else 306 + return (1 << nb) - 1; 307 + } 308 + 291 309 void ssb_chipcommon_init(struct ssb_chipcommon *cc) 292 310 { 293 311 if (!cc->dev) ··· 423 405 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 424 406 void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) 425 407 { 426 - /* instant NMI */ 427 - chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); 408 + u32 maxt; 409 + enum ssb_clkmode clkmode; 410 + 411 + maxt = ssb_chipco_watchdog_get_max_timer(cc); 412 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { 413 + if (ticks == 1) 414 + ticks = 2; 415 + else if (ticks > maxt) 416 + ticks = maxt; 417 + chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks); 418 + } else { 419 + clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC; 420 + ssb_chipco_set_clockmode(cc, clkmode); 421 + if (ticks > maxt) 422 + ticks = maxt; 423 + /* instant NMI */ 424 + chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); 425 + } 428 426 } 429 427 430 428 void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)