Received: by 10.223.185.116 with SMTP id b49csp994723wrg; Fri, 16 Feb 2018 10:28:56 -0800 (PST) X-Google-Smtp-Source: AH8x227SRYR/lELY/5kz15Lh/622oJpIMA6SQfqiSF25WRf2AZuXVd7LnAQuKymmF3TR46CvZmSb X-Received: by 10.99.117.26 with SMTP id q26mr6056780pgc.46.1518805736000; Fri, 16 Feb 2018 10:28:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518805735; cv=none; d=google.com; s=arc-20160816; b=UxMy/mHfw+aA9SXT8QBHRH9LRD5vrdXH/37UAtBV3eB2K3KJYLKl7vlVSAqsSFumKd lzw2j84JH0o4qYDHV2jJ9bWbHkT5Lot9G2CMBL/ihjqkUCBaUGjFq5GhpE5Or/vG8jzj SGPuZuMAAm3eHlNCGt5mC7P7q7G9gpp1JiN8pA0DPKD7lEAxLVwmVBw4KsHbpFFIuYlw VUNNtAH8g734jqPf48f2roGmLQhOkxmvw9epPutgZGjDAZYd1cFdDFfppylKFRLY6kp6 1z2GMKYPu7imMz34+GkCwOvId3mdCmyHSgww7QhwdFEgdjljfRiQIoclFRlQajGnFrLu 20fg== 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=tc/ZsD+rGHDLrHAgK+DZuYv7GzsvCQzFbmLrZYcmzJA=; b=H9UaJy3P8J9kyUUyM/Lek/+U7G2uNaSKr3KzWVJVa3oIG2pDJ852ijQUgvRvDpvaa0 lKONtbQ+e3qy9mcIAvCX8guwhazybgg5cVzG2eI1ZF2D+Q7wIR+ib6JDeWIFsQb041h4 BicImaRad9dkDGmxcTCiHR1o5Yz5NhfOp2m50M8LQmY7NOArEHXVxRfXFnoHbfmxkDWS K55B2pZ4RZas2to1t7VIhrM482//QoZoK0q/5v172vCoanECWwD0bnCpzAMIfSQO3bjT 0bAKnv6pKAGJHLejCwzAAiW8dwwuLoVhTb0E3ylX56JuZLUZp8UmPBe8bwJolYG0rrwP YtsA== 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 q9si183782pgn.210.2018.02.16.10.28.41; Fri, 16 Feb 2018 10:28:55 -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 S1167565AbeBOXqS (ORCPT + 99 others); Thu, 15 Feb 2018 18:46:18 -0500 Received: from g2t2352.austin.hpe.com ([15.233.44.25]:52529 "EHLO g2t2352.austin.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1167467AbeBOXpD (ORCPT ); Thu, 15 Feb 2018 18:45:03 -0500 Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2352.austin.hpe.com (Postfix) with ESMTP id 1725FA7; Thu, 15 Feb 2018 23:45:03 +0000 (UTC) Received: from anatevka.ftc.rdlabs.hpecorp.net (anatevka.americas.hpqcorp.net [10.34.81.6]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id 9720537; Thu, 15 Feb 2018 23:45:02 +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 v3 07/11] watchdog/hpwdt: Modify to use watchdog core. Date: Thu, 15 Feb 2018 16:43:56 -0700 Message-Id: <20180215234400.5022-8-jerry.hoemann@hpe.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180215234400.5022-1-jerry.hoemann@hpe.com> References: <20180215234400.5022-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 | 249 ++++++++++++----------------------------------- 1 file changed, 63 insertions(+), 186 deletions(-) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 71e49d0ab789..da9a04101814 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) +{ + dev_dbg(dev->parent, "settimeout = %d\n", val); + + 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; } @@ -123,8 +121,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); hex_byte_pack(panic_msg, mynmi); nmi_panic(regs, panic_msg); @@ -133,68 +133,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 | @@ -203,90 +141,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 /* { */ @@ -373,32 +231,32 @@ static int hpwdt_probe(struct pci_dev *dev, const struct pci_device_id *ent) hpwdt_timer_reg = pci_mem_addr + 0x70; 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); - /* Initialize NMI Decoding functionality */ retval = hpwdt_init_nmi_decoding(dev); if (retval != 0) goto error_init_nmi_decoding; - retval = misc_register(&hpwdt_miscdev); + hpwdt_dev.parent = &dev->dev; + 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; } + /* Make sure that timer is disabled until /dev/watchdog is opened */ + hpwdt_stop(&hpwdt_dev); + + 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); + 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); @@ -410,9 +268,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); @@ -425,6 +283,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