aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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