Received: by 10.223.185.116 with SMTP id b49csp3302139wrg; Sun, 25 Feb 2018 19:26:00 -0800 (PST) X-Google-Smtp-Source: AH8x224KV1nONqVszIL48JoWYYAokxN0e9uk6ySaoTMxRnVOCF/r9TypRlCIZWdkQOAvZmo82trJ X-Received: by 2002:a17:902:6e8c:: with SMTP id v12-v6mr9173272plk.424.1519615559971; Sun, 25 Feb 2018 19:25:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519615559; cv=none; d=google.com; s=arc-20160816; b=k990a0yhsWoUVSvxiFGyAa/X+gRJ30F+jhcqkH6mw50+l5bvog4yKJaWFyZQa5gKBX Z2dEXVspnmACDkw/h5bSPxNp+jEIN+sdtHH1I7VfqjJGd8S4g2qRatRDcDaHsWHjcLp+ TsI4MeHh9qI1Uobauy7m+BB0aD/B65ZMEjjxK0U7+GD2FA3Jqt2OHjYeAZrTjwcZx1Vd bMMF5maJvKs2p0NfGKZBXnZ6c/gDcSAx4sfxdxR7QJipw5D/QfAasgF/1HZjpFEds1J/ OPZDHGBrqe74KjEMYnS84+V3mZwJPL1sTsLxYr6VZGoJvzNsi/37qC3knrx+hXiG2JlJ eboQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=9XmoTat0IkZ4mrze4UkUDtBmTO7SS8FQ8ubgxQM0WHk=; b=YwfGCGGcTspBbjTdNFAmH4Uoa+Dqjl6YS1ro5A54xhbEKEJTwdfCqKLI+Zjx0/Vh8Y qX7N+xCxmc88+HxVXdcBXKzWEpejUmZHZH0uy+EvZqp+1SYX0GLTQAn76pwmRImDqqp4 0dD1Rh8AvjwR1rU1nr48NLRERlYAoOsSybe7CL4MmC79OVctLYzfr4DMrt2XSWaxWZv8 BHpUN1n9H/jwBYazlmSOVNDhS0LYk2zFGGCtKSvA52868W4MI8+jXfAq94cYqCT6EUcX AwOV8/yn9PBDMYYaf0SyxqavWeCncIyjwATzVL3676SdlnDHE01XizTZ7SVa9K7Rt43i pf1g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s4si4975003pgf.390.2018.02.25.19.25.45; Sun, 25 Feb 2018 19:25:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752296AbeBZDXc (ORCPT + 99 others); Sun, 25 Feb 2018 22:23:32 -0500 Received: from g9t5008.houston.hpe.com ([15.241.48.72]:60970 "EHLO g9t5008.houston.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752150AbeBZDWg (ORCPT ); Sun, 25 Feb 2018 22:22:36 -0500 Received: from g9t2301.houston.hpecorp.net (g9t2301.houston.hpecorp.net [16.220.97.129]) by g9t5008.houston.hpe.com (Postfix) with ESMTP id 530F34D; Mon, 26 Feb 2018 03:22:35 +0000 (UTC) Received: from anatevka.ftc.rdlabs.hpecorp.net (anatevka.americas.hpqcorp.net [10.34.81.6]) by g9t2301.houston.hpecorp.net (Postfix) with ESMTP id D141D4F; Mon, 26 Feb 2018 03:22:34 +0000 (UTC) From: Jerry Hoemann To: wim@linux-watchdog.org, linux@roeck-us.net Cc: linux-watchdog@vger.kernel.org, linux-kernel@vger.kernel.org, rwright@hpe.com, maurice.a.saldivar@hpe.com, mingo@kernel.org, marcus.folkesson@gmail.com, Jerry Hoemann Subject: [PATCH v5 7/9] watchdog/hpwdt: Programable Pretimeout NMI Date: Sun, 25 Feb 2018 20:22:25 -0700 Message-Id: <20180226032227.14615-8-jerry.hoemann@hpe.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180226032227.14615-1-jerry.hoemann@hpe.com> References: <20180226032227.14615-1-jerry.hoemann@hpe.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Make whether or not the hpwdt watchdog delivers a pretimeout NMI programable by the user. The underlying iLO hardware is programmable as to whether or not a pre-timeout NMI is delivered to the system before the iLO resets the system. However, the iLO does not allow for programming the length of time that NMI is delivered before the system is reset. By watchdog API, in hpwdt_set_pretimeout a val == 0 disables the NMI. When val != 0, hpwdt_set_pretimeout will enable the pretimeout NMI provided the current timeout is greator than the HW specified pretimeout length. Otherwise an error is returned. In set_timeout, if the new timeout is <= an already established pretimeout, the pretimeout is canceled. This matches the action watchdog_set_timeout in the watchdog core would do if an hpwdt specific set_timeout function wasn't specified. Signed-off-by: Jerry Hoemann --- drivers/watchdog/hpwdt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 68e84a212d00..b8205c6e61c1 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -31,11 +31,12 @@ #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) #define DEFAULT_MARGIN 30 +#define PRETIMEOUT_SEC 9 static bool ilo5; static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ -static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; +static bool pretimeout = IS_ENABLED(CONFIG_HPWDT_NMI_DECODING); static void __iomem *pci_mem_addr; /* the PCI-memory address */ static unsigned long __iomem *hpwdt_nmistat; @@ -55,10 +56,11 @@ MODULE_DEVICE_TABLE(pci, hpwdt_devices); */ static int hpwdt_start(struct watchdog_device *wdd) { - reload = SECS_TO_TICKS(wdd->timeout); + int control = 0x81 | (pretimeout ? 0x4 : 0); + int reload = SECS_TO_TICKS(wdd->timeout); iowrite16(reload, hpwdt_timer_reg); - iowrite8(0x85, hpwdt_timer_con); + iowrite8(control, hpwdt_timer_con); return 0; } @@ -81,7 +83,10 @@ static int hpwdt_stop_core(struct watchdog_device *wdd) static int hpwdt_ping(struct watchdog_device *wdd) { + int reload = SECS_TO_TICKS(wdd->timeout); + iowrite16(reload, hpwdt_timer_reg); + return 0; } @@ -93,12 +98,37 @@ static unsigned int hpwdt_gettimeleft(struct watchdog_device *wdd) static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) { wdd->timeout = val; + if (val <= wdd->pretimeout) { + wdd->pretimeout = 0; + pretimeout = 0; + if (watchdog_active(wdd)) + hpwdt_start(wdd); + } hpwdt_ping(wdd); return 0; } #ifdef CONFIG_HPWDT_NMI_DECODING +static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req) +{ + unsigned int val = 0; + + if (req) { + val = PRETIMEOUT_SEC; + if (val >= wdd->timeout) + return -EINVAL; + } + + wdd->pretimeout = val; + pretimeout = !!val; + + if (watchdog_active(wdd)) + hpwdt_start(wdd); + + return 0; +} + static int hpwdt_my_nmi(void) { return ioread8(hpwdt_nmistat) & 0x6; @@ -121,6 +151,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) if (ilo5 && ulReason == NMI_UNKNOWN && mynmi) return NMI_DONE; + if (ilo5 && !pretimeout) + return NMI_DONE; + hpwdt_stop(); hex_byte_pack(panic_msg, mynmi); @@ -132,7 +165,8 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) static const struct watchdog_info ident = { - .options = WDIOF_SETTIMEOUT | + .options = WDIOF_PRETIMEOUT | + WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .identity = "HPE iLO2+ HW Watchdog Timer", @@ -149,6 +183,9 @@ static const struct watchdog_ops hpwdt_ops = { .ping = hpwdt_ping, .set_timeout = hpwdt_settimeout, .get_timeleft = hpwdt_gettimeleft, +#ifdef CONFIG_HPWDT_NMI_DECODING + .set_pretimeout = hpwdt_set_pretimeout, +#endif }; static struct watchdog_device hpwdt_dev = { @@ -157,6 +194,9 @@ static struct watchdog_device hpwdt_dev = { .min_timeout = 1, .max_timeout = HPWDT_MAX_TIMER, .timeout = DEFAULT_MARGIN, +#ifdef CONFIG_HPWDT_NMI_DECODING + .pretimeout = PRETIMEOUT_SEC, +#endif }; @@ -317,4 +357,9 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +#ifdef CONFIG_HPWDT_NMI_DECODING +module_param(pretimeout, bool, 0); +MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout enabled"); +#endif + module_pci_driver(hpwdt_driver); -- 2.13.6