Received: by 10.223.176.5 with SMTP id f5csp1217953wra; Tue, 6 Feb 2018 15:03:40 -0800 (PST) X-Google-Smtp-Source: AH8x224nroycU67PT63yEKyEVpBcfbh93peglFkZlDCdl19IaK0zp02yIUtTZJ3FjeqxYPWby39s X-Received: by 10.98.63.142 with SMTP id z14mr3839792pfj.95.1517958220831; Tue, 06 Feb 2018 15:03:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517958220; cv=none; d=google.com; s=arc-20160816; b=FU3Nv5a1+JQtOFFTnm/LS4zeWhRqWJWeSnW3MytCRqX+eNEvkRuG72OLJUwMiqjRVw F14KfhVsdpBjzwQUwpL2v6e8R9JYyMJ5+LppGLhUfhDRpvLrxYwnmKI6rCMAefi6rEwZ g4bEVmu2vhPwaBDqQEbfbnMhEGRxwv9dGSNjoIn4pdDJFjQ/APRxsghx5PB2ui8P7qge flmH6NmyitpKDM8oP1sGY8ZJo8uh1KAbbWdvNlh62CCO1Rs3y5wAcWbtr8Gxeh1eNb6H vFy9Y/pvCEPxdz44RpeBk3yQf8BmIXiur7hTc1w1Pa3JZIe87LOyYp2DaFYcaBSeR00W A+1w== 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=43A/dstwgMkpILKMVDKSi6nh8+uhO17oZ9hh0G6TOrw=; b=G1GRrNSCHJ4LfHBTbBpA3Ci/10dJZ2usHH0zRmcOXSq/y1nvZKyVWZ1V2iTvdVTBUc JqOffWARWIYvelioyf3IOthITR3teVArDDubkrO9PbVuKE4bxwNi1e7rKoYX750VghXN fHm9Xbxnmin/YrbbsbAOHSwCTWJocGzTLB0cSe5c0+hxvGMt7B5siO4hiVhm3SCzi5Bu dwNl3ycNoQkxeyeWg7i/OeGta/VZDi1QEo9zXT3Skik/uYSm7eranHmbyf2AWdruZkMA hvdFUSpFJt1VuCFiO5g57ywSj7H0GyZ8ZXVWaLL0CyYO9m6Sav1QgsKtgEzgQn2tLP5Q UPFw== 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 28si84669pfl.53.2018.02.06.15.03.27; Tue, 06 Feb 2018 15:03:40 -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 S1753970AbeBFXBx (ORCPT + 99 others); Tue, 6 Feb 2018 18:01:53 -0500 Received: from g9t5009.houston.hpe.com ([15.241.48.73]:43952 "EHLO g9t5009.houston.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753893AbeBFXAP (ORCPT ); Tue, 6 Feb 2018 18:00:15 -0500 Received: from g9t2301.houston.hpecorp.net (g9t2301.houston.hpecorp.net [16.220.97.129]) by g9t5009.houston.hpe.com (Postfix) with ESMTP id D43C87C; Tue, 6 Feb 2018 23:00:14 +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 6DF694D; Tue, 6 Feb 2018 23:00:14 +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, Jerry Hoemann Subject: [PATCH 06/10] watchdog/hpwdt: Modify to use watchdog core. Date: Tue, 6 Feb 2018 15:58:51 -0700 Message-Id: <20180206225855.30582-7-jerry.hoemann@hpe.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180206225855.30582-1-jerry.hoemann@hpe.com> References: <20180206225855.30582-1-jerry.hoemann@hpe.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Follow Documentation/watchdog/convert_drivers_to_kernel_api.txt to convert hpwdt from legacy watchdog driver to use the watchdog core. Removed functions: hpwdt_open, hpwdt_release, hpwdt_write, hpwdt_ioctl Removed data structures: hpwdt_fops, hpwdt_miscdev, watchdog_device Modified functions: hpwdt_start, hpwdt_stop, hpwdt_ping, hpwdt_gettimeleft Added functions: hpwdt_settimeout Added structures: watchdog_device Signed-off-by: Jerry Hoemann --- drivers/watchdog/hpwdt.c | 254 ++++++++++++----------------------------------- 1 file changed, 66 insertions(+), 188 deletions(-) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 3fae3119369f..a8e5c6542406 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -14,18 +14,13 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include -#include -#include #include -#include #include #include #include -#include #include -#include #include + #include #define HPWDT_VERSION "1.4.0" @@ -38,8 +33,6 @@ static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ static unsigned int reload; /* the computed soft_margin */ static bool nowayout = WATCHDOG_NOWAYOUT; static unsigned int allow_kdump = 1; -static char expect_release; -static unsigned long hpwdt_is_open; static void __iomem *pci_mem_addr; /* the PCI-memory address */ static unsigned long __iomem *hpwdt_nmistat; @@ -53,53 +46,58 @@ static const struct pci_device_id hpwdt_devices[] = { }; MODULE_DEVICE_TABLE(pci, hpwdt_devices); +static struct watchdog_device hpwdt_dev; /* * Watchdog operations */ -static void hpwdt_start(void) +static int hpwdt_start(struct watchdog_device *dev) { - reload = SECS_TO_TICKS(soft_margin); + reload = SECS_TO_TICKS(dev->timeout); + iowrite16(reload, hpwdt_timer_reg); iowrite8(0x85, hpwdt_timer_con); + + return 0; } -static void hpwdt_stop(void) +static int hpwdt_stop(struct watchdog_device *dev) { unsigned long data; data = ioread8(hpwdt_timer_con); data &= 0xFE; iowrite8(data, hpwdt_timer_con); + return 0; } -static void hpwdt_ping(void) -{ - iowrite16(reload, hpwdt_timer_reg); -} - -static int hpwdt_change_timer(int new_margin) +static int hpwdt_ping(struct watchdog_device *dev) { - if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) { - pr_warn("New value passed in is invalid: %d seconds\n", - new_margin); - return -EINVAL; - } + reload = SECS_TO_TICKS(dev->timeout); - soft_margin = new_margin; - pr_debug("New timer passed in is %d seconds\n", new_margin); - reload = SECS_TO_TICKS(soft_margin); + iowrite16(reload, hpwdt_timer_reg); return 0; } -static int hpwdt_time_left(void) +static unsigned int hpwdt_gettimeleft(struct watchdog_device *dev) { return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); } +static int hpwdt_settimeout(struct watchdog_device *dev, unsigned int val) +{ + pr_debug("settimeout = %d\n", val); + + soft_margin = dev->timeout = val; + hpwdt_ping(dev); + + return 0; +} + #ifdef CONFIG_HPWDT_NMI_DECODING /* { */ -static int hpwdt_my_nmi(void) + +static unsigned int hpwdt_my_nmi(void) { return ioread8(hpwdt_nmistat) & 0x6; } @@ -126,8 +124,10 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) if ((ulReason == NMI_UNKNOWN) && !mynmi) return NMI_DONE; + pr_debug("nmi: ulReason=%d, mynmi=0x%0x\n", ulReason, mynmi); + if (allow_kdump) - hpwdt_stop(); + hpwdt_stop(&hpwdt_dev); panic_msg[0] = hexdigit((mynmi>>4)&0xf); panic_msg[1] = hexdigit(mynmi&0xf); @@ -138,68 +138,6 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) } #endif /* } */ -/* - * /dev/watchdog handling - */ -static int hpwdt_open(struct inode *inode, struct file *file) -{ - /* /dev/watchdog can only be opened once */ - if (test_and_set_bit(0, &hpwdt_is_open)) - return -EBUSY; - - /* Start the watchdog */ - hpwdt_start(); - hpwdt_ping(); - - return nonseekable_open(inode, file); -} - -static int hpwdt_release(struct inode *inode, struct file *file) -{ - /* Stop the watchdog */ - if (expect_release == 42) { - hpwdt_stop(); - } else { - pr_crit("Unexpected close, not stopping watchdog!\n"); - hpwdt_ping(); - } - - expect_release = 0; - - /* /dev/watchdog is being closed, make sure it can be re-opened */ - clear_bit(0, &hpwdt_is_open); - - return 0; -} - -static ssize_t hpwdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - /* See if we got the magic character 'V' and reload the timer */ - if (len) { - if (!nowayout) { - size_t i; - - /* note: just in case someone wrote the magic character - * five months ago... */ - expect_release = 0; - - /* scan to see whether or not we got the magic char. */ - for (i = 0; i != len; i++) { - char c; - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_release = 42; - } - } - - /* someone wrote to us, we should reload the timer */ - hpwdt_ping(); - } - - return len; -} static const struct watchdog_info hpwdt_info = { .options = WDIOF_SETTIMEOUT | @@ -208,92 +146,13 @@ static const struct watchdog_info hpwdt_info = { .identity = "HPE iLO2+ HW Watchdog Timer", }; -static long hpwdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - int new_margin, options; - int ret = -ENOTTY; - - switch (cmd) { - case WDIOC_GETSUPPORT: - ret = 0; - if (copy_to_user(argp, &hpwdt_info, sizeof(hpwdt_info))) - ret = -EFAULT; - break; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - ret = put_user(0, p); - break; - - case WDIOC_KEEPALIVE: - hpwdt_ping(); - ret = 0; - break; - - case WDIOC_SETOPTIONS: - ret = get_user(options, p); - if (ret) - break; - - if (options & WDIOS_DISABLECARD) - hpwdt_stop(); - - if (options & WDIOS_ENABLECARD) { - hpwdt_start(); - hpwdt_ping(); - } - break; - - case WDIOC_SETTIMEOUT: - ret = get_user(new_margin, p); - if (ret) - break; - - ret = hpwdt_change_timer(new_margin); - if (ret) - break; - - hpwdt_ping(); - /* Fall */ - case WDIOC_GETTIMEOUT: - ret = put_user(soft_margin, p); - break; - - case WDIOC_GETTIMELEFT: - ret = put_user(hpwdt_time_left(), p); - break; - } - return ret; -} - -/* - * Kernel interfaces - */ -static const struct file_operations hpwdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = hpwdt_write, - .unlocked_ioctl = hpwdt_ioctl, - .open = hpwdt_open, - .release = hpwdt_release, -}; - -static struct miscdevice hpwdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &hpwdt_fops, -}; - /* * Init & Exit */ - static int hpwdt_init_nmi_decoding(struct pci_dev *dev) { +#ifdef CONFIG_HPWDT_NMI_DECODING /* { */ int retval; /* * Only one function can register for NMI_UNKNOWN @@ -308,10 +167,7 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev) if (retval) goto error2; - dev_info(&dev->dev, - "HPE Watchdog Timer Driver: NMI decoding initialized" - ", allow kernel dump: %s (default = 1/ON)\n", - (allow_kdump == 0) ? "OFF" : "ON"); + dev_info(&dev->dev, "HPE Watchdog Timer Driver: NMI decoding initialized"); return 0; error2: @@ -323,6 +179,8 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev) "Unable to register a die notifier (err=%d).\n", retval); return retval; +#endif /* } */ + return 0; } static void hpwdt_exit_nmi_decoding(void) @@ -376,31 +234,32 @@ static int hpwdt_probe(struct pci_dev *dev, const struct pci_device_id *ent) hpwdt_timer_con = pci_mem_addr + 0x72; /* Make sure that timer is disabled until /dev/watchdog is opened */ - hpwdt_stop(); - - /* Make sure that we have a valid soft_margin */ - if (hpwdt_change_timer(soft_margin)) - hpwdt_change_timer(DEFAULT_MARGIN); + hpwdt_stop(&hpwdt_dev); /* Initialize NMI Decoding functionality */ retval = hpwdt_init_nmi_decoding(dev); if (retval != 0) goto error_init_nmi_decoding; - retval = misc_register(&hpwdt_miscdev); + retval = watchdog_register_device(&hpwdt_dev); if (retval < 0) { - dev_warn(&dev->dev, - "Unable to register miscdev on minor=%d (err=%d).\n", - WATCHDOG_MINOR, retval); - goto error_misc_register; + dev_warn(&dev->dev, "Unable to register hpe watchdog (err=%d).\n", retval); + goto error_wd_register; + } + + watchdog_set_nowayout(&hpwdt_dev, nowayout); + if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL)) { + dev_warn(&dev->dev, "Invalid soft_margin: %d. Using default\n", soft_margin); + soft_margin = DEFAULT_MARGIN; } dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s" ", timer margin: %d seconds (nowayout=%d).\n", - HPWDT_VERSION, soft_margin, nowayout); + HPWDT_VERSION, hpwdt_dev.timeout, nowayout); + return 0; -error_misc_register: +error_wd_register: hpwdt_exit_nmi_decoding(); error_init_nmi_decoding: pci_iounmap(dev, pci_mem_addr); @@ -412,9 +271,9 @@ static int hpwdt_probe(struct pci_dev *dev, const struct pci_device_id *ent) static void hpwdt_exit(struct pci_dev *dev) { if (!nowayout) - hpwdt_stop(); + hpwdt_stop(&hpwdt_dev); - misc_deregister(&hpwdt_miscdev); + watchdog_unregister_device(&hpwdt_dev); hpwdt_exit_nmi_decoding(); pci_iounmap(dev, pci_mem_addr); pci_disable_device(dev); @@ -427,6 +286,25 @@ static struct pci_driver hpwdt_driver = { .remove = hpwdt_exit, }; + +static const struct watchdog_ops hpwdt_ops = { + .owner = THIS_MODULE, + .start = hpwdt_start, + .stop = hpwdt_stop, + .ping = hpwdt_ping, + .set_timeout = hpwdt_settimeout, + .get_timeleft = hpwdt_gettimeleft, +}; + +static struct watchdog_device hpwdt_dev = { + .info = &hpwdt_info, + .ops = &hpwdt_ops, + .min_timeout = 1, + .max_timeout = HPWDT_MAX_TIMER, + .timeout = DEFAULT_MARGIN, +}; + + MODULE_AUTHOR("Jerry Hoemann"); MODULE_DESCRIPTION("hpe watchdog driver"); MODULE_LICENSE("GPL"); -- 2.13.6