|
@@ -41,6 +41,28 @@ u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT;
|
|
#define WDTP_MASK (TCR_WP_MASK)
|
|
#define WDTP_MASK (TCR_WP_MASK)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+/* Checks wdt=x and wdt_period=xx command-line option */
|
|
|
|
+notrace int __init early_parse_wdt(char *p)
|
|
|
|
+{
|
|
|
|
+ if (p && strncmp(p, "0", 1) != 0)
|
|
|
|
+ booke_wdt_enabled = 1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+early_param("wdt", early_parse_wdt);
|
|
|
|
+
|
|
|
|
+int __init early_parse_wdt_period(char *p)
|
|
|
|
+{
|
|
|
|
+ unsigned long ret;
|
|
|
|
+ if (p) {
|
|
|
|
+ if (!kstrtol(p, 0, &ret))
|
|
|
|
+ booke_wdt_period = ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+early_param("wdt_period", early_parse_wdt_period);
|
|
|
|
+
|
|
#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
|
|
|
|
/* For the specified period, determine the number of seconds
|
|
/* For the specified period, determine the number of seconds
|
|
@@ -103,17 +125,18 @@ static unsigned int sec_to_period(unsigned int secs)
|
|
static void __booke_wdt_set(void *data)
|
|
static void __booke_wdt_set(void *data)
|
|
{
|
|
{
|
|
u32 val;
|
|
u32 val;
|
|
|
|
+ struct watchdog_device *wdog = data;
|
|
|
|
|
|
val = mfspr(SPRN_TCR);
|
|
val = mfspr(SPRN_TCR);
|
|
val &= ~WDTP_MASK;
|
|
val &= ~WDTP_MASK;
|
|
- val |= WDTP(booke_wdt_period);
|
|
|
|
|
|
+ val |= WDTP(sec_to_period(wdog->timeout));
|
|
|
|
|
|
mtspr(SPRN_TCR, val);
|
|
mtspr(SPRN_TCR, val);
|
|
}
|
|
}
|
|
|
|
|
|
-static void booke_wdt_set(void)
|
|
|
|
|
|
+static void booke_wdt_set(void *data)
|
|
{
|
|
{
|
|
- on_each_cpu(__booke_wdt_set, NULL, 0);
|
|
|
|
|
|
+ on_each_cpu(__booke_wdt_set, data, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static void __booke_wdt_ping(void *data)
|
|
static void __booke_wdt_ping(void *data)
|
|
@@ -131,12 +154,13 @@ static int booke_wdt_ping(struct watchdog_device *wdog)
|
|
static void __booke_wdt_enable(void *data)
|
|
static void __booke_wdt_enable(void *data)
|
|
{
|
|
{
|
|
u32 val;
|
|
u32 val;
|
|
|
|
+ struct watchdog_device *wdog = data;
|
|
|
|
|
|
/* clear status before enabling watchdog */
|
|
/* clear status before enabling watchdog */
|
|
__booke_wdt_ping(NULL);
|
|
__booke_wdt_ping(NULL);
|
|
val = mfspr(SPRN_TCR);
|
|
val = mfspr(SPRN_TCR);
|
|
val &= ~WDTP_MASK;
|
|
val &= ~WDTP_MASK;
|
|
- val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
|
|
|
|
|
|
+ val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(sec_to_period(wdog->timeout)));
|
|
|
|
|
|
mtspr(SPRN_TCR, val);
|
|
mtspr(SPRN_TCR, val);
|
|
}
|
|
}
|
|
@@ -162,25 +186,17 @@ static void __booke_wdt_disable(void *data)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-static void __booke_wdt_start(struct watchdog_device *wdog)
|
|
|
|
|
|
+static int booke_wdt_start(struct watchdog_device *wdog)
|
|
{
|
|
{
|
|
- on_each_cpu(__booke_wdt_enable, NULL, 0);
|
|
|
|
|
|
+ on_each_cpu(__booke_wdt_enable, wdog, 0);
|
|
pr_debug("watchdog enabled (timeout = %u sec)\n", wdog->timeout);
|
|
pr_debug("watchdog enabled (timeout = %u sec)\n", wdog->timeout);
|
|
-}
|
|
|
|
|
|
|
|
-static int booke_wdt_start(struct watchdog_device *wdog)
|
|
|
|
-{
|
|
|
|
- if (booke_wdt_enabled == 0) {
|
|
|
|
- booke_wdt_enabled = 1;
|
|
|
|
- __booke_wdt_start(wdog);
|
|
|
|
- }
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static int booke_wdt_stop(struct watchdog_device *wdog)
|
|
static int booke_wdt_stop(struct watchdog_device *wdog)
|
|
{
|
|
{
|
|
on_each_cpu(__booke_wdt_disable, NULL, 0);
|
|
on_each_cpu(__booke_wdt_disable, NULL, 0);
|
|
- booke_wdt_enabled = 0;
|
|
|
|
pr_debug("watchdog disabled\n");
|
|
pr_debug("watchdog disabled\n");
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -191,9 +207,8 @@ static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev,
|
|
{
|
|
{
|
|
if (timeout > MAX_WDT_TIMEOUT)
|
|
if (timeout > MAX_WDT_TIMEOUT)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- booke_wdt_period = sec_to_period(timeout);
|
|
|
|
wdt_dev->timeout = timeout;
|
|
wdt_dev->timeout = timeout;
|
|
- booke_wdt_set();
|
|
|
|
|
|
+ booke_wdt_set(wdt_dev);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -231,10 +246,10 @@ static int __init booke_wdt_init(void)
|
|
pr_info("powerpc book-e watchdog driver loaded\n");
|
|
pr_info("powerpc book-e watchdog driver loaded\n");
|
|
booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value;
|
|
booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value;
|
|
booke_wdt_set_timeout(&booke_wdt_dev,
|
|
booke_wdt_set_timeout(&booke_wdt_dev,
|
|
- period_to_sec(CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT));
|
|
|
|
|
|
+ period_to_sec(booke_wdt_period));
|
|
watchdog_set_nowayout(&booke_wdt_dev, nowayout);
|
|
watchdog_set_nowayout(&booke_wdt_dev, nowayout);
|
|
if (booke_wdt_enabled)
|
|
if (booke_wdt_enabled)
|
|
- __booke_wdt_start(&booke_wdt_dev);
|
|
|
|
|
|
+ booke_wdt_start(&booke_wdt_dev);
|
|
|
|
|
|
ret = watchdog_register_device(&booke_wdt_dev);
|
|
ret = watchdog_register_device(&booke_wdt_dev);
|
|
|
|
|