Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Pull watchdog updates from Wim Van Sebroeck:

 - a new watchdog pretimeout governor framework

 - support to upload the firmware on the ziirave_wdt

 - several fixes and cleanups

* git://www.linux-watchdog.org/linux-watchdog: (26 commits)
  watchdog: imx2_wdt: add pretimeout function support
  watchdog: softdog: implement pretimeout support
  watchdog: pretimeout: add pretimeout_available_governors attribute
  watchdog: pretimeout: add option to select a pretimeout governor in runtime
  watchdog: pretimeout: add panic pretimeout governor
  watchdog: pretimeout: add noop pretimeout governor
  watchdog: add watchdog pretimeout governor framework
  watchdog: hpwdt: add support for iLO5
  fs: compat_ioctl: add pretimeout functions for watchdogs
  watchdog: add pretimeout support to the core
  watchdog: imx2_wdt: use preferred BIT macro instead of open coded values
  watchdog: st_wdt: Remove support for obsolete platforms
  watchdog: bindings: Remove obsolete platforms from dt doc.
  watchdog: mt7621_wdt: Remove assignment of dev pointer
  watchdog: rt2880_wdt: Remove assignment of dev pointer
  watchdog: constify watchdog_ops structures
  watchdog: tegra: constify watchdog_ops structures
  watchdog: iTCO_wdt: constify iTCO_wdt_pm structure
  watchdog: cadence_wdt: Fix the suspend resume
  watchdog: txx9wdt: Add missing clock (un)prepare calls for CCF
  ...
  • Loading branch information
torvalds committed Oct 13, 2016
2 parents b67be92 + 39487f6 commit e3799a2
Show file tree
Hide file tree
Showing 31 changed files with 1,131 additions and 79 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Required properties:
- reg : Physical base address and size

