Received: by 10.223.185.116 with SMTP id b49csp1853363wrg; Sun, 11 Feb 2018 23:11:13 -0800 (PST) X-Google-Smtp-Source: AH8x226mFJxUZA/ABVMe+k/UIid6EiUQgKinO1Ap+K+nPnTrtF+CQGTOCjzQ893Y2iM7ATdAic0E X-Received: by 10.101.86.137 with SMTP id v9mr8580979pgs.353.1518419473625; Sun, 11 Feb 2018 23:11:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518419473; cv=none; d=google.com; s=arc-20160816; b=Ak1ySBpZlUYxm5lEZZ0xcDJYTfTGn/GncI3v6hRENYsC8cXtUwp6hGBXw2sTJdJLEF Q8N8DakFx5WPboSYM+FDKBnMkE5WcrVB46aLpOtzgaxFNrPhtCMHr3UnJ8qYdGdUKCrP xuqCNprx6cMYrWGSi5B6tfkvrqb6WntJCYLJbWnp6f9rUQl1G9U/KJFQ2kLYCcK8vnK0 eLDviSC1qe2GXVUghMh9mX92ALg0VnupsoSn8t8CtVuGgaeXpBH1GpY3Zcm917JinmEB /PjUOb5VI5LVgzzwPM8tvLh0D0nhEJH5AxkFRssiASg/ldbZMhKiOgxfJOFzb/vxnUGh xb1g== 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=MWNZX3DpnJUs9Ny5aV200p3L161rlr+WR4asIA0oyPc=; b=xBz6J+qs0Nqg+8Z7WTKql04do/2TyILXBqACuEhhQWxmHbAoLnhHvd58+qRbUGKWLL O0L3pW42voKkpPOP9r7FcXFC2Xnks4ZiB9v+aiyG7c9YSDxevyR7IC6cOUCrAwS8MhSk AYTjVrKKD4P97NyYfXoqCplNQfZBjn8poVUZCNuS3jEFdrrEAzGx5+fFVqhW8dQTfNmO tubvTGc6fgudS25wNxz06c1/CblxfxbrhTa5sJPXc179leD8m+XtO+oNWNEkMziaOD7q iJrEDERwRrwxScTbFPHJMxfun/o+POvfJ3Fvf4UjExepPfeEw1+YolhGvTHlaY7qfjn2 ZBRg== 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 k1si53306pfa.177.2018.02.11.23.10.23; Sun, 11 Feb 2018 23:11:13 -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 S932824AbeBLFXY (ORCPT + 99 others); Mon, 12 Feb 2018 00:23:24 -0500 Received: from g2t1383g.austin.hpe.com ([15.233.16.89]:56869 "EHLO g2t1383g.austin.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751259AbeBLFW1 (ORCPT ); Mon, 12 Feb 2018 00:22:27 -0500 Received: from g4t3425.houston.hpe.com (g4t3425.houston.hpe.com [15.241.140.78]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g2t1383g.austin.hpe.com (Postfix) with ESMTPS id BF1CDB37; Mon, 12 Feb 2018 05:22:25 +0000 (UTC) Received: from g9t2301.houston.hpecorp.net (g9t2301.houston.hpecorp.net [16.220.97.129]) by g4t3425.houston.hpe.com (Postfix) with ESMTP id E3207AC; Mon, 12 Feb 2018 05:22:24 +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 7F4B54C; Mon, 12 Feb 2018 05:22:24 +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 v2 06/11] watchdog/hpwdt: Modify to use watchdog core. Date: Sun, 11 Feb 2018 22:21:06 -0700 Message-Id: <20180212052111.12010-7-jerry.hoemann@hpe.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180212052111.12010-1-jerry.hoemann@hpe.com> References: <20180212052111.12010-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 | 251 ++++++++++++----------------------------------- 1 file changed, 63 insertions(+), 188 deletions(-) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index dead59f9ca80..740d0c633204 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" @@ -40,8 +35,6 @@ static bool nowayout = WATCHDOG_NOWAYOUT; #ifdef CONFIG_HPWDT_NMI_DECODING static unsigned int allow_kdump = 1; #endif -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; @@ -55,53 +48,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; } @@ -128,8 +126,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); @@ -140,68 +140,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 | @@ -210,90 +148,10 @@ 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 /* { */ @@ -311,10 +169,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: @@ -381,31 +236,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); @@ -417,9 +273,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); @@ -432,6 +288,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