From afc3c7596af4c3e52d3783732babdfb7b60009b7 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 24 Nov 2012 20:07:25 +0000 Subject: brcm47xx: update watchdog driver This watchdog driver should work with SoC having a PMU. This fixes #11720. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34323 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../551-ssb-add-methods-for-watchdog-driver.patch | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 target/linux/brcm47xx/patches-3.6/551-ssb-add-methods-for-watchdog-driver.patch (limited to 'target/linux/brcm47xx/patches-3.6/551-ssb-add-methods-for-watchdog-driver.patch') diff --git a/target/linux/brcm47xx/patches-3.6/551-ssb-add-methods-for-watchdog-driver.patch b/target/linux/brcm47xx/patches-3.6/551-ssb-add-methods-for-watchdog-driver.patch new file mode 100644 index 0000000000..46911d1306 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.6/551-ssb-add-methods-for-watchdog-driver.patch @@ -0,0 +1,131 @@ +--- a/drivers/ssb/driver_chipcommon.c ++++ b/drivers/ssb/driver_chipcommon.c +@@ -4,6 +4,7 @@ + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch ++ * Copyright 2012, Hauke Mehrtens + * + * Licensed under the GNU/GPL. See COPYING for details. + */ +@@ -12,6 +13,7 @@ + #include + #include + #include ++#include + + #include "ssb_private.h" + +@@ -306,6 +308,43 @@ static u32 ssb_chipco_watchdog_get_max_t + return (1 << nb) - 1; + } + ++u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks) ++{ ++ struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt); ++ ++ if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB) ++ return 0; ++ ++ return ssb_chipco_watchdog_timer_set(cc, ticks); ++} ++ ++u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms) ++{ ++ struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt); ++ u32 ticks; ++ ++ if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB) ++ return 0; ++ ++ ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms); ++ return ticks / cc->ticks_per_ms; ++} ++ ++static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc) ++{ ++ struct ssb_bus *bus = cc->dev->bus; ++ ++ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { ++ /* based on 32KHz ILP clock */ ++ return 32; ++ } else { ++ if (cc->dev->id.revision < 18) ++ return ssb_clockspeed(bus) / 1000; ++ else ++ return ssb_chipco_alp_clock(cc) / 1000; ++ } ++} ++ + void ssb_chipcommon_init(struct ssb_chipcommon *cc) + { + if (!cc->dev) +@@ -323,6 +362,11 @@ void ssb_chipcommon_init(struct ssb_chip + chipco_powercontrol_init(cc); + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); + calc_fast_powerup_delay(cc); ++ ++ if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) { ++ cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc); ++ cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; ++ } + } + + void ssb_chipco_suspend(struct ssb_chipcommon *cc) +@@ -421,7 +465,7 @@ 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) ++u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) + { + u32 maxt; + enum ssb_clkmode clkmode; +@@ -441,6 +485,7 @@ void ssb_chipco_watchdog_timer_set(struc + /* instant NMI */ + chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); + } ++ return ticks; + } + + void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) +--- a/drivers/ssb/ssb_private.h ++++ b/drivers/ssb/ssb_private.h +@@ -3,6 +3,7 @@ + + #include + #include ++#include + + + #define PFX "ssb: " +@@ -226,4 +227,8 @@ static inline int ssb_sflash_init(struct + + extern struct platform_device ssb_pflash_dev; + ++extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, ++ u32 ticks); ++extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms); ++ + #endif /* LINUX_SSB_PRIVATE_H_ */ +--- a/include/linux/ssb/ssb_driver_chipcommon.h ++++ b/include/linux/ssb/ssb_driver_chipcommon.h +@@ -607,6 +607,8 @@ struct ssb_chipcommon { + #ifdef CONFIG_SSB_SFLASH + struct bcm47xx_sflash sflash; + #endif ++ u32 ticks_per_ms; ++ u32 max_timer_ms; + }; + + static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) +@@ -646,8 +648,7 @@ enum ssb_clkmode { + extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, + enum ssb_clkmode mode); + +-extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, +- u32 ticks); ++extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks); + + void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); + -- cgit v1.2.3