aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2012-12-05 12:46:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-12-06 14:58:57 -0500
commit7ffbffe37de3979d43c1105e38eb2918bf5d35fe (patch)
tree40fdf7ca496cc75111ba81fbdf211641b2b9ae8f
parent26107309c08f8548a2e0aef0d0aabd64bc2d22c1 (diff)
ssb: add methods for watchdog driver
The watchdog driver wants to set the watchdog timeout in ms and not in ticks, which is depending on the SoC type and the clock. Calculate the number of ticks per millisecond and provide two functions for the watchdog driver. Also return the ticks or millisecond the timer was set to in case the provided value was bigger than the max allowed value. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/ssb/driver_chipcommon.c47
-rw-r--r--drivers/ssb/ssb_private.h5
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h5
3 files changed, 54 insertions, 3 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 6e080f6a07a5..95c33a05f434 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright 2005, Broadcom Corporation 5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7 * 8 *
8 * Licensed under the GNU/GPL. See COPYING for details. 9 * Licensed under the GNU/GPL. See COPYING for details.
9 */ 10 */
@@ -12,6 +13,7 @@
12#include <linux/ssb/ssb_regs.h> 13#include <linux/ssb/ssb_regs.h>
13#include <linux/export.h> 14#include <linux/export.h>
14#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/bcm47xx_wdt.h>
15 17
16#include "ssb_private.h" 18#include "ssb_private.h"
17 19
@@ -306,6 +308,43 @@ static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)
306 return (1 << nb) - 1; 308 return (1 << nb) - 1;
307} 309}
308 310
311u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
312{
313 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
314
315 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
316 return 0;
317
318 return ssb_chipco_watchdog_timer_set(cc, ticks);
319}
320
321u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
322{
323 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
324 u32 ticks;
325
326 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
327 return 0;
328
329 ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
330 return ticks / cc->ticks_per_ms;
331}
332
333static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)
334{
335 struct ssb_bus *bus = cc->dev->bus;
336
337 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
338 /* based on 32KHz ILP clock */
339 return 32;
340 } else {
341 if (cc->dev->id.revision < 18)
342 return ssb_clockspeed(bus) / 1000;
343 else
344 return ssb_chipco_alp_clock(cc) / 1000;
345 }
346}
347
309void ssb_chipcommon_init(struct ssb_chipcommon *cc) 348void ssb_chipcommon_init(struct ssb_chipcommon *cc)
310{ 349{
311 if (!cc->dev) 350 if (!cc->dev)
@@ -323,6 +362,11 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
323 chipco_powercontrol_init(cc); 362 chipco_powercontrol_init(cc);
324 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); 363 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
325 calc_fast_powerup_delay(cc); 364 calc_fast_powerup_delay(cc);
365
366 if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {
367 cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);
368 cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
369 }
326} 370}
327 371
328void ssb_chipco_suspend(struct ssb_chipcommon *cc) 372void ssb_chipco_suspend(struct ssb_chipcommon *cc)
@@ -421,7 +465,7 @@ void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
421} 465}
422 466
423/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 467/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
424void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) 468u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
425{ 469{
426 u32 maxt; 470 u32 maxt;
427 enum ssb_clkmode clkmode; 471 enum ssb_clkmode clkmode;
@@ -441,6 +485,7 @@ void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
441 /* instant NMI */ 485 /* instant NMI */
442 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); 486 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
443 } 487 }
488 return ticks;
444} 489}
445 490
446void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) 491void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 98b2915cd30b..03cc40a71510 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/ssb/ssb.h> 4#include <linux/ssb/ssb.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/bcm47xx_wdt.h>
6 7
7 8
8#define PFX "ssb: " 9#define PFX "ssb: "
@@ -212,4 +213,8 @@ extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
212extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); 213extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
213extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); 214extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc);
214 215
216extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
217 u32 ticks);
218extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
219
215#endif /* LINUX_SSB_PRIVATE_H_ */ 220#endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index c2b02a5c86ae..38339fd68a5f 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -591,6 +591,8 @@ struct ssb_chipcommon {
591 /* Fast Powerup Delay constant */ 591 /* Fast Powerup Delay constant */
592 u16 fast_pwrup_delay; 592 u16 fast_pwrup_delay;
593 struct ssb_chipcommon_pmu pmu; 593 struct ssb_chipcommon_pmu pmu;
594 u32 ticks_per_ms;
595 u32 max_timer_ms;
594}; 596};
595 597
596static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) 598static inline bool ssb_chipco_available(struct ssb_chipcommon *cc)
@@ -630,8 +632,7 @@ enum ssb_clkmode {
630extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, 632extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
631 enum ssb_clkmode mode); 633 enum ssb_clkmode mode);
632 634
633extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, 635extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks);
634 u32 ticks);
635 636
636void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); 637void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value);
637 638