diff options
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 47 | ||||
-rw-r--r-- | drivers/ssb/ssb_private.h | 5 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_chipcommon.h | 5 |
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 | ||
311 | u32 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 | |||
321 | u32 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 | |||
333 | static 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 | |||
309 | void ssb_chipcommon_init(struct ssb_chipcommon *cc) | 348 | void 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 | ||
328 | void ssb_chipco_suspend(struct ssb_chipcommon *cc) | 372 | void 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 */ |
424 | void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) | 468 | u32 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 | ||
446 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) | 491 | void 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); | |||
212 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); | 213 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); |
213 | extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); | 214 | extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); |
214 | 215 | ||
216 | extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, | ||
217 | u32 ticks); | ||
218 | extern 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 | ||
596 | static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) | 598 | static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) |
@@ -630,8 +632,7 @@ enum ssb_clkmode { | |||
630 | extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, | 632 | extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, |
631 | enum ssb_clkmode mode); | 633 | enum ssb_clkmode mode); |
632 | 634 | ||
633 | extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, | 635 | extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks); |
634 | u32 ticks); | ||
635 | 636 | ||
636 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); | 637 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); |
637 | 638 | ||