diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-25 10:19:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-25 10:19:17 -0700 |
commit | 1f93d2abf488c6a41bdd5e6caf80b559493eea8d (patch) | |
tree | 6c81f37167ee42fed575d48e2fcc6dc92ec1d79f /drivers/watchdog | |
parent | 48dd7cefa010b704eb2532a2883798fd6d703a0e (diff) | |
parent | 540be8b2add1a18a4289b11c1a9b6956eb846630 (diff) |
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck:
- add support for Fintek F81865 Super-IO chip
- add support for watchdogs (RWDT and SWDT) found on RCar Gen3 based
SoCs from Renesas
- octeon: Handle the FROZEN hot plug notifier actions
- f71808e_wdt fixes and cleanups
- some small improvements in code and documentation
* git://www.linux-watchdog.org/linux-watchdog:
MAINTAINERS: Add file patterns for watchdog device tree bindings
Documentation: Add ebc-c384_wdt watchdog-parameters.txt entry
watchdog: shwdt: Use setup_timer()
watchdog: cpwd: Use setup_timer()
arm64: defconfig: enable Renesas Watchdog Timer
watchdog: renesas-wdt: add driver
watchdog: remove error message when unable to allocate watchdog device
watchdog: f71808e_wdt: Fix WDTMOUT_STS register read
watchdog: f71808e_wdt: Fix typo
watchdog: f71808e_wdt: Add F81865 support
watchdog: sp5100_tco: properly check for new register layouts
watchdog: core: Fix circular locking dependency
watchdog: core: fix trivial typo in a comment
watchdog: hpwdt: Adjust documentation to match latest kernel module parameters.
watchdog: imx2_wdt: add external reset support via dt prop
watchdog: octeon: Handle the FROZEN hot plug notifier actions.
watchdog: qcom: Report reboot reason
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 8 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 1 | ||||
-rw-r--r-- | drivers/watchdog/cpwd.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/f71808e_wdt.c | 30 | ||||
-rw-r--r-- | drivers/watchdog/imx2_wdt.c | 19 | ||||
-rw-r--r-- | drivers/watchdog/jz4740_wdt.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/octeon-wdt-main.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/qcom-wdt.c | 7 | ||||
-rw-r--r-- | drivers/watchdog/renesas_wdt.c | 213 | ||||
-rw-r--r-- | drivers/watchdog/shwdt.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/sp5100_tco.c | 15 | ||||
-rw-r--r-- | drivers/watchdog/watchdog_core.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/watchdog_dev.c | 1 |
13 files changed, 284 insertions, 26 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 5b45e277697b..b54f26c55dfd 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -661,6 +661,14 @@ config ATLAS7_WATCHDOG To compile this driver as a module, choose M here: the module will be called atlas7_wdt. +config RENESAS_WDT + tristate "Renesas WDT Watchdog" + depends on ARCH_RENESAS || COMPILE_TEST + select WATCHDOG_CORE + help + This driver adds watchdog support for the integrated watchdogs in the + Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT). + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 9bde095ff691..a46e7c1380ac 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o +obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 02007689e9ca..71ee07950e63 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -611,9 +611,7 @@ static int cpwd_probe(struct platform_device *op) } if (p->broken) { - init_timer(&cpwd_timer); - cpwd_timer.function = cpwd_brokentimer; - cpwd_timer.data = (unsigned long) p; + setup_timer(&cpwd_timer, cpwd_brokentimer, (unsigned long)p); cpwd_timer.expires = WD_BTIMEOUT; pr_info("PLD defect workaround enabled for model %s\n", diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 016bd9355190..d4ba262da7ba 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -38,7 +38,7 @@ #define SIO_F71808FG_LD_WDT 0x07 /* Watchdog timer logical device */ #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ -#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ +#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ #define SIO_REG_LDSEL 0x07 /* Logical device select */ #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ @@ -59,6 +59,7 @@ #define SIO_F71869A_ID 0x1007 /* Chipset ID */ #define SIO_F71882_ID 0x0541 /* Chipset ID */ #define SIO_F71889_ID 0x0723 /* Chipset ID */ +#define SIO_F81865_ID 0x0704 /* Chipset ID */ #define F71808FG_REG_WDO_CONF 0xf0 #define F71808FG_REG_WDT_CONF 0xf5 @@ -66,11 +67,14 @@ #define F71808FG_FLAG_WDOUT_EN 7 -#define F71808FG_FLAG_WDTMOUT_STS 5 +#define F71808FG_FLAG_WDTMOUT_STS 6 #define F71808FG_FLAG_WD_EN 5 #define F71808FG_FLAG_WD_PULSE 4 #define F71808FG_FLAG_WD_UNIT 3 +#define F81865_REG_WDO_CONF 0xfa +#define F81865_FLAG_WDOUT_EN 0 + /* Default values */ #define WATCHDOG_TIMEOUT 60 /* 1 minute default timeout */ #define WATCHDOG_MAX_TIMEOUT (60 * 255) @@ -112,7 +116,7 @@ module_param(start_withtimeout, uint, 0); MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with" " given initial timeout. Zero (default) disables this feature."); -enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg }; +enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg, f81865 }; static const char *f71808e_names[] = { "f71808fg", @@ -121,6 +125,7 @@ static const char *f71808e_names[] = { "f71869", "f71882fg", "f71889fg", + "f81865", }; /* Super-I/O Function prototypes */ @@ -360,6 +365,11 @@ static int watchdog_start(void) superio_inb(watchdog.sioaddr, SIO_REG_MFUNCT3) & 0xcf); break; + case f81865: + /* Set pin 70 to WDTRST# */ + superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 5); + break; + default: /* * 'default' label to shut up the compiler and catch @@ -371,8 +381,13 @@ static int watchdog_start(void) superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0); - superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF, - F71808FG_FLAG_WDOUT_EN); + + if (watchdog.type == f81865) + superio_set_bit(watchdog.sioaddr, F81865_REG_WDO_CONF, + F81865_FLAG_WDOUT_EN); + else + superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF, + F71808FG_FLAG_WDOUT_EN); superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, F71808FG_FLAG_WD_EN); @@ -655,7 +670,7 @@ static int __init watchdog_init(int sioaddr) superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF); - watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS; + watchdog.caused_reboot = wdt_conf & BIT(F71808FG_FLAG_WDTMOUT_STS); superio_exit(sioaddr); @@ -770,6 +785,9 @@ static int __init f71808e_find(int sioaddr) /* Confirmed (by datasheet) not to have a watchdog. */ err = -ENODEV; goto exit; + case SIO_F81865_ID: + watchdog.type = f81865; + break; default: pr_info("Unrecognized Fintek device: %04x\n", (unsigned int)devid); diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 331aed831dac..62f346bb4348 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -37,6 +37,8 @@ #define IMX2_WDT_WCR 0x00 /* Control Register */ #define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ +#define IMX2_WDT_WCR_WDA (1 << 5) /* -> External Reset WDOG_B */ +#define IMX2_WDT_WCR_SRS (1 << 4) /* -> Software Reset Signal */ #define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ #define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ #define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */ @@ -59,6 +61,7 @@ struct imx2_wdt_device { struct clk *clk; struct regmap *regmap; struct watchdog_device wdog; + bool ext_reset; }; static bool nowayout = WATCHDOG_NOWAYOUT; @@ -83,6 +86,12 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action, struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); unsigned int wcr_enable = IMX2_WDT_WCR_WDE; + /* Use internal reset or external - not both */ + if (wdev->ext_reset) + wcr_enable |= IMX2_WDT_WCR_SRS; /* do not assert int reset */ + else + wcr_enable |= IMX2_WDT_WCR_WDA; /* do not assert ext-reset */ + /* Assert SRS signal */ regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable); /* @@ -112,8 +121,12 @@ static inline void imx2_wdt_setup(struct watchdog_device *wdog) val |= IMX2_WDT_WCR_WDZST; /* Strip the old watchdog Time-Out value */ val &= ~IMX2_WDT_WCR_WT; - /* Generate reset if WDOG times out */ - val &= ~IMX2_WDT_WCR_WRE; + /* Generate internal chip-level reset if WDOG times out */ + if (!wdev->ext_reset) + val &= ~IMX2_WDT_WCR_WRE; + /* Or if external-reset assert WDOG_B reset only on time-out */ + else + val |= IMX2_WDT_WCR_WRE; /* Keep Watchdog Disabled */ val &= ~IMX2_WDT_WCR_WDE; /* Set the watchdog's Time-Out value */ @@ -230,6 +243,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val); wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0; + wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, + "fsl,ext-reset-output"); wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); if (wdog->timeout != timeout) dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n", diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 6a7d5c365438..c8d51ddb26d5 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c @@ -160,10 +160,8 @@ static int jz4740_wdt_probe(struct platform_device *pdev) drvdata = devm_kzalloc(&pdev->dev, sizeof(struct jz4740_wdt_drvdata), GFP_KERNEL); - if (!drvdata) { - dev_err(&pdev->dev, "Unable to alloacate watchdog device\n"); + if (!drvdata) return -ENOMEM; - } if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 14521c8b3d5a..b55981f88a08 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -431,7 +431,7 @@ static int octeon_wdt_cpu_callback(struct notifier_block *nfb, { unsigned int cpu = (unsigned long)hcpu; - switch (action) { + switch (action & ~CPU_TASKS_FROZEN) { case CPU_DOWN_PREPARE: octeon_wdt_disable_interrupt(cpu); break; diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index 20563ccb7be0..a043fa4f60e5 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -21,6 +21,7 @@ #define WDT_RST 0x38 #define WDT_EN 0x40 +#define WDT_STS 0x44 #define WDT_BITE_TIME 0x5C struct qcom_wdt { @@ -108,7 +109,8 @@ static const struct watchdog_ops qcom_wdt_ops = { static const struct watchdog_info qcom_wdt_info = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE - | WDIOF_SETTIMEOUT, + | WDIOF_SETTIMEOUT + | WDIOF_CARDRESET, .identity = KBUILD_MODNAME, }; @@ -171,6 +173,9 @@ static int qcom_wdt_probe(struct platform_device *pdev) wdt->wdd.max_timeout = 0x10000000U / wdt->rate; wdt->wdd.parent = &pdev->dev; + if (readl(wdt->base + WDT_STS) & 1) + wdt->wdd.bootstatus = WDIOF_CARDRESET; + /* * If 'timeout-sec' unspecified in devicetree, assume a 30 second * default, unless the max timeout is less than 30 seconds, then use diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c new file mode 100644 index 000000000000..cf61c92f7ecd --- /dev/null +++ b/drivers/watchdog/renesas_wdt.c @@ -0,0 +1,213 @@ +/* + * Watchdog driver for Renesas WDT watchdog + * + * Copyright (C) 2015-16 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> + * Copyright (C) 2015-16 Renesas Electronics Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/watchdog.h> + +#define RWTCNT 0 +#define RWTCSRA 4 +#define RWTCSRA_WOVF BIT(4) +#define RWTCSRA_WRFLG BIT(5) +#define RWTCSRA_TME BIT(7) + +#define RWDT_DEFAULT_TIMEOUT 60U + +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024 }; + +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) ")"); + +struct rwdt_priv { + void __iomem *base; + struct watchdog_device wdev; + struct clk *clk; + unsigned int clks_per_sec; + u8 cks; +}; + +static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) +{ + if (reg == RWTCNT) + val |= 0x5a5a0000; + else + val |= 0xa5a5a500; + + writel_relaxed(val, priv->base + reg); +} + +static int rwdt_init_timeout(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, 65536 - wdev->timeout * priv->clks_per_sec, RWTCNT); + + return 0; +} + +static int rwdt_start(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + clk_prepare_enable(priv->clk); + + rwdt_write(priv, priv->cks, RWTCSRA); + rwdt_init_timeout(wdev); + + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) + cpu_relax(); + + rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); + + return 0; +} + +static int rwdt_stop(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, priv->cks, RWTCSRA); + clk_disable_unprepare(priv->clk); + + return 0; +} + +static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + u16 val = readw_relaxed(priv->base + RWTCNT); + + return DIV_ROUND_CLOSEST(65536 - val, priv->clks_per_sec); +} + +static const struct watchdog_info rwdt_ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .identity = "Renesas WDT Watchdog", +}; + +static const struct watchdog_ops rwdt_ops = { + .owner = THIS_MODULE, + .start = rwdt_start, + .stop = rwdt_stop, + .ping = rwdt_init_timeout, + .get_timeleft = rwdt_get_timeleft, +}; + +static int rwdt_probe(struct platform_device *pdev) +{ + struct rwdt_priv *priv; + struct resource *res; + unsigned long rate; + unsigned int clks_per_sec; + int ret, i; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + rate = clk_get_rate(priv->clk); + if (!rate) + return -ENOENT; + + for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { + clks_per_sec = DIV_ROUND_UP(rate, clk_divs[i]); + if (clks_per_sec) { + priv->clks_per_sec = clks_per_sec; + priv->cks = i; + break; + } + } + + if (!clks_per_sec) { + dev_err(&pdev->dev, "Can't find suitable clock divider\n"); + return -ERANGE; + } + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + priv->wdev.info = &rwdt_ident, + priv->wdev.ops = &rwdt_ops, + priv->wdev.parent = &pdev->dev; + priv->wdev.min_timeout = 1; + priv->wdev.max_timeout = 65536 / clks_per_sec; + priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); + + platform_set_drvdata(pdev, priv); + watchdog_set_drvdata(&priv->wdev, priv); + watchdog_set_nowayout(&priv->wdev, nowayout); + + /* This overrides the default timeout only if DT configuration was found */ + ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); + if (ret) + dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); + + ret = watchdog_register_device(&priv->wdev); + if (ret < 0) { + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return ret; + } + + return 0; +} + +static int rwdt_remove(struct platform_device *pdev) +{ + struct rwdt_priv *priv = platform_get_drvdata(pdev); + + watchdog_unregister_device(&priv->wdev); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +/* + * This driver does also fit for R-Car Gen2 (r8a779[0-4]) WDT. However, for SMP + * to work there, one also needs a RESET (RST) driver which does not exist yet + * due to HW issues. This needs to be solved before adding compatibles here. + */ +static const struct of_device_id rwdt_ids[] = { + { .compatible = "renesas,rcar-gen3-wdt", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rwdt_ids); + +static struct platform_driver rwdt_driver = { + .driver = { + .name = "renesas_wdt", + .of_match_table = rwdt_ids, + }, + .probe = rwdt_probe, + .remove = rwdt_remove, +}; +module_platform_driver(rwdt_driver); + +MODULE_DESCRIPTION("Renesas WDT Watchdog Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index f90812170657..517a733175ef 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -275,9 +275,7 @@ static int sh_wdt_probe(struct platform_device *pdev) return rc; } - init_timer(&wdt->timer); - wdt->timer.function = sh_wdt_ping; - wdt->timer.data = (unsigned long)wdt; + setup_timer(&wdt->timer, sh_wdt_ping, (unsigned long)wdt); wdt->timer.expires = next_ping_period(clock_division_ratio); dev_info(&pdev->dev, "initialized.\n"); diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index 6467b91f2245..028618c5eeba 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c @@ -73,6 +73,13 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." /* * Some TCO specific functions */ + +static bool tco_has_sp5100_reg_layout(struct pci_dev *dev) +{ + return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && + dev->revision < 0x40; +} + static void tco_timer_start(void) { u32 val; @@ -129,7 +136,7 @@ static void tco_timer_enable(void) { int val; - if (sp5100_tco_pci->revision >= 0x40) { + if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) { /* For SB800 or later */ /* Set the Watchdog timer resolution to 1 sec */ outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG); @@ -342,8 +349,7 @@ static unsigned char sp5100_tco_setupdevice(void) /* * Determine type of southbridge chipset. */ - if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && - sp5100_tco_pci->revision < 0x40) { + if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { dev_name = SP5100_DEVNAME; index_reg = SP5100_IO_PM_INDEX_REG; data_reg = SP5100_IO_PM_DATA_REG; @@ -388,8 +394,7 @@ static unsigned char sp5100_tco_setupdevice(void) * Secondly, Find the watchdog timer MMIO address * from SBResource_MMIO register. */ - if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && - sp5100_tco_pci->revision < 0x40) { + if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */ pci_read_config_dword(sp5100_tco_pci, SP5100_SB_RESOURCE_MMIO_BASE, &val); diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 981a668b17e3..7c3ba58ae1be 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -104,7 +104,7 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) * timeout module parameter (if it is valid value) or the timeout-sec property * (only if it is a valid value and the timeout_parm is out of bounds). * If none of them are valid then we keep the old value (which should normally - * be the default timeout value. + * be the default timeout value). * * A zero is returned on success and -EINVAL for failure. */ diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index e2c5abbb45ff..3595cffa24ea 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -736,7 +736,6 @@ static int watchdog_release(struct inode *inode, struct file *file) watchdog_ping(wdd); } - cancel_delayed_work_sync(&wd_data->work); watchdog_update_worker(wdd); /* make sure that /dev/watchdog can be re-opened */ |