Merge tag 'linux-watchdog-5.1-rc1' of git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Mar 2019 18:22:15 +0000 (11:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Mar 2019 18:22:15 +0000 (11:22 -0700)
Pull watchdog updates from Wim Van Sebroeck:

 - a new watchdog driver for the Mellanox systems

 - renesas-wdt: Document r8a77470 support

 - numerous 'Mark expected switch fall-throughs'

 - qcom: Add suspend/resume support

 - some small fixes and documentation updates

* tag 'linux-watchdog-5.1-rc1' of git://www.linux-watchdog.org/linux-watchdog:
  watchdog: w83877f_wdt: Mark expected switch fall-through
  watchdog: sc520_wdt: Mark expected switch fall-through
  watchdog: sbc60xxwdt: Mark expected switch fall-through
  watchdog: smsc37b787_wdt: Mark expected switch fall-through
  watchdog: sc1200: Mark expected switch fall-through
  watchdog: pc87413: Mark expected switch fall-through
  Documentation/watchdog: Add documentation mlx-wdt driver
  watchdog: mlx-wdt: introduce a watchdog driver for Mellanox systems.
  platform_data/mlxreg: additions for Mellanox watchdog driver.
  watchdog: Update sysfs documentation.
  watchdog: dw: remove useless pr_fmt
  watchdog: pika_wdt: drop pointless static qualifier in pikawdt_init
  watchdog/hpwdt: Update Kconfig documentation
  dt-bindings: watchdog: renesas-wdt: Document r8a77470 support
  watchdog: qcom: Add suspend/resume support

16 files changed:
Documentation/ABI/testing/sysfs-class-watchdog
Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
Documentation/watchdog/mlx-wdt.txt [new file with mode: 0644]
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/dw_wdt.c
drivers/watchdog/mlx_wdt.c [new file with mode: 0644]
drivers/watchdog/pc87413_wdt.c
drivers/watchdog/pika_wdt.c
drivers/watchdog/qcom-wdt.c
drivers/watchdog/sbc60xxwdt.c
drivers/watchdog/sc1200wdt.c
drivers/watchdog/sc520_wdt.c
drivers/watchdog/smsc37b787_wdt.c
drivers/watchdog/w83877f_wdt.c
include/linux/platform_data/mlxreg.h

index 736046b330405284d29d5384943a1145fd495164..6317ade5ad19a90c48a459aecd981122fde48df9 100644 (file)
@@ -49,3 +49,26 @@ Contact:     Wim Van Sebroeck <wim@iguana.be>
 Description:
                It is a read only file. It is read to know about current
                value of timeout programmed.
+
+What:          /sys/class/watchdog/watchdogn/pretimeout
+Date:          December 2016
+Contact:       Wim Van Sebroeck <wim@iguana.be>
+Description:
+               It is a read only file. It specifies the time in seconds before
+               timeout when the pretimeout interrupt is delivered.  Pretimeout
+               is an optional feature.
+
+What:          /sys/class/watchdog/watchdogn/pretimeout_avaialable_governors
+Date:          February 2017
+Contact:       Wim Van Sebroeck <wim@iguana.be>
+Description:
+               It is a read only file. It shows the pretimeout governors
+               available for this watchdog.
+
+What:          /sys/class/watchdog/watchdogn/pretimeout_governor
+Date:          February 2017
+Contact:       Wim Van Sebroeck <wim@iguana.be>
+Description:
+               It is a read/write file. When read, the currently assigned
+               pretimeout governor is returned.  When written, it sets
+               the pretimeout governor.
index ef2b97b72e082a0557a817b1d91a3978fd138b71..9f365c1a33995f2b12324cd7874dbbb1c8fa59e2 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
                 - "renesas,r8a7743-wdt" (RZ/G1M)
                 - "renesas,r8a7744-wdt" (RZ/G1N)
                 - "renesas,r8a7745-wdt" (RZ/G1E)
+                - "renesas,r8a77470-wdt" (RZ/G1C)
                 - "renesas,r8a774a1-wdt" (RZ/G2M)
                 - "renesas,r8a774c0-wdt" (RZ/G2E)
                 - "renesas,r8a7790-wdt" (R-Car H2)
diff --git a/Documentation/watchdog/mlx-wdt.txt b/Documentation/watchdog/mlx-wdt.txt
new file mode 100644 (file)
index 0000000..66eeb78
--- /dev/null
@@ -0,0 +1,52 @@
+               Mellanox watchdog drivers
+               for x86 based system switches
+
+This driver provides watchdog functionality for various Mellanox
+Ethernet and Infiniband switch systems.
+
+Mellanox watchdog device is implemented in a programmable logic device.
+
+There are 2 types of HW watchdog implementations.
+
+Type 1:
+Actual HW timeout can be defined as a power of 2 msec.
+e.g. timeout 20 sec will be rounded up to 32768 msec.
+The maximum timeout period is 32 sec (32768 msec.),
+Get time-left isn't supported
+
+Type 2:
+Actual HW timeout is defined in sec. and it's the same as
+a user-defined timeout.
+Maximum timeout is 255 sec.
+Get time-left is supported.
+
+Type 1 HW watchdog implementation exist in old systems and
+all new systems have type 2 HW watchdog.
+Two types of HW implementation have also different register map.
+
+Mellanox system can have 2 watchdogs: main and auxiliary.
+Main and auxiliary watchdog devices can be enabled together
+on the same system.
+There are several actions that can be defined in the watchdog:
+system reset, start fans on full speed and increase register counter.
+The last 2 actions are performed without a system reset.
+Actions without reset are provided for auxiliary watchdog device,
+which is optional.
+Watchdog can be started during a probe, in this case it will be
+pinged by watchdog core before watchdog device will be opened by
+user space application.
+Watchdog can be initialised in nowayout way, i.e. oncse started
+it can't be stopped.
+
+This mlx-wdt driver supports both HW watchdog implementations.
+
+Watchdog driver is probed from the common mlx_platform driver.
+Mlx_platform driver provides an appropriate set of registers for
+Mellanox watchdog device, identity name (mlx-wdt-main or mlx-wdt-aux),
+initial timeout, performed action in expiration and configuration flags.
+watchdog configuration flags: nowayout and start_at_boot, hw watchdog
+version - type1 or type2.
+The driver checks during initialization if the previous system reset
+was done by the watchdog. If yes, it makes a notification about this event.
+
+Access to HW registers is performed through a generic regmap interface.
index 65c3c42b5e7c3495634ac302521892a597c0d93e..242eea8596373e21fc677a9004f55641034ab6fd 100644 (file)
@@ -241,6 +241,22 @@ config RAVE_SP_WATCHDOG
        help
          Support for the watchdog on RAVE SP device.
 
+config MLX_WDT
+       tristate "Mellanox Watchdog"
+       depends on MELLANOX_PLATFORM
+       select WATCHDOG_CORE
+       select REGMAP
+       help
+         This is the driver for the hardware watchdog on Mellanox systems.
+         If you are going to use it, say Y here, otherwise N.
+         This driver can be used together with the watchdog daemon.
+         It can also watch your kernel to make sure it doesn't freeze,
+         and if it does, it reboots your system after a certain amount of
+         time.
+
+         To compile this driver as a module, choose M here: the
+         module will be called mlx-wdt.
+
 # ALPHA Architecture
 
 # ARM Architecture
@@ -1157,7 +1173,7 @@ config HP_WATCHDOG
        select WATCHDOG_CORE
        depends on X86 && PCI
        help
-         A software monitoring watchdog and NMI sourcing driver. This driver
+         A software monitoring watchdog and NMI handling driver. This driver
          will detect lockups and provide a stack trace. This is a driver that
          will only load on an HP ProLiant system with a minimum of iLO2 support.
          To compile this driver as a module, choose M here: the module will be
@@ -1175,12 +1191,13 @@ config KEMPLD_WDT
          called kempld_wdt.
 
 config HPWDT_NMI_DECODING
-       bool "NMI decoding support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
+       bool "NMI support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
        depends on HP_WATCHDOG
        default y
        help
-         When an NMI occurs this feature will make the necessary BIOS calls to
-         log the cause of the NMI.
+         Enables the NMI handler for the watchdog pretimeout NMI and the iLO
+         "Generate NMI to System" virtual button.  When an NMI is claimed
+         by the driver, panic is called.
 
 config SC1200_WDT
        tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
index 4e78a8c73f0ce11d89d6a30b87fb9058056305bb..ba930e464657590131ba2f35ef28afad27ef091e 100644 (file)
@@ -142,6 +142,7 @@ obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o
 obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o
 obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o
 obj-$(CONFIG_NIC7018_WDT) += nic7018_wdt.o
+obj-$(CONFIG_MLX_WDT) += mlx_wdt.o
 
 # M68K Architecture
 obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o
index 501aebb5b81f65cb92edb0f9fc5a33745c2a65b1..aa95f57cc1c316c64b3325259bcf12efcf3f1743 100644 (file)
@@ -16,8 +16,6 @@
  * heartbeat requests after the watchdog device has been closed.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
diff --git a/drivers/watchdog/mlx_wdt.c b/drivers/watchdog/mlx_wdt.c
new file mode 100644 (file)
index 0000000..70c2cbf
--- /dev/null
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Mellanox watchdog driver
+ *
+ * Copyright (C) 2019 Mellanox Technologies
+ * Copyright (C) 2019 Michael Shych <mshych@mellanox.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+#define MLXREG_WDT_CLOCK_SCALE         1000
+#define MLXREG_WDT_MAX_TIMEOUT_TYPE1   32
+#define MLXREG_WDT_MAX_TIMEOUT_TYPE2   255
+#define MLXREG_WDT_MIN_TIMEOUT         1
+#define MLXREG_WDT_OPTIONS_BASE (WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | \
+                                WDIOF_SETTIMEOUT)
+
+/**
+ * struct mlxreg_wdt - wd private data:
+ *
+ * @wdd:       watchdog device;
+ * @device:    basic device;
+ * @pdata:     data received from platform driver;
+ * @regmap:    register map of parent device;
+ * @timeout:   defined timeout in sec.;
+ * @action_idx:        index for direct access to action register;
+ * @timeout_idx:index for direct access to TO register;
+ * @tleft_idx: index for direct access to time left register;
+ * @ping_idx:  index for direct access to ping register;
+ * @reset_idx: index for direct access to reset cause register;
+ * @wd_type:   watchdog HW type;
+ */
+struct mlxreg_wdt {
+       struct watchdog_device wdd;
+       struct mlxreg_core_platform_data *pdata;
+       void *regmap;
+       int action_idx;
+       int timeout_idx;
+       int tleft_idx;
+       int ping_idx;
+       int reset_idx;
+       enum mlxreg_wdt_type wdt_type;
+};
+
+static void mlxreg_wdt_check_card_reset(struct mlxreg_wdt *wdt)
+{
+       struct mlxreg_core_data *reg_data;
+       u32 regval;
+       int rc;
+
+       if (wdt->reset_idx == -EINVAL)
+               return;
+
+       if (!(wdt->wdd.info->options & WDIOF_CARDRESET))
+               return;
+
+       reg_data = &wdt->pdata->data[wdt->reset_idx];
+       rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+       if (!rc) {
+               if (regval & ~reg_data->mask) {
+                       wdt->wdd.bootstatus = WDIOF_CARDRESET;
+                       dev_info(wdt->wdd.parent,
+                                "watchdog previously reset the CPU\n");
+               }
+       }
+}
+
+static int mlxreg_wdt_start(struct watchdog_device *wdd)
+{
+       struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+       struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
+
+       return regmap_update_bits(wdt->regmap, reg_data->reg, ~reg_data->mask,
+                                 BIT(reg_data->bit));
+}
+
+static int mlxreg_wdt_stop(struct watchdog_device *wdd)
+{
+       struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+       struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
+
+       return regmap_update_bits(wdt->regmap, reg_data->reg, ~reg_data->mask,
+                                 ~BIT(reg_data->bit));
+}
+
+static int mlxreg_wdt_ping(struct watchdog_device *wdd)
+{
+       struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+       struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->ping_idx];
+
+       return regmap_update_bits_base(wdt->regmap, reg_data->reg,
+                                      ~reg_data->mask, BIT(reg_data->bit),
+                                      NULL, false, true);
+}
+
+static int mlxreg_wdt_set_timeout(struct watchdog_device *wdd,
+                                 unsigned int timeout)
+{
+       struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+       struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->timeout_idx];
+       u32 regval, set_time, hw_timeout;
+       int rc;
+
+       if (wdt->wdt_type == MLX_WDT_TYPE1) {
+               rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+               if (rc)
+                       return rc;
+
+               hw_timeout = order_base_2(timeout * MLXREG_WDT_CLOCK_SCALE);
+               regval = (regval & reg_data->mask) | hw_timeout;
+               /* Rowndown to actual closest number of sec. */
+               set_time = BIT(hw_timeout) / MLXREG_WDT_CLOCK_SCALE;
+       } else {
+               set_time = timeout;
+               regval = timeout;
+       }
+
+       wdd->timeout = set_time;
+       rc = regmap_write(wdt->regmap, reg_data->reg, regval);
+
+       if (!rc) {
+               /*
+                * Restart watchdog with new timeout period
+                * if watchdog is already started.
+                */
+               if (watchdog_active(wdd)) {
+                       rc = mlxreg_wdt_stop(wdd);
+                       if (!rc)
+                               rc = mlxreg_wdt_start(wdd);
+               }
+       }
+
+       return rc;
+}
+
+static unsigned int mlxreg_wdt_get_timeleft(struct watchdog_device *wdd)
+{
+       struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+       struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->tleft_idx];
+       u32 regval;
+       int rc;
+
+       rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+       /* Return 0 timeleft in case of failure register read. */
+       return rc == 0 ? regval : 0;
+}
+
+static const struct watchdog_ops mlxreg_wdt_ops_type1 = {
+       .start          = mlxreg_wdt_start,
+       .stop           = mlxreg_wdt_stop,
+       .ping           = mlxreg_wdt_ping,
+       .set_timeout    = mlxreg_wdt_set_timeout,
+       .owner          = THIS_MODULE,
+};
+
+static const struct watchdog_ops mlxreg_wdt_ops_type2 = {
+       .start          = mlxreg_wdt_start,
+       .stop           = mlxreg_wdt_stop,
+       .ping           = mlxreg_wdt_ping,
+       .set_timeout    = mlxreg_wdt_set_timeout,
+       .get_timeleft   = mlxreg_wdt_get_timeleft,
+       .owner          = THIS_MODULE,
+};
+
+static const struct watchdog_info mlxreg_wdt_main_info = {
+       .options        = MLXREG_WDT_OPTIONS_BASE
+                       | WDIOF_CARDRESET,
+       .identity       = "mlx-wdt-main",
+};
+
+static const struct watchdog_info mlxreg_wdt_aux_info = {
+       .options        = MLXREG_WDT_OPTIONS_BASE
+                       | WDIOF_ALARMONLY,
+       .identity       = "mlx-wdt-aux",
+};
+
+static void mlxreg_wdt_config(struct mlxreg_wdt *wdt,
+                             struct mlxreg_core_platform_data *pdata)
+{
+       struct mlxreg_core_data *data = pdata->data;
+       int i;
+
+       wdt->reset_idx = -EINVAL;
+       for (i = 0; i < pdata->counter; i++, data++) {
+               if (strnstr(data->label, "action", sizeof(data->label)))
+                       wdt->action_idx = i;
+               else if (strnstr(data->label, "timeout", sizeof(data->label)))
+                       wdt->timeout_idx = i;
+               else if (strnstr(data->label, "timeleft", sizeof(data->label)))
+                       wdt->tleft_idx = i;
+               else if (strnstr(data->label, "ping", sizeof(data->label)))
+                       wdt->ping_idx = i;
+               else if (strnstr(data->label, "reset", sizeof(data->label)))
+                       wdt->reset_idx = i;
+       }
+
+       wdt->pdata = pdata;
+       if (strnstr(pdata->identity, mlxreg_wdt_main_info.identity,
+                   sizeof(mlxreg_wdt_main_info.identity)))
+               wdt->wdd.info = &mlxreg_wdt_main_info;
+       else
+               wdt->wdd.info = &mlxreg_wdt_aux_info;
+
+       wdt->wdt_type = pdata->version;
+       if (wdt->wdt_type == MLX_WDT_TYPE2) {
+               wdt->wdd.ops = &mlxreg_wdt_ops_type2;
+               wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE2;
+       } else {
+               wdt->wdd.ops = &mlxreg_wdt_ops_type1;
+               wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE1;
+       }
+       wdt->wdd.min_timeout = MLXREG_WDT_MIN_TIMEOUT;
+}
+
+static int mlxreg_wdt_init_timeout(struct mlxreg_wdt *wdt,
+                                  struct mlxreg_core_platform_data *pdata)
+{
+       u32 timeout;
+
+       timeout = pdata->data[wdt->timeout_idx].health_cntr;
+       return mlxreg_wdt_set_timeout(&wdt->wdd, timeout);
+}
+
+static int mlxreg_wdt_probe(struct platform_device *pdev)
+{
+       struct mlxreg_core_platform_data *pdata;
+       struct mlxreg_wdt *wdt;
+       int rc;
+
+       pdata = dev_get_platdata(&pdev->dev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "Failed to get platform data.\n");
+               return -EINVAL;
+       }
+       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+       if (!wdt)
+               return -ENOMEM;
+
+       wdt->wdd.parent = &pdev->dev;
+       wdt->regmap = pdata->regmap;
+       mlxreg_wdt_config(wdt, pdata);
+
+       if ((pdata->features & MLXREG_CORE_WD_FEATURE_NOWAYOUT))
+               watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
+       watchdog_stop_on_reboot(&wdt->wdd);
+       watchdog_stop_on_unregister(&wdt->wdd);
+       watchdog_set_drvdata(&wdt->wdd, wdt);
+       rc = mlxreg_wdt_init_timeout(wdt, pdata);
+       if (rc)
+               goto register_error;
+
+       if ((pdata->features & MLXREG_CORE_WD_FEATURE_START_AT_BOOT)) {
+               rc = mlxreg_wdt_start(&wdt->wdd);
+               if (rc)
+                       goto register_error;
+               set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
+       }
+       mlxreg_wdt_check_card_reset(wdt);
+       rc = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+
+register_error:
+       if (rc)
+               dev_err(&pdev->dev,
+                       "Cannot register watchdog device (err=%d)\n", rc);
+       return rc;
+}
+
+static struct platform_driver mlxreg_wdt_driver = {
+       .probe  = mlxreg_wdt_probe,
+       .driver = {
+                       .name = "mlx-wdt",
+       },
+};
+
+module_platform_driver(mlxreg_wdt_driver);
+
+MODULE_AUTHOR("Michael Shych <michaelsh@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mlx-wdt");
index 06a892e36a8d889ab1c6936b3209d8cd61a2f8c1..2ffa39b46970ad9ebbd2614b160dfc96a285d08e 100644 (file)
@@ -437,7 +437,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd,
                        return -EINVAL;
                timeout = new_timeout;
                pc87413_refresh();
