Received: by 10.223.185.116 with SMTP id b49csp3089132wrg; Sun, 25 Feb 2018 13:36:39 -0800 (PST) X-Google-Smtp-Source: AH8x226Q4s7mf5zybm49VYW9OsTwW6nuGpetSYlNzi+Gxo6N1EHeUgSKKGag+zWYrm1ikRMS2FBt X-Received: by 2002:a17:902:584c:: with SMTP id f12-v6mr8471702plj.374.1519594599259; Sun, 25 Feb 2018 13:36:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519594599; cv=none; d=google.com; s=arc-20160816; b=RttFwLterlzvxPaUTbFwJAgmVQWpijo+FTkQA/w7K8vffwCFiK7dJFePqlkxvFKVAZ ihYCNd2dN21UmLs2DwFE7RT9KB456WuA+j3N8/ryJbbRXVcgBVoOiYbFtBqlF5HIF8ac /mNxSL8Qtk1GaxcXhThq83XYOItRR9Pbq2gEiNrleIBOsvZs5fKwjnXyCIbWHlBIEibE /gVWFTfAOjGlySMCtOho0vRKBgYU9Dkh2hLIeIHTDEadQDIJHsCmlYWlKVmvP1ylA5kR nFEWaL096QNnvWGI7wRyEKo8IiUWXcEyErCaOZdfCFzKFVudHMZuJKPxSiB4jWxT5cN3 /W8g== 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=lsKIpuQeNKdcCswHloHD2lFJuu7dEI4gjioVI9bsbEU=; b=HXVAs8Z88IUq3Ng47/aYJ+XgBJhUxw+J294EIzAFMDLeS4/D+WHqlaElyNVwFUyM0t MKFDCUHfiGHwSt8BB1aPyFh9cvCDd9gJwsgldmpmnjoAYSdgVwyo5huF61J0bSUjfxFZ 2qqYWfY6y37pLTsvLMpHMriIaYDKn0OMHQuH6JdpnGjy+tohLfUnO8sg506QorYyg4os zpZjVat4L/KmlYopZYjcjYX9VQbNkz8abgWqpQIzLw8ky9nBy4pJenlYhIlU8/Qwp52S DsN0bv9lUUH+XundxmEIziqx3Zt6Mcvrmku4tQS99VEDmxGagX1j2MR5AizntDkqGBiK 7jcw== 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 r2si4593303pgp.704.2018.02.25.13.36.24; Sun, 25 Feb 2018 13:36:39 -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 S1752012AbeBYVdy (ORCPT + 99 others); Sun, 25 Feb 2018 16:33:54 -0500 Received: from g9t5008.houston.hpe.com ([15.241.48.72]:39188 "EHLO g9t5008.houston.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751945AbeBYVdo (ORCPT ); Sun, 25 Feb 2018 16:33:44 -0500 Received: from g4t3433.houston.hpecorp.net (g4t3433.houston.hpecorp.net [16.208.49.245]) by g9t5008.houston.hpe.com (Postfix) with ESMTP id 40C454D; Sun, 25 Feb 2018 21:33:43 +0000 (UTC) Received: from anatevka.ftc.rdlabs.hpecorp.net (anatevka.americas.hpqcorp.net [10.34.81.6]) by g4t3433.houston.hpecorp.net (Postfix) with ESMTP id BAC4E4B; Sun, 25 Feb 2018 21:33:42 +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 v4 08/10] watchdog/hpwdt: Programable Pretimeout NMI Date: Sun, 25 Feb 2018 14:32:57 -0700 Message-Id: <20180225213259.2861-9-jerry.hoemann@hpe.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180225213259.2861-1-jerry.hoemann@hpe.com> References: <20180225213259.2861-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 a584ccf05202..be7b3edac56c 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; } @@ -94,12 +99,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; @@ -122,6 +152,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); @@ -133,7 +166,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", @@ -150,6 +184,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 = { @@ -158,6 +195,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 }; @@ -319,4 +359,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