Optional properties:
- clocks : Input clock specifier. Refer to common clock
bindings.
- clock-frequency : Frequency of clock in Hz
- xlnx,wdt-enable-once : 0 - Watchdog can be restarted
1 - Watchdog can be enabled just once
Expand All @@ -17,6 +19,7 @@ Example:
axi-timebase-wdt@40100000 {
clock-frequency = <50000000>;
compatible = "xlnx,xps-timebase-wdt-1.00.a";
clocks = <&clkc 15>;
reg = <0x40100000 0x10000>;
xlnx,wdt-enable-once = <0x0>;
xlnx,wdt-interval = <0x1b>;
Expand Down
3 changes: 1 addition & 2 deletions Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ functionality.

Required properties

- compatible : Must be one of: "st,stih407-lpc" "st,stih416-lpc"
"st,stih415-lpc" "st,stid127-lpc"
- compatible : Should be: "st,stih407-lpc"
- reg : LPC registers base address + size
- interrupts : LPC interrupt line number and associated flags
- clocks : Clock used by LPC device (See: ../clock/clock-bindings.txt)
Expand Down
33 changes: 33 additions & 0 deletions Documentation/watchdog/watchdog-kernel-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ struct watchdog_device {
const struct attribute_group **groups;
const struct watchdog_info *info;
const struct watchdog_ops *ops;
const struct watchdog_governor *gov;
unsigned int bootstatus;
unsigned int timeout;
unsigned int pretimeout;
unsigned int min_timeout;
unsigned int max_timeout;
unsigned int min_hw_heartbeat_ms;
Expand All @@ -74,9 +76,11 @@ It contains following fields:
* info: a pointer to a watchdog_info structure. This structure gives some
additional information about the watchdog timer itself. (Like it's unique name)
* ops: a pointer to the list of watchdog operations that the watchdog supports.
* gov: a pointer to the assigned watchdog device pretimeout governor or NULL.
* timeout: the watchdog timer's timeout value (in seconds).
This is the time after which the system will reboot if user space does
not send a heartbeat request if WDOG_ACTIVE is set.
* pretimeout: the watchdog timer's pretimeout value (in seconds).
* min_timeout: the watchdog timer's minimum timeout value (in seconds).
If set, the minimum configurable value for 'timeout'.
* max_timeout: the watchdog timer's maximum timeout value (in seconds),
Expand Down Expand Up @@ -121,6 +125,7 @@ struct watchdog_ops {
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
int (*set_timeout)(struct watchdog_device *, unsigned int);
int (*set_pretimeout)(struct watchdog_device *, unsigned int);
unsigned int (*get_timeleft)(struct watchdog_device *);
int (*restart)(struct watchdog_device *);
void (*ref)(struct watchdog_device *) __deprecated;
Expand Down Expand Up @@ -188,6 +193,23 @@ they are supported. These optional routines/operations are:
If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog
infrastructure updates the timeout value of the watchdog_device internally
to the requested value.
If the pretimeout feature is used (WDIOF_PRETIMEOUT), then set_timeout must
also take care of checking if pretimeout is still valid and set up the timer
accordingly. This can't be done in the core without races, so it is the
duty of the driver.
* set_pretimeout: this routine checks and changes the pretimeout value of
the watchdog. It is optional because not all watchdogs support pretimeout
notification. The timeout value is not an absolute time, but the number of
seconds before the actual timeout would happen. It returns 0 on success,
-EINVAL for "parameter out of range" and -EIO for "could not write value to
the watchdog". A value of 0 disables pretimeout notification.
(Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the
watchdog's info structure).
If the watchdog driver does not have to perform any action but setting the
watchdog_device.pretimeout, this callback can be omitted. That means if
set_pretimeout is not provided but WDIOF_PRETIMEOUT is set, the watchdog
infrastructure updates the pretimeout value of the watchdog_device internally
to the requested value.
* get_timeleft: this routines returns the time that's left before a reset.
* restart: this routine restarts the machine. It returns 0 on success or a
negative errno code for failure.
Expand Down Expand Up @@ -268,3 +290,14 @@ User should follow the following guidelines for setting the priority:
* 128: default restart handler, use if no other handler is expected to be
available, and/or if restart is sufficient to restart the entire system
* 255: highest priority, will preempt all other restart handlers

To raise a pretimeout notification, the following function should be used:

void watchdog_notify_pretimeout(struct watchdog_device *wdd)

The function can be called in the interrupt context. If watchdog pretimeout
governor framework (kbuild CONFIG_WATCHDOG_PRETIMEOUT_GOV symbol) is enabled,
an action is taken by a preconfigured pretimeout governor preassigned to
the watchdog device. If watchdog pretimeout governor framework is not
enabled, watchdog_notify_pretimeout() prints a notification message to
the kernel log buffer.
49 changes: 49 additions & 0 deletions drivers/watchdog/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1844,4 +1844,53 @@ config USBPCWATCHDOG

Most people will say N.

comment "Watchdog Pretimeout Governors"

config WATCHDOG_PRETIMEOUT_GOV
bool "Enable watchdog pretimeout governors"
help
The option allows to select watchdog pretimeout governors.

if WATCHDOG_PRETIMEOUT_GOV

choice
prompt "Default Watchdog Pretimeout Governor"
default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
help
This option selects a default watchdog pretimeout governor.
The governor takes its action, if a watchdog is capable
to report a pretimeout event.

config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
bool "noop"
select WATCHDOG_PRETIMEOUT_GOV_NOOP
help
Use noop watchdog pretimeout governor by default. If noop
governor is selected by a user, write a short message to
the kernel log buffer and don't do any system changes.

config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
bool "panic"
select WATCHDOG_PRETIMEOUT_GOV_PANIC
help
Use panic watchdog pretimeout governor by default, if
a watchdog pretimeout event happens, consider that
a watchdog feeder is dead and reboot is unavoidable.

endchoice

config WATCHDOG_PRETIMEOUT_GOV_NOOP
tristate "Noop watchdog pretimeout governor"
help
Noop watchdog pretimeout governor, only an informational
message is added to kernel log buffer.

config WATCHDOG_PRETIMEOUT_GOV_PANIC
tristate "Panic watchdog pretimeout governor"
help
Panic watchdog pretimeout governor, on watchdog pretimeout
event put the kernel into panic.

endif # WATCHDOG_PRETIMEOUT_GOV

endif # WATCHDOG
8 changes: 7 additions & 1 deletion drivers/watchdog/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
#

# The WatchDog Timer Driver Core.
watchdog-objs += watchdog_core.o watchdog_dev.o
obj-$(CONFIG_WATCHDOG_CORE) += watchdog.o

watchdog-objs += watchdog_core.o watchdog_dev.o

watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o

obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o
obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o

# Only one watchdog can succeed. We probe the ISA/PCI/USB based
# watchdog-cards first, then the architecture specific watchdog
# drivers and then the architecture independent "softdog" driver.
Expand Down
1 change: 0 additions & 1 deletion drivers/watchdog/asm9260_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,6 @@ MODULE_DEVICE_TABLE(of, asm9260_wdt_of_match);
static struct platform_driver asm9260_wdt_driver = {
.driver = {
.name = "asm9260-wdt",
.owner = THIS_MODULE,
.of_match_table = asm9260_wdt_of_match,
},
.probe = asm9260_wdt_probe,
Expand Down
2 changes: 1 addition & 1 deletion drivers/watchdog/bcm7038_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static struct watchdog_info bcm7038_wdt_info = {
WDIOF_MAGICCLOSE
};

static struct watchdog_ops bcm7038_wdt_ops = {
static const struct watchdog_ops bcm7038_wdt_ops = {
.owner = THIS_MODULE,
.start = bcm7038_wdt_start,
.stop = bcm7038_wdt_stop,
Expand Down
20 changes: 12 additions & 8 deletions drivers/watchdog/cadence_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ static struct watchdog_info cdns_wdt_info = {
};

/* Watchdog Core Ops */
static struct watchdog_ops cdns_wdt_ops = {
static const struct watchdog_ops cdns_wdt_ops = {
.owner = THIS_MODULE,
.start = cdns_wdt_start,
.stop = cdns_wdt_stop,
Expand Down Expand Up @@ -424,8 +424,10 @@ static int __maybe_unused cdns_wdt_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct cdns_wdt *wdt = platform_get_drvdata(pdev);

cdns_wdt_stop(&wdt->cdns_wdt_device);
clk_disable_unprepare(wdt->clk);
if (watchdog_active(&wdt->cdns_wdt_device)) {
cdns_wdt_stop(&wdt->cdns_wdt_device);
clk_disable_unprepare(wdt->clk);
}

return 0;
}
Expand All @@ -442,12 +444,14 @@ static int __maybe_unused cdns_wdt_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct cdns_wdt *wdt = platform_get_drvdata(pdev);

ret = clk_prepare_enable(wdt->clk);
if (ret) {
dev_err(dev, "unable to enable clock\n");
return ret;
if (watchdog_active(&wdt->cdns_wdt_device)) {
ret = clk_prepare_enable(wdt->clk);
if (ret) {
dev_err(dev, "unable to enable clock\n");
return ret;
}
cdns_wdt_start(&wdt->cdns_wdt_device);
}
cdns_wdt_start(&wdt->cdns_wdt_device);

return 0;
}
Expand Down
11 changes: 9 additions & 2 deletions drivers/watchdog/dw_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
struct dw_wdt {
void __iomem *regs;
struct clk *clk;
unsigned long rate;
struct notifier_block restart_handler;
struct watchdog_device wdd;
};
Expand All @@ -72,7 +73,7 @@ static inline int dw_wdt_top_in_seconds(struct dw_wdt *dw_wdt, unsigned top)
* There are 16 possible timeout values in 0..15 where the number of
* cycles is 2 ^ (16 + i) and the watchdog counts down.
*/
return (1U << (16 + top)) / clk_get_rate(dw_wdt->clk);
return (1U << (16 + top)) / dw_wdt->rate;
}

static int dw_wdt_get_top(struct dw_wdt *dw_wdt)
Expand Down Expand Up @@ -163,7 +164,7 @@ static unsigned int dw_wdt_get_timeleft(struct watchdog_device *wdd)
struct dw_wdt *dw_wdt = to_dw_wdt(wdd);

return readl(dw_wdt->regs + WDOG_CURRENT_COUNT_REG_OFFSET) /
clk_get_rate(dw_wdt->clk);
dw_wdt->rate;
}

static const struct watchdog_info dw_wdt_ident = {
Expand Down Expand Up @@ -231,6 +232,12 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
if (ret)
return ret;

dw_wdt->rate = clk_get_rate(dw_wdt->clk);
if (dw_wdt->rate == 0) {
ret = -EINVAL;
goto out_disable_clk;
}

wdd = &dw_wdt->wdd;
wdd->info = &dw_wdt_ident;
wdd->ops = &dw_wdt_ops;
Expand Down
8 changes: 5 additions & 3 deletions drivers/watchdog/hpwdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <asm/nmi.h>
#include <asm/frame.h>

#define HPWDT_VERSION "1.3.3"
#define HPWDT_VERSION "1.4.0"
#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535)
Expand Down Expand Up @@ -814,7 +814,8 @@ static int hpwdt_init_one(struct pci_dev *dev,
* not run on a legacy ASM box.
* So we only support the G5 ProLiant servers and higher.
*/
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP &&
dev->subsystem_vendor != PCI_VENDOR_ID_HP_3PAR) {
dev_warn(&dev->dev,
"This server does not have an iLO2+ ASIC.\n");
return -ENODEV;
Expand All @@ -823,7 +824,8 @@ static int hpwdt_init_one(struct pci_dev *dev,
/*
* Ignore all auxilary iLO devices with the following PCI ID
*/
if (dev->subsystem_device == 0x1979)
if (dev->subsystem_vendor == PCI_VENDOR_ID_HP &&
dev->subsystem_device == 0x1979)
return -ENODEV;

if (pci_enable_device(dev)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/watchdog/iTCO_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ static int iTCO_wdt_resume_noirq(struct device *dev)
return 0;
}

static struct dev_pm_ops iTCO_wdt_pm = {
static const struct dev_pm_ops iTCO_wdt_pm = {
.suspend_noirq = iTCO_wdt_suspend_noirq,
.resume_noirq = iTCO_wdt_resume_noirq,
};
Expand Down
Loading

0 comments on commit e3799a2

Please sign in to comment.