/* If the kernel parameter wdt=1, the watchdog will be enabled at boot. * Also, the wdt_period sets the watchdog timer period timeout. * For E500 cpus the wdt_period sets which bit changing from 0->1 will * trigger a watchdog timeout. This watchdog timeout will occur 3 times, the * first time nothing will happen, the second time a watchdog exception will * occur, and the final time the board will reset.
*/
staticbool booke_wdt_enabled;
module_param(booke_wdt_enabled, bool, 0); staticint booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT;
module_param(booke_wdt_period, int, 0); staticbool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
#ifdef CONFIG_PPC_E500
/* For the specified period, determine the number of seconds * corresponding to the reset time. There will be a watchdog * exception at approximately 3/5 of this time. * * The formula to calculate this is given by: * 2.5 * (2^(63-period+1)) / timebase_freq * * In order to simplify things, we assume that period is * at least 1. This will still result in a very long timeout.
*/ staticunsignedlonglong period_to_sec(unsignedint period)
{ unsignedlonglong tmp = 1ULL << (64 - period); unsignedlong tmp2 = ppc_tb_freq;
/* tmp may be a very large number and we don't want to overflow, * so divide the timebase freq instead of multiplying tmp
*/
tmp2 = tmp2 / 5 * 2;
do_div(tmp, tmp2); return tmp;
}
/* * This procedure will find the highest period which will give a timeout * greater than the one required. e.g. for a bus speed of 66666666 and * a parameter of 2 secs, then this procedure will return a value of 38.
*/ staticunsignedint sec_to_period(unsignedint secs)
{ unsignedint period; for (period = 63; period > 0; period--) { if (period_to_sec(period) >= secs) return period;
} return 0;
}
/* clear status before enabling watchdog */
__booke_wdt_ping(NULL);
val = mfspr(SPRN_TCR);
val &= ~WDTP_MASK;
val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(sec_to_period(wdog->timeout)));
mtspr(SPRN_TCR, val);
}
/** * __booke_wdt_disable - disable the watchdog on the given CPU * * This function is called on each CPU. It disables the watchdog on that CPU. * * TCR[WRC] cannot be changed once it has been set to non-zero, but we can * effectively disable the watchdog by setting its period to the maximum value.
*/ staticvoid __booke_wdt_disable(void *data)
{
u32 val;
val = mfspr(SPRN_TCR);
val &= ~(TCR_WIE | WDTP_MASK);
mtspr(SPRN_TCR, val);
/* clear status to make sure nothing is pending */
__booke_wdt_ping(NULL);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.