Commit a913d94e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-watchdog-6.10-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

 - Add Lenovo SE10 platform Watchdog Driver

 - Other small fixes and improvements

* tag 'linux-watchdog-6.10-rc1' of git://www.linux-watchdog.org/linux-watchdog:
  watchdog: LENOVO_SE10_WDT should depend on X86 && DMI
  watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe()
  watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin
  watchdog: add HAS_IOPORT dependencies
  watchdog/wdt-main: Use cpumask_of() to avoid cpumask var on stack
  watchdog: bd9576: Drop "always-running" property
  watchdog: mtx-1: drop driver owner assignment
  watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
  watchdog: lenovo_se10_wdt: Watchdog driver for Lenovo SE10 platform
parents 0a07e090 c45b8cfc
...@@ -254,6 +254,17 @@ config GPIO_WATCHDOG_ARCH_INITCALL ...@@ -254,6 +254,17 @@ config GPIO_WATCHDOG_ARCH_INITCALL
arch_initcall. arch_initcall.
If in doubt, say N. If in doubt, say N.
config LENOVO_SE10_WDT
tristate "Lenovo SE10 Watchdog"
depends on (X86 && DMI) || COMPILE_TEST
select WATCHDOG_CORE
help
If you say yes here you get support for the watchdog
functionality for the Lenovo SE10 platform.
This driver can also be built as a module. If so, the module
will be called lenovo-se10-wdt.
config MENF21BMC_WATCHDOG config MENF21BMC_WATCHDOG
tristate "MEN 14F021P00 BMC Watchdog" tristate "MEN 14F021P00 BMC Watchdog"
depends on MFD_MENF21BMC || COMPILE_TEST depends on MFD_MENF21BMC || COMPILE_TEST
...@@ -482,6 +493,7 @@ config 21285_WATCHDOG ...@@ -482,6 +493,7 @@ config 21285_WATCHDOG
config 977_WATCHDOG config 977_WATCHDOG
tristate "NetWinder WB83C977 watchdog" tristate "NetWinder WB83C977 watchdog"
depends on (FOOTBRIDGE && ARCH_NETWINDER) || (ARM && COMPILE_TEST) depends on (FOOTBRIDGE && ARCH_NETWINDER) || (ARM && COMPILE_TEST)
depends on HAS_IOPORT
help help
Say Y here to include support for the WB977 watchdog included in Say Y here to include support for the WB977 watchdog included in
NetWinder machines. Alternatively say M to compile the driver as NetWinder machines. Alternatively say M to compile the driver as
...@@ -1075,7 +1087,7 @@ config ACQUIRE_WDT ...@@ -1075,7 +1087,7 @@ config ACQUIRE_WDT
config ADVANTECH_WDT config ADVANTECH_WDT
tristate "Advantech SBC Watchdog Timer" tristate "Advantech SBC Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
If you are configuring a Linux kernel for the Advantech single-board If you are configuring a Linux kernel for the Advantech single-board
computer, say `Y' here to support its built-in watchdog timer computer, say `Y' here to support its built-in watchdog timer
...@@ -1084,7 +1096,7 @@ config ADVANTECH_WDT ...@@ -1084,7 +1096,7 @@ config ADVANTECH_WDT
config ADVANTECH_EC_WDT config ADVANTECH_EC_WDT
tristate "Advantech Embedded Controller Watchdog Timer" tristate "Advantech Embedded Controller Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select ISA_BUS_API select ISA_BUS_API
select WATCHDOG_CORE select WATCHDOG_CORE
help help
...@@ -1117,7 +1129,7 @@ config ALIM7101_WDT ...@@ -1117,7 +1129,7 @@ config ALIM7101_WDT
config EBC_C384_WDT config EBC_C384_WDT
tristate "WinSystems EBC-C384 Watchdog Timer" tristate "WinSystems EBC-C384 Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select ISA_BUS_API select ISA_BUS_API
select WATCHDOG_CORE select WATCHDOG_CORE
help help
...@@ -1127,7 +1139,7 @@ config EBC_C384_WDT ...@@ -1127,7 +1139,7 @@ config EBC_C384_WDT
config EXAR_WDT config EXAR_WDT
tristate "Exar Watchdog Timer" tristate "Exar Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
help help
Enables watchdog timer support for the watchdog timer present Enables watchdog timer support for the watchdog timer present
...@@ -1138,7 +1150,7 @@ config EXAR_WDT ...@@ -1138,7 +1150,7 @@ config EXAR_WDT
config F71808E_WDT config F71808E_WDT
tristate "Fintek F718xx, F818xx Super I/O Watchdog" tristate "Fintek F718xx, F818xx Super I/O Watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
help help
This is the driver for the hardware watchdog on the Fintek F71808E, This is the driver for the hardware watchdog on the Fintek F71808E,
...@@ -1150,7 +1162,7 @@ config F71808E_WDT ...@@ -1150,7 +1162,7 @@ config F71808E_WDT
config SP5100_TCO config SP5100_TCO
tristate "AMD/ATI SP5100 TCO Timer/Watchdog" tristate "AMD/ATI SP5100 TCO Timer/Watchdog"
depends on (X86 || COMPILE_TEST) && PCI depends on (X86 || COMPILE_TEST) && PCI && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
help help
Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO
...@@ -1189,7 +1201,7 @@ config SC520_WDT ...@@ -1189,7 +1201,7 @@ config SC520_WDT
config SBC_FITPC2_WATCHDOG config SBC_FITPC2_WATCHDOG
tristate "Compulab SBC-FITPC2 watchdog" tristate "Compulab SBC-FITPC2 watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the built-in watchdog timer on the fit-PC2, This is the driver for the built-in watchdog timer on the fit-PC2,
fit-PC2i, CM-iAM single-board computers made by Compulab. fit-PC2i, CM-iAM single-board computers made by Compulab.
...@@ -1214,7 +1226,7 @@ config SBC_FITPC2_WATCHDOG ...@@ -1214,7 +1226,7 @@ config SBC_FITPC2_WATCHDOG
config EUROTECH_WDT config EUROTECH_WDT
tristate "Eurotech CPU-1220/1410 Watchdog Timer" tristate "Eurotech CPU-1220/1410 Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
Enable support for the watchdog timer on the Eurotech CPU-1220 and Enable support for the watchdog timer on the Eurotech CPU-1220 and
CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product
...@@ -1222,7 +1234,7 @@ config EUROTECH_WDT ...@@ -1222,7 +1234,7 @@ config EUROTECH_WDT
config IB700_WDT config IB700_WDT
tristate "IB700 SBC Watchdog Timer" tristate "IB700 SBC Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog on the IB700 Single This is the driver for the hardware watchdog on the IB700 Single
Board Computer produced by TMC Technology (www.tmc-uk.com). This Board Computer produced by TMC Technology (www.tmc-uk.com). This
...@@ -1239,7 +1251,7 @@ config IB700_WDT ...@@ -1239,7 +1251,7 @@ config IB700_WDT
config IBMASR config IBMASR
tristate "IBM Automatic Server Restart" tristate "IBM Automatic Server Restart"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the IBM Automatic Server Restart watchdog This is the driver for the IBM Automatic Server Restart watchdog
timer built-in into some eServer xSeries machines. timer built-in into some eServer xSeries machines.
...@@ -1249,7 +1261,7 @@ config IBMASR ...@@ -1249,7 +1261,7 @@ config IBMASR
config WAFER_WDT config WAFER_WDT
tristate "ICP Single Board Computer Watchdog Timer" tristate "ICP Single Board Computer Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is a driver for the hardware watchdog on the ICP Single This is a driver for the hardware watchdog on the ICP Single
Board Computer. This driver is working on (at least) the following Board Computer. This driver is working on (at least) the following
...@@ -1271,7 +1283,7 @@ config I6300ESB_WDT ...@@ -1271,7 +1283,7 @@ config I6300ESB_WDT
config IE6XX_WDT config IE6XX_WDT
tristate "Intel Atom E6xx Watchdog" tristate "Intel Atom E6xx Watchdog"
depends on (X86 || COMPILE_TEST) && PCI depends on (X86 || COMPILE_TEST) && PCI && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
select MFD_CORE select MFD_CORE
select LPC_SCH select LPC_SCH
...@@ -1301,6 +1313,7 @@ config ITCO_WDT ...@@ -1301,6 +1313,7 @@ config ITCO_WDT
select WATCHDOG_CORE select WATCHDOG_CORE
depends on I2C || I2C=n depends on I2C || I2C=n
depends on MFD_INTEL_PMC_BXT || !MFD_INTEL_PMC_BXT depends on MFD_INTEL_PMC_BXT || !MFD_INTEL_PMC_BXT
depends on HAS_IOPORT # for I2C_I801
select LPC_ICH if !EXPERT select LPC_ICH if !EXPERT
select I2C_I801 if !EXPERT && I2C select I2C_I801 if !EXPERT && I2C
help help
...@@ -1331,7 +1344,7 @@ config ITCO_VENDOR_SUPPORT ...@@ -1331,7 +1344,7 @@ config ITCO_VENDOR_SUPPORT
config IT8712F_WDT config IT8712F_WDT
tristate "IT8712F (Smart Guardian) Watchdog Timer" tristate "IT8712F (Smart Guardian) Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the built-in watchdog timer on the IT8712F This is the driver for the built-in watchdog timer on the IT8712F
Super I/0 chipset used on many motherboards. Super I/0 chipset used on many motherboards.
...@@ -1344,7 +1357,7 @@ config IT8712F_WDT ...@@ -1344,7 +1357,7 @@ config IT8712F_WDT
config IT87_WDT config IT87_WDT
tristate "IT87 Watchdog Timer" tristate "IT87 Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
help help
This is the driver for the hardware watchdog on the ITE IT8607, This is the driver for the hardware watchdog on the ITE IT8607,
...@@ -1392,7 +1405,7 @@ config KEMPLD_WDT ...@@ -1392,7 +1405,7 @@ config KEMPLD_WDT
config SC1200_WDT config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is a driver for National Semiconductor PC87307/PC97307 hardware This is a driver for National Semiconductor PC87307/PC97307 hardware
watchdog cards as found on the SC1200. This watchdog is mainly used watchdog cards as found on the SC1200. This watchdog is mainly used
...@@ -1415,7 +1428,7 @@ config SCx200_WDT ...@@ -1415,7 +1428,7 @@ config SCx200_WDT
config PC87413_WDT config PC87413_WDT
tristate "NS PC87413 watchdog" tristate "NS PC87413 watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog on the PC87413 chipset This is the driver for the hardware watchdog on the PC87413 chipset
This watchdog simply watches your kernel to make sure it doesn't This watchdog simply watches your kernel to make sure it doesn't
...@@ -1429,7 +1442,7 @@ config PC87413_WDT ...@@ -1429,7 +1442,7 @@ config PC87413_WDT
config NV_TCO config NV_TCO
tristate "nVidia TCO Timer/Watchdog" tristate "nVidia TCO Timer/Watchdog"
depends on (X86 || COMPILE_TEST) && PCI depends on (X86 || COMPILE_TEST) && PCI && HAS_IOPORT
help help
Hardware driver for the TCO timer built into the nVidia Hub family Hardware driver for the TCO timer built into the nVidia Hub family
(such as the MCP51). The TCO (Total Cost of Ownership) timer is a (such as the MCP51). The TCO (Total Cost of Ownership) timer is a
...@@ -1458,7 +1471,7 @@ config RDC321X_WDT ...@@ -1458,7 +1471,7 @@ config RDC321X_WDT
config 60XX_WDT config 60XX_WDT
tristate "SBC-60XX Watchdog Timer" tristate "SBC-60XX Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This driver can be used with the watchdog timer found on some This driver can be used with the watchdog timer found on some
single board computers, namely the 6010 PII based computer. single board computers, namely the 6010 PII based computer.
...@@ -1498,7 +1511,7 @@ config SBC7240_WDT ...@@ -1498,7 +1511,7 @@ config SBC7240_WDT
config CPU5_WDT config CPU5_WDT
tristate "SMA CPU5 Watchdog" tristate "SMA CPU5 Watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
TBD. TBD.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
...@@ -1506,7 +1519,7 @@ config CPU5_WDT ...@@ -1506,7 +1519,7 @@ config CPU5_WDT
config SMSC_SCH311X_WDT config SMSC_SCH311X_WDT
tristate "SMSC SCH311X Watchdog Timer" tristate "SMSC SCH311X Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog timer on the This is the driver for the hardware watchdog timer on the
SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset
...@@ -1518,7 +1531,7 @@ config SMSC_SCH311X_WDT ...@@ -1518,7 +1531,7 @@ config SMSC_SCH311X_WDT
config SMSC37B787_WDT config SMSC37B787_WDT
tristate "Winbond SMsC37B787 Watchdog Timer" tristate "Winbond SMsC37B787 Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog component on the This is the driver for the hardware watchdog component on the
Winbond SMsC37B787 chipset as used on the NetRunner Mainboard Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
...@@ -1564,7 +1577,7 @@ config VIA_WDT ...@@ -1564,7 +1577,7 @@ config VIA_WDT
config W83627HF_WDT config W83627HF_WDT
tristate "Watchdog timer for W83627HF/W83627DHG and compatibles" tristate "Watchdog timer for W83627HF/W83627DHG and compatibles"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
select WATCHDOG_CORE select WATCHDOG_CORE
help help
This is the driver for the hardware watchdog on the following This is the driver for the hardware watchdog on the following
...@@ -1594,7 +1607,7 @@ config W83627HF_WDT ...@@ -1594,7 +1607,7 @@ config W83627HF_WDT
config W83877F_WDT config W83877F_WDT
tristate "W83877F (EMACS) Watchdog Timer" tristate "W83877F (EMACS) Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog on the W83877F chipset This is the driver for the hardware watchdog on the W83877F chipset
as used in EMACS PC-104 motherboards (and likely others). This as used in EMACS PC-104 motherboards (and likely others). This
...@@ -1609,7 +1622,7 @@ config W83877F_WDT ...@@ -1609,7 +1622,7 @@ config W83877F_WDT
config W83977F_WDT config W83977F_WDT
tristate "W83977F (PCM-5335) Watchdog Timer" tristate "W83977F (PCM-5335) Watchdog Timer"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the hardware watchdog on the W83977F I/O chip This is the driver for the hardware watchdog on the W83977F I/O chip
as used in AAEON's PCM-5335 SBC (and likely others). This as used in AAEON's PCM-5335 SBC (and likely others). This
...@@ -1622,7 +1635,7 @@ config W83977F_WDT ...@@ -1622,7 +1635,7 @@ config W83977F_WDT
config MACHZ_WDT config MACHZ_WDT
tristate "ZF MachZ Watchdog" tristate "ZF MachZ Watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
If you are using a ZF Micro MachZ processor, say Y here, otherwise If you are using a ZF Micro MachZ processor, say Y here, otherwise
N. This is the driver for the watchdog timer built-in on that N. This is the driver for the watchdog timer built-in on that
...@@ -1635,7 +1648,7 @@ config MACHZ_WDT ...@@ -1635,7 +1648,7 @@ config MACHZ_WDT
config SBC_EPX_C3_WATCHDOG config SBC_EPX_C3_WATCHDOG
tristate "Winsystems SBC EPX-C3 watchdog" tristate "Winsystems SBC EPX-C3 watchdog"
depends on X86 || COMPILE_TEST depends on (X86 || COMPILE_TEST) && HAS_IOPORT
help help
This is the driver for the built-in watchdog timer on the EPX-C3 This is the driver for the built-in watchdog timer on the EPX-C3
Single-board computer made by Winsystems, Inc. Single-board computer made by Winsystems, Inc.
...@@ -2197,7 +2210,7 @@ comment "PCI-based Watchdog Cards" ...@@ -2197,7 +2210,7 @@ comment "PCI-based Watchdog Cards"
config PCIPCWATCHDOG config PCIPCWATCHDOG
tristate "Berkshire Products PCI-PC Watchdog" tristate "Berkshire Products PCI-PC Watchdog"
depends on PCI depends on PCI && HAS_IOPORT
help help
This is the driver for the Berkshire Products PCI-PC Watchdog card. This is the driver for the Berkshire Products PCI-PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze, This card simply watches your kernel to make sure it doesn't freeze,
...@@ -2212,7 +2225,7 @@ config PCIPCWATCHDOG ...@@ -2212,7 +2225,7 @@ config PCIPCWATCHDOG
config WDTPCI config WDTPCI
tristate "PCI-WDT500/501 Watchdog timer" tristate "PCI-WDT500/501 Watchdog timer"
depends on PCI depends on PCI && HAS_IOPORT
help help
If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N. If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N.
......
...@@ -120,6 +120,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o ...@@ -120,6 +120,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
obj-$(CONFIG_LENOVO_SE10_WDT) += lenovo_se10_wdt.o
ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
endif endif
......
...@@ -29,7 +29,6 @@ struct bd9576_wdt_priv { ...@@ -29,7 +29,6 @@ struct bd9576_wdt_priv {
struct gpio_desc *gpiod_en; struct gpio_desc *gpiod_en;
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
bool always_running;
struct watchdog_device wdd; struct watchdog_device wdd;
}; };
...@@ -62,10 +61,7 @@ static int bd9576_wdt_stop(struct watchdog_device *wdd) ...@@ -62,10 +61,7 @@ static int bd9576_wdt_stop(struct watchdog_device *wdd)
{ {
struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd); struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd);
if (!priv->always_running) bd9576_wdt_disable(priv);
bd9576_wdt_disable(priv);
else
set_bit(WDOG_HW_RUNNING, &wdd->status);
return 0; return 0;
} }
...@@ -264,9 +260,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev) ...@@ -264,9 +260,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
priv->always_running = device_property_read_bool(dev->parent,
"always-running");
watchdog_set_drvdata(&priv->wdd, priv); watchdog_set_drvdata(&priv->wdd, priv);
priv->wdd.info = &bd957x_wdt_ident; priv->wdd.info = &bd957x_wdt_ident;
...@@ -281,9 +274,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev) ...@@ -281,9 +274,6 @@ static int bd9576_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(&priv->wdd); watchdog_stop_on_reboot(&priv->wdd);
if (priv->always_running)
bd9576_wdt_start(&priv->wdd);
return devm_watchdog_register_device(dev, &priv->wdd); return devm_watchdog_register_device(dev, &priv->wdd);
} }
......
...@@ -252,7 +252,7 @@ static void cpu5wdt_exit(void) ...@@ -252,7 +252,7 @@ static void cpu5wdt_exit(void)
if (cpu5wdt_device.queue) { if (cpu5wdt_device.queue) {
cpu5wdt_device.queue = 0; cpu5wdt_device.queue = 0;
wait_for_completion(&cpu5wdt_device.stop); wait_for_completion(&cpu5wdt_device.stop);
del_timer(&cpu5wdt_device.timer); timer_shutdown_sync(&cpu5wdt_device.timer);
} }
misc_deregister(&cpu5wdt_misc); misc_deregister(&cpu5wdt_misc);
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* WDT driver for Lenovo SE10.
*/
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#define STATUS_PORT 0x6C
#define CMD_PORT 0x6C
#define DATA_PORT 0x68
#define OUTBUF_FULL 0x01
#define INBUF_EMPTY 0x02
#define CFG_LDN 0x07
#define CFG_BRAM_LDN 0x10 /* for BRAM Base */
#define CFG_PORT 0x2E
#define CFG_SIZE 2
#define CMD_SIZE 4
#define BRAM_SIZE 2
#define UNLOCK_KEY 0x87
#define LOCK_KEY 0xAA
#define CUS_WDT_SWI 0x1A
#define CUS_WDT_CFG 0x1B
#define CUS_WDT_FEED 0xB0
#define CUS_WDT_CNT 0xB1
#define DRVNAME "lenovo-se10-wdt"
/*The timeout range is 1-255 seconds*/
#define MIN_TIMEOUT 1
#define MAX_TIMEOUT 255
#define MAX_WAIT 10
#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
static unsigned short bram_base;
static struct platform_device *se10_pdev;
static int timeout; /* in seconds */
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout,
"Watchdog timeout in seconds. 1 <= timeout <= 255, default="
__MODULE_STRING(WATCHDOG_TIMEOUT) ".");
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 se10_wdt {
struct watchdog_device wdd;
};
static int set_bram(unsigned char offset, unsigned char val)
{
if (!request_muxed_region(bram_base, BRAM_SIZE, DRVNAME))
return -EBUSY;
outb(offset, bram_base);
outb(val, bram_base + 1);
release_region(bram_base, BRAM_SIZE);
return 0;
}
static void wait_for_buffer(int condition)
{
int loop = 0;
while (1) {
if (inb(STATUS_PORT) & condition || loop > MAX_WAIT)
break;
loop++;
usleep_range(10, 125);
}
}
static void send_cmd(unsigned char cmd)
{
wait_for_buffer(INBUF_EMPTY);
outb(cmd, CMD_PORT);
wait_for_buffer(INBUF_EMPTY);
}
static void lpc_write(unsigned char index, unsigned char data)
{
outb(index, CFG_PORT);
outb(data, CFG_PORT + 1);
}
static unsigned char lpc_read(unsigned char index)
{
outb(index, CFG_PORT);
return inb(CFG_PORT + 1);
}
static int wdt_start(struct watchdog_device *wdog)
{
return set_bram(CUS_WDT_SWI, 0x80);
}
static int wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout)
{
wdog->timeout = timeout;
return set_bram(CUS_WDT_CFG, wdog->timeout);
}
static int wdt_stop(struct watchdog_device *wdog)
{
return set_bram(CUS_WDT_SWI, 0);
}
static unsigned int wdt_get_time(struct watchdog_device *wdog)
{
unsigned char time;
if (!request_muxed_region(CMD_PORT, CMD_SIZE, DRVNAME))
return -EBUSY;
send_cmd(CUS_WDT_CNT);
wait_for_buffer(OUTBUF_FULL);
time = inb(DATA_PORT);
release_region(CMD_PORT, CMD_SIZE);
return time;
}
static int wdt_ping(struct watchdog_device *wdog)
{
if (!request_muxed_region(CMD_PORT, CMD_SIZE, DRVNAME))
return -EBUSY;
send_cmd(CUS_WDT_FEED);
release_region(CMD_PORT, CMD_SIZE);
return 0;
}
static const struct watchdog_info wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "Lenovo SE10 Watchdog",
};
static const struct watchdog_ops se10_wdt_ops = {
.owner = THIS_MODULE,
.start = wdt_start,
.stop = wdt_stop,
.ping = wdt_ping,
.set_timeout = wdt_set_timeout,
.get_timeleft = wdt_get_time,
};
static unsigned int get_chipID(void)
{
unsigned char msb, lsb;
outb(UNLOCK_KEY, CFG_PORT);
outb(0x01, CFG_PORT);
outb(0x55, CFG_PORT);
outb(0x55, CFG_PORT);
msb = lpc_read(0x20);
lsb = lpc_read(0x21);
outb(LOCK_KEY, CFG_PORT);
return (msb * 256 + lsb);
}
static int se10_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct se10_wdt *priv;
unsigned int chip_id;
int ret;
if (!request_muxed_region(CFG_PORT, CFG_SIZE, DRVNAME))
return -EBUSY;
chip_id = get_chipID();
if (chip_id != 0x5632) {
release_region(CFG_PORT, CFG_SIZE);
return -ENODEV;
}
lpc_write(CFG_LDN, CFG_BRAM_LDN);
bram_base = (lpc_read(0x60) << 8) | lpc_read(0x61);
release_region(CFG_PORT, CFG_SIZE);
dev_info(dev, "Found Lenovo SE10 0x%x\n", chip_id);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
watchdog_set_drvdata(&priv->wdd, priv);
priv->wdd.parent = dev;
priv->wdd.info = &wdt_info,
priv->wdd.ops = &se10_wdt_ops,
priv->wdd.timeout = WATCHDOG_TIMEOUT; /* Set default timeout */
priv->wdd.min_timeout = MIN_TIMEOUT;
priv->wdd.max_timeout = MAX_TIMEOUT;
set_bram(CUS_WDT_CFG, WATCHDOG_TIMEOUT); /* Set time to default */
watchdog_init_timeout(&priv->wdd, timeout, dev);
watchdog_set_nowayout(&priv->wdd, nowayout);
watchdog_stop_on_reboot(&priv->wdd);
watchdog_stop_on_unregister(&priv->wdd);
ret = devm_watchdog_register_device(dev, &priv->wdd);
dev_dbg(&pdev->dev, "initialized. timeout=%d sec (nowayout=%d)\n",
priv->wdd.timeout, nowayout);
return ret;
}
static struct platform_driver se10_wdt_driver = {
.driver = {
.name = DRVNAME,
},
.probe = se10_wdt_probe,
};
static int se10_create_platform_device(const struct dmi_system_id *id)
{
int err;
se10_pdev = platform_device_alloc("lenovo-se10-wdt", -1);
if (!se10_pdev)
return -ENOMEM;
err = platform_device_add(se10_pdev);
if (err)
platform_device_put(se10_pdev);
return err;
}
static const struct dmi_system_id se10_dmi_table[] __initconst = {
{
.ident = "LENOVO-SE10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "12NH"),
},
.callback = se10_create_platform_device,
},
{
.ident = "LENOVO-SE10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "12NJ"),
},
.callback = se10_create_platform_device,
},
{
.ident = "LENOVO-SE10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "12NK"),
},
.callback = se10_create_platform_device,
},
{
.ident = "LENOVO-SE10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "12NL"),
},
.callback = se10_create_platform_device,
},
{
.ident = "LENOVO-SE10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "12NM"),
},
.callback = se10_create_platform_device,
},
{}
};
MODULE_DEVICE_TABLE(dmi, se10_dmi_table);
static int __init se10_wdt_init(void)
{
if (!dmi_check_system(se10_dmi_table))
return -ENODEV;
return platform_driver_register(&se10_wdt_driver);
}
static void __exit se10_wdt_exit(void)
{
if (se10_pdev)
platform_device_unregister(se10_pdev);
platform_driver_unregister(&se10_wdt_driver);
}
module_init(se10_wdt_init);
module_exit(se10_wdt_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Ober<dober@lenovo.com>");
MODULE_AUTHOR("Mark Pearson <mpearson-lenovo@squebb.ca>");
MODULE_DESCRIPTION("WDT driver for Lenovo SE10");
...@@ -236,7 +236,6 @@ static struct platform_driver mtx1_wdt_driver = { ...@@ -236,7 +236,6 @@ static struct platform_driver mtx1_wdt_driver = {
.probe = mtx1_wdt_probe, .probe = mtx1_wdt_probe,
.remove_new = mtx1_wdt_remove, .remove_new = mtx1_wdt_remove,
.driver.name = "mtx1-wdt", .driver.name = "mtx1-wdt",
.driver.owner = THIS_MODULE,
}; };
module_platform_driver(mtx1_wdt_driver); module_platform_driver(mtx1_wdt_driver);
......
...@@ -381,11 +381,7 @@ static int octeon_wdt_cpu_online(unsigned int cpu) ...@@ -381,11 +381,7 @@ static int octeon_wdt_cpu_online(unsigned int cpu)
/* Must set the irq affinity here */ /* Must set the irq affinity here */
if (octeon_has_feature(OCTEON_FEATURE_CIU3)) { if (octeon_has_feature(OCTEON_FEATURE_CIU3)) {
cpumask_t mask; irq_set_affinity(irq, cpumask_of(cpu));
cpumask_clear(&mask);
cpumask_set_cpu(cpu, &mask);
irq_set_affinity(irq, &mask);
} }
cpumask_set_cpu(cpu, &irq_enabled_cpus); cpumask_set_cpu(cpu, &irq_enabled_cpus);
......
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
#define PON_REASON_EOF_NUM 0xCCCCBBBB #define PON_REASON_EOF_NUM 0xCCCCBBBB
#define RESERVED_MEM_MIN_SIZE 12 #define RESERVED_MEM_MIN_SIZE 12
#define MAX_HW_ERROR 250
static int heartbeat = DEFAULT_HEARTBEAT; static int heartbeat = DEFAULT_HEARTBEAT;
/* /*
...@@ -97,7 +99,7 @@ static int rti_wdt_start(struct watchdog_device *wdd) ...@@ -97,7 +99,7 @@ static int rti_wdt_start(struct watchdog_device *wdd)
* to be 50% or less than that; we obviouly want to configure the open * to be 50% or less than that; we obviouly want to configure the open
* window as large as possible so we select the 50% option. * window as large as possible so we select the 50% option.
*/ */
wdd->min_hw_heartbeat_ms = 500 * wdd->timeout; wdd->min_hw_heartbeat_ms = 520 * wdd->timeout + MAX_HW_ERROR;
/* Generate NMI when wdt expires */ /* Generate NMI when wdt expires */
writel_relaxed(RTIWWDRX_NMI, wdt->base + RTIWWDRXCTRL); writel_relaxed(RTIWWDRX_NMI, wdt->base + RTIWWDRXCTRL);
...@@ -131,31 +133,33 @@ static int rti_wdt_setup_hw_hb(struct watchdog_device *wdd, u32 wsize) ...@@ -131,31 +133,33 @@ static int rti_wdt_setup_hw_hb(struct watchdog_device *wdd, u32 wsize)
* be petted during the open window; not too early or not too late. * be petted during the open window; not too early or not too late.
* The HW configuration options only allow for the open window size * The HW configuration options only allow for the open window size
* to be 50% or less than that. * to be 50% or less than that.
* To avoid any glitches, we accommodate 2% + max hardware error
* safety margin.
*/ */
switch (wsize) { switch (wsize) {
case RTIWWDSIZE_50P: case RTIWWDSIZE_50P:
/* 50% open window => 50% min heartbeat */ /* 50% open window => 52% min heartbeat */
wdd->min_hw_heartbeat_ms = 500 * heartbeat; wdd->min_hw_heartbeat_ms = 520 * heartbeat + MAX_HW_ERROR;
break; break;
case RTIWWDSIZE_25P: case RTIWWDSIZE_25P:
/* 25% open window => 75% min heartbeat */ /* 25% open window => 77% min heartbeat */
wdd->min_hw_heartbeat_ms = 750 * heartbeat; wdd->min_hw_heartbeat_ms = 770 * heartbeat + MAX_HW_ERROR;
break; break;
case RTIWWDSIZE_12P5: case RTIWWDSIZE_12P5:
/* 12.5% open window => 87.5% min heartbeat */ /* 12.5% open window => 89.5% min heartbeat */
wdd->min_hw_heartbeat_ms = 875 * heartbeat; wdd->min_hw_heartbeat_ms = 895 * heartbeat + MAX_HW_ERROR;
break; break;
case RTIWWDSIZE_6P25: case RTIWWDSIZE_6P25:
/* 6.5% open window => 93.5% min heartbeat */ /* 6.5% open window => 95.5% min heartbeat */
wdd->min_hw_heartbeat_ms = 935 * heartbeat; wdd->min_hw_heartbeat_ms = 955 * heartbeat + MAX_HW_ERROR;
break; break;
case RTIWWDSIZE_3P125: case RTIWWDSIZE_3P125:
/* 3.125% open window => 96.9% min heartbeat */ /* 3.125% open window => 98.9% min heartbeat */
wdd->min_hw_heartbeat_ms = 969 * heartbeat; wdd->min_hw_heartbeat_ms = 989 * heartbeat + MAX_HW_ERROR;
break; break;
default: default:
...@@ -233,14 +237,6 @@ static int rti_wdt_probe(struct platform_device *pdev) ...@@ -233,14 +237,6 @@ static int rti_wdt_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
/*
* If watchdog is running at 32k clock, it is not accurate.
* Adjust frequency down in this case so that we don't pet
* the watchdog too often.
*/
if (wdt->freq < 32768)
wdt->freq = wdt->freq * 9 / 10;
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = pm_runtime_resume_and_get(dev); ret = pm_runtime_resume_and_get(dev);
if (ret < 0) { if (ret < 0) {
......
...@@ -191,9 +191,8 @@ static int sa1100dog_probe(struct platform_device *pdev) ...@@ -191,9 +191,8 @@ static int sa1100dog_probe(struct platform_device *pdev)
if (!res) if (!res)
return -ENXIO; return -ENXIO;
reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
ret = PTR_ERR_OR_ZERO(reg_base); if (!reg_base)
if (ret) return -ENOMEM;
return ret;
clk = clk_get(NULL, "OSTIMER0"); clk = clk_get(NULL, "OSTIMER0");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment