diff options
Diffstat (limited to 'drivers/watchdog/booke_wdt.c')
| -rw-r--r-- | drivers/watchdog/booke_wdt.c | 79 |
1 files changed, 33 insertions, 46 deletions
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index f1b8d555080e..932a03f4436a 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Watchdog timer for PowerPC Book-E systems * @@ -5,11 +6,6 @@ * Maintainer: Kumar Gala <galak@kernel.crashing.org> * * Copyright 2005, 2008, 2010-2011 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -25,15 +21,13 @@ /* 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 watchog timeout. This watchdog timeout will occur 3 times, the + * 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. */ -u32 booke_wdt_enabled; -u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT; -#ifdef CONFIG_PPC_FSL_BOOK3E +#ifdef CONFIG_PPC_E500 #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) #define WDTP_MASK (WDTP(0x3f)) #else @@ -41,7 +35,17 @@ u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT; #define WDTP_MASK (TCR_WP_MASK) #endif -#ifdef CONFIG_PPC_FSL_BOOK3E +static bool booke_wdt_enabled; +module_param(booke_wdt_enabled, bool, 0); +static int booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT; +module_param(booke_wdt_period, int, 0); +static bool 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 @@ -70,7 +74,7 @@ static unsigned long long period_to_sec(unsigned int period) /* * 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 - * and a parameter of 2 secs, then this procedure will return a value of 38. + * a parameter of 2 secs, then this procedure will return a value of 38. */ static unsigned int sec_to_period(unsigned int secs) { @@ -84,7 +88,7 @@ static unsigned int sec_to_period(unsigned int secs) #define MAX_WDT_TIMEOUT period_to_sec(1) -#else /* CONFIG_PPC_FSL_BOOK3E */ +#else /* CONFIG_PPC_E500 */ static unsigned long long period_to_sec(unsigned int period) { @@ -98,22 +102,23 @@ static unsigned int sec_to_period(unsigned int secs) #define MAX_WDT_TIMEOUT 3 /* from Kconfig */ -#endif /* !CONFIG_PPC_FSL_BOOK3E */ +#endif /* !CONFIG_PPC_E500 */ static void __booke_wdt_set(void *data) { u32 val; + struct watchdog_device *wdog = data; val = mfspr(SPRN_TCR); val &= ~WDTP_MASK; - val |= WDTP(booke_wdt_period); + val |= WDTP(sec_to_period(wdog->timeout)); 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) @@ -131,26 +136,19 @@ static int booke_wdt_ping(struct watchdog_device *wdog) static void __booke_wdt_enable(void *data) { u32 val; + struct watchdog_device *wdog = data; /* clear status before enabling watchdog */ __booke_wdt_ping(NULL); val = mfspr(SPRN_TCR); val &= ~WDTP_MASK; - val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); - -#ifdef CONFIG_PPC_BOOK3E_64 - /* - * Crit ints are currently broken on PPC64 Book-E, so - * just disable them for now. - */ - val &= ~TCR_WIE; -#endif + 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 + * __booke_wdt_disable - disable the watchdog on the given CPU * * This function is called on each CPU. It disables the watchdog on that CPU. * @@ -170,25 +168,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); -} -static int booke_wdt_start(struct watchdog_device *wdog) -{ - if (booke_wdt_enabled == 0) { - booke_wdt_enabled = 1; - __booke_wdt_start(wdog); - } return 0; } static int booke_wdt_stop(struct watchdog_device *wdog) { on_each_cpu(__booke_wdt_disable, NULL, 0); - booke_wdt_enabled = 0; pr_debug("watchdog disabled\n"); return 0; @@ -197,21 +187,18 @@ static int booke_wdt_stop(struct watchdog_device *wdog) static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev, unsigned int timeout) { - if (timeout > MAX_WDT_TIMEOUT) - return -EINVAL; - booke_wdt_period = sec_to_period(timeout); wdt_dev->timeout = timeout; - booke_wdt_set(); + booke_wdt_set(wdt_dev); return 0; } -static struct watchdog_info booke_wdt_info = { +static struct watchdog_info booke_wdt_info __ro_after_init = { .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = "PowerPC Book-E Watchdog", }; -static struct watchdog_ops booke_wdt_ops = { +static const struct watchdog_ops booke_wdt_ops = { .owner = THIS_MODULE, .start = booke_wdt_start, .stop = booke_wdt_stop, @@ -223,7 +210,6 @@ static struct watchdog_device booke_wdt_dev = { .info = &booke_wdt_info, .ops = &booke_wdt_ops, .min_timeout = 1, - .max_timeout = 0xFFFF }; static void __exit booke_wdt_exit(void) @@ -234,15 +220,15 @@ static void __exit booke_wdt_exit(void) static int __init booke_wdt_init(void) { int ret = 0; - bool nowayout = WATCHDOG_NOWAYOUT; pr_info("powerpc book-e watchdog driver loaded\n"); booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value; 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); + booke_wdt_dev.max_timeout = MAX_WDT_TIMEOUT; if (booke_wdt_enabled) - __booke_wdt_start(&booke_wdt_dev); + booke_wdt_start(&booke_wdt_dev); ret = watchdog_register_device(&booke_wdt_dev); @@ -252,5 +238,6 @@ static int __init booke_wdt_init(void) module_init(booke_wdt_init); module_exit(booke_wdt_exit); +MODULE_ALIAS("booke_wdt"); MODULE_DESCRIPTION("PowerPC Book-E watchdog driver"); MODULE_LICENSE("GPL"); |