-               /* fall through and return the new timeout... */
+               /* fall through and return the new timeout... */
        case WDIOC_GETTIMEOUT:
                new_timeout = timeout * 60;
                return put_user(new_timeout, uarg.i);
index e0a6f8c0f03cde84a32e5744a1f3ee24fd7cbd00..bb97f5b2f7eb1c195924dea9459334e637a5cc0b 100644 (file)
@@ -225,7 +225,7 @@ static int __init pikawdt_init(void)
 {
        struct device_node *np;
        void __iomem *fpga;
-       static u32 post1;
+       u32 post1;
        int ret;
 
        np = of_find_compatible_node(NULL, NULL, "pika,fpga");
index 780971318810d4a989b0cf58979f93676f2aa42b..5dfd604477a4873d4fd491a179842b5a0b495d91 100644 (file)
@@ -245,6 +245,28 @@ static int qcom_wdt_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused qcom_wdt_suspend(struct device *dev)
+{
+       struct qcom_wdt *wdt = dev_get_drvdata(dev);
+
+       if (watchdog_active(&wdt->wdd))
+               qcom_wdt_stop(&wdt->wdd);
+
+       return 0;
+}
+
+static int __maybe_unused qcom_wdt_resume(struct device *dev)
+{
+       struct qcom_wdt *wdt = dev_get_drvdata(dev);
+
+       if (watchdog_active(&wdt->wdd))
+               qcom_wdt_start(&wdt->wdd);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(qcom_wdt_pm_ops, qcom_wdt_suspend, qcom_wdt_resume);
+
 static const struct of_device_id qcom_wdt_of_table[] = {
        { .compatible = "qcom,kpss-timer", .data = reg_offset_data_apcs_tmr },
        { .compatible = "qcom,scss-timer", .data = reg_offset_data_apcs_tmr },
@@ -259,6 +281,7 @@ static struct platform_driver qcom_watchdog_driver = {
        .driver = {
                .name           = KBUILD_MODNAME,
                .of_match_table = qcom_wdt_of_table,
+               .pm             = &qcom_wdt_pm_ops,
        },
 };
 module_platform_driver(qcom_watchdog_driver);
index 87333a41f75384ca7bd4ff3b5c66bad5602e5dd8..72d15fd1f183f63a8afef21459915f5c92e271ef 100644 (file)
@@ -270,8 +270,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
                timeout = new_timeout;
                wdt_keepalive();
-               /* Fall through */
        }
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
        default:
index 8e4e2fc13f87a5db0480914c3937e06da99f03e6..e035a4d4b299f388e6f5287b69621acc2f6e4ee1 100644 (file)
@@ -239,7 +239,7 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
                        return -EINVAL;
                timeout = new_timeout;
                sc1200wdt_write_data(WDTO, timeout);
-               /* fall through and return the new timeout */
+               /* fall through and return the new timeout */
 
        case WDIOC_GETTIMEOUT:
                return put_user(timeout * 60, p);
index 6aadb56e7faaa7161b8f32d8fd45a573e989e4a2..403542f9ed8dfd21b5bfcfc5e26ffbc3ca72b3d6 100644 (file)
@@ -324,8 +324,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
 
                wdt_keepalive();
-               /* Fall through */
        }
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
        default:
index 445ea1ad1fa9abc7fcef53b63e5d0025032f9f07..c768dcd5303484120ecae579da9cc08ddc8f1e74 100644 (file)
@@ -478,7 +478,7 @@ static long wb_smsc_wdt_ioctl(struct file *file,
                        return -EINVAL;
                timeout = new_timeout;
                wb_smsc_wdt_set_timeout(timeout);
-               /* fall through and return the new timeout... */
+               /* fall through and return the new timeout... */
        case WDIOC_GETTIMEOUT:
                new_timeout = timeout;
                if (unit == UNIT_MINUTE)
index 05658ecc0aa4cdc87875ec05aba6eed23b4f1551..db9b6488e3888c6f59d76e9d38babaf660f0b3cf 100644 (file)
@@ -292,8 +292,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
                timeout = new_timeout;
                wdt_keepalive();
-               /* Fall through */
        }
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
        default:
index 1b2f86f9674382815e5e2d17ef0e7b2eb078e28f..6d54fe3bcac9c934e679d53d8101e3da81a88d4e 100644 (file)
 #define __LINUX_PLATFORM_DATA_MLXREG_H
 
 #define MLXREG_CORE_LABEL_MAX_SIZE     32
+#define MLXREG_CORE_WD_FEATURE_NOWAYOUT                BIT(0)
+#define MLXREG_CORE_WD_FEATURE_START_AT_BOOT   BIT(1)
+
+/**
+ * enum mlxreg_wdt_type - type of HW watchdog
+ *
+ * TYPE1 HW watchdog implementation exist in old systems.
+ * All new systems have TYPE2 HW watchdog.
+ */
+enum mlxreg_wdt_type {
+       MLX_WDT_TYPE1,
+       MLX_WDT_TYPE2,
+};
 
 /**
  * struct mlxreg_hotplug_device - I2C device data:
@@ -112,11 +125,17 @@ struct mlxreg_core_item {
  * @data: instance private data;
  * @regmap: register map of parent device;
  * @counter: number of instances;
+ * @features: supported features of device;
+ * @version: implementation version;
+ * @identity: device identity name;
  */
 struct mlxreg_core_platform_data {
        struct mlxreg_core_data *data;
        void *regmap;
        int counter;
+       u32 features;
+       u32 version;
+       char identity[MLXREG_CORE_LABEL_MAX_SIZE];
 };
 
 /**