From patchwork Thu Oct 5 08:51:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenkai X-Patchwork-Id: 13410057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18058E9371D for ; Thu, 5 Oct 2023 13:56:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229611AbjJENzx (ORCPT ); Thu, 5 Oct 2023 09:55:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243728AbjJENtD (ORCPT ); Thu, 5 Oct 2023 09:49:03 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0193A93D0; Thu, 5 Oct 2023 01:52:11 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-690bd8f89baso569810b3a.2; Thu, 05 Oct 2023 01:52:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696495930; x=1697100730; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jIyP9FGLHDdotVle9KkMUcCQfjZGob1ifbnnnZcJG2c=; b=fT/UPpPl2B9BkfA+i+pCZ7oIK6jXZ6cVCXUTGAOhogvs2hEKFVOaNZyukfBzczCnsf uZvNVdtaRp8qJ9hbgOd6dW3N59exZKeWHtL2iUsK1EgK/uRI8i49Wz22v/JTYGCFL3Vg zDDKx5zCf8vSd1De8T/gkGg2SKAQ5oEplCsA59+hPCNrd8huANLGfIzBOCEDAzw8cTNF 3uT2eOGx6xXKOsUXhX5X+ohkYku8ntjiGoVHZh+f0Lt1OVgVOwwI2KzSD7uRxG928pth q7l3tVm9MmjN8tgCyLRLGkMNcdPunh2orltfFSvQn61//FWVEVwJttBxQITK4CoHc4TM rIog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696495930; x=1697100730; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jIyP9FGLHDdotVle9KkMUcCQfjZGob1ifbnnnZcJG2c=; b=hThXKWx+bU7ROWjSKwtP+qBYMioxH5k+0te28v0pFIhhL68Km6PDpeAVboWMQLV/rm MVVl9saEl9pOKRff+kR8M+utuYRsAQInu8cphm970NjPEEl2Hieltt6ceSqQmAYCWhNO GN4IetiG5ZNNlYph1ZzMCdXOPzc8DJTmMbo/uVkjQpWleNJ3uX2KTGpxS1osJVYk3ATj XBM0R9tGyf8HxD0/CmokuFx5DTXjTzwdwQA51vdv4c86ZTx0Bf9fMVShabzTVpFuMWfY djNe8MMofTMQpg1cJcLn8bxF/Ch7MC0QsIQeLVHLB8bXdJ0wORNFWhBRjQg5JcQmS4bO UdKA== X-Gm-Message-State: AOJu0YyahfLWuZGuCpp5AgVEwG8DQlQAAN0Y02r1tQkSBv9L2y/S0XSA eFdArFUdfZyE39P/cLx4bAH09Lu2iKvtnQ== X-Google-Smtp-Source: AGHT+IHRe8y1VtpH5ZcQKqlSFq+oDdJTBvmplz9WTmoiYdbTUe182GPvvFf4kQznuqOp58MTWGrQ9w== X-Received: by 2002:a05:6a20:12d6:b0:15d:bc0f:9b64 with SMTP id v22-20020a056a2012d600b0015dbc0f9b64mr5333019pzg.45.1696495929893; Thu, 05 Oct 2023 01:52:09 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id b19-20020a170902ed1300b001c737950e4dsm1066781pld.2.2023.10.05.01.52.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 01:52:09 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Wim Van Sebroeck , Guenter Roeck , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org Subject: [PATCH 1/5] watchdog: eiois200_wdt: Constructing Advantech EIO-IS200 watchdog driver Date: Thu, 5 Oct 2023 16:51:19 +0800 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Wenkai This is the initial patch that adds the Advantech EIO-IS200 Watchdog Driver to the kernel. It includes the necessary Makefile and Kconfig entries to integrate the driver with the watchdog framework. However, please note that this patch does not yet implement the actual watchdog functionality. When configuring the kernel using tools like menuconfig, as all other eiois200 series drivers, it cannot be selected Y as built in, you can select M to build it as a module or select N to exclude it. Please also be aware that this driver is a sub-driver of `drivers/mfd/eiois200_core`. Therefore, it is required for the proper compilation of the Advantech EIO-IS200 support. Failing to include this driver may result in compilation errors. Signed-off-by: Wenkai --- drivers/watchdog/Kconfig | 14 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/eiois200_wdt.c | 124 ++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 drivers/watchdog/eiois200_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index ee97d89dfc11..218c90714830 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1079,6 +1079,20 @@ config ADVANTECH_EC_WDT This driver supports Advantech products with ITE based Embedded Controller. It does not support Advantech products with other ECs or without EC. +config EIOIS200_WDT + tristate "Advantech EIO IS-200 Watchdog Timer" + depends on X86 && m + default m + select MFD_EIOIS200 + help + This is the driver for the hardware watchdog on the EIO IS-200 EC + chip as used in Advantech boards (and likely others). + + To compile this driver as a module, choose M here: the module will + be called eiois200_wdt. + + Most people will say M. + config ALIM1535_WDT tristate "ALi M1535 PMU Watchdog Timer" depends on X86 && PCI diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 3633f5b98236..713872a4f7de 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o obj-$(CONFIG_ADVANTECH_EC_WDT) += advantech_ec_wdt.o +obj-$(CONFIG_EIOIS200_WDT) += eiois200_wdt.o obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o obj-$(CONFIG_EBC_C384_WDT) += ebc-c384_wdt.o diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c new file mode 100644 index 000000000000..bf132a75a2ec --- /dev/null +++ b/drivers/watchdog/eiois200_wdt.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Advantech EIO-IS200 Watchdog Driver + * + * Copyright (C) 2023 Advantech Co., Ltd. + * Author: wenkai + */ + +#include +#include +#include +#include + +#include "../mfd/eiois200.h" + +#define WATCHDOG_TIMEOUT 60 +#define WATCHDOG_PRETIMEOUT 10 + +static struct _wdt { + u32 support; + long last_time; + struct regmap *iomap; + struct device *dev; +} wdt; + +/* Pointer to the eiois200_core device structure */ +static struct eiois200_dev *eiois200_dev; + +static struct watchdog_info wdinfo = { + .identity = KBUILD_MODNAME, + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, +}; + +static struct watchdog_device wddev = { + .info = &wdinfo, + .max_timeout = 0x7FFF, + .min_timeout = 1, +}; + +static int wdt_set_timeout(struct watchdog_device *dev, + unsigned int _timeout) +{ + dev->timeout = _timeout; + dev_dbg(wdt.dev, "Set timeout: %d\n", _timeout); + + return 0; +} + +static int wdt_start(struct watchdog_device *dev) +{ + return 0; +} + +static int wdt_stop(struct watchdog_device *dev) +{ + return 0; +} + +static int wdt_ping(struct watchdog_device *dev) +{ + return 0; +} + +static unsigned int wdt_get_timeleft(struct watchdog_device *dev) +{ + return 0; +} + +static const struct watchdog_ops wdt_ops = { + .owner = THIS_MODULE, + .start = wdt_start, + .stop = wdt_stop, + .ping = wdt_ping, + .set_timeout = wdt_set_timeout, + .get_timeleft = wdt_get_timeleft, +}; + +static int wdt_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + + /* Contact eiois200_core */ + eiois200_dev = dev_get_drvdata(dev->parent); + if (!eiois200_dev) + return dev_err_probe(dev, ret, + "Error contact eiois200_core %d\n", ret); + + wdt.dev = dev; + wdt.iomap = dev_get_regmap(dev->parent, NULL); + if (!wdt.iomap) + return dev_err_probe(dev, -ENOMEM, "Query parent regmap fail\n"); + + /* Inform watchdog info */ + wddev.ops = &wdt_ops; + ret = watchdog_init_timeout(&wddev, wddev.timeout, dev); + if (ret) + return dev_err_probe(dev, ret, "Init timeout fail\n"); + + watchdog_stop_on_reboot(&wddev); + + watchdog_stop_on_unregister(&wddev); + + /* Register watchdog */ + ret = devm_watchdog_register_device(dev, &wddev); + if (ret) + return dev_err_probe(dev, ret, + "Cannot register watchdog device (err: %d)\n", + ret); + + return 0; +} + +static struct platform_driver eiois200_wdt_driver = { + .driver = { + .name = "eiois200_wdt", + }, +}; +module_platform_driver_probe(eiois200_wdt_driver, wdt_probe); + +MODULE_AUTHOR("wenkai "); +MODULE_DESCRIPTION("Watchdog interface for Advantech EIO-IS200 embedded controller"); +MODULE_LICENSE("GPL"); From patchwork Thu Oct 5 08:51:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenkai X-Patchwork-Id: 13410113 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8912AE9270A for ; Thu, 5 Oct 2023 14:18:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231754AbjJEOS3 (ORCPT ); Thu, 5 Oct 2023 10:18:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244418AbjJENxe (ORCPT ); Thu, 5 Oct 2023 09:53:34 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18FFF93D2; Thu, 5 Oct 2023 01:52:15 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1c5c91bece9so5436955ad.3; Thu, 05 Oct 2023 01:52:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696495934; x=1697100734; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zgM5ckKPxNB77t1sRiLlpy3j0VyAqto+yLSEBB/aNRg=; b=BNSXk1jGkIh2FykCW3jyKH1DLljKVV/vo0OuYJ+hpWYw6/WAoSZqdfLgXu/u/ZNW8U g05XbCIwqNasy4Z2vk9a51BWV9PBJXMY1mfwThOo+cCA9x0m0MT6B4DJI1DBKoCGtRah TpCjjCgAMWLUw7iIuuYFnXtMpXpnMNLfS0epzQmPz184gw4pTFq62+UPXtJJeSIToaiI JmCu5j4yv29QbYViBTg+eTHy8IlNr9/JHQoueC5pEKhbrAveEeUp3qhKBxBnw5/trs1o icIPjX3s/NgF0n3djkhk8JZu95u2fx936596KkflHSg+WcKets0QuKN3puAtTxEnTa04 heZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696495934; x=1697100734; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zgM5ckKPxNB77t1sRiLlpy3j0VyAqto+yLSEBB/aNRg=; b=wMbd2tVQ1K0EOGUsJHxKqpE+kzfsLEPO7jLiT/oZuKOZu4KEs67EImcZtNGEJ2qhsP CGCgsRoAOfRomUwPR/PJZTWQecOp5KYxwob3au8dRNA9JcFZyNafNquj0ycQAqZYp0fw 8Mj/1IDJh3Bs7hKMRqd63DBo/dzqtKx3vgF48mvveqBMWpiJbohLYxSTcLsL6v5WXY6p Zvnp5yOVLjYnzNYNrEqr12c78MbOZw9OF9lVq88r5zdMTFykkW0qB4DsO1NXDEAXwZbs RzbgaL+eaxrzgUzjQcXNAXnqYgUjhnvtnhQqPD2RwsZuaqCj7FP6p/oK324MkaMnplnO 4Dvg== X-Gm-Message-State: AOJu0YxF2puC02EGF+FxgUUknptYWcUTsd1f22bOuiDiD5LcY9neZdNc gKc53x15fZETYhUYzn8Z673oxKOf7MCNZg== X-Google-Smtp-Source: AGHT+IHaquDPsukG6jJq108ZBRy06PSDfaFfZOEMKm3D8kLZf8yJt6ZNQ2ty+aXqa8AoHdUElL3Ogg== X-Received: by 2002:a17:902:e883:b0:1c6:19da:b29f with SMTP id w3-20020a170902e88300b001c619dab29fmr5291623plg.26.1696495934010; Thu, 05 Oct 2023 01:52:14 -0700 (PDT) Received: from wenkaidev ([123.51.235.123]) by smtp.gmail.com with ESMTPSA id h19-20020a170902f7d300b001bc59cd718asm1058645plw.278.2023.10.05.01.52.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 01:52:13 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Wim Van Sebroeck , Guenter Roeck , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org Subject: [PATCH 2/5] watchdog: eiois200_wdt: Add PMC support with eiois200_core. Date: Thu, 5 Oct 2023 16:51:20 +0800 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Wenkai All eiois200 series driver functionalities are based on PMC (Peripheral Management Controller) communication. This patch enables communication between the driver and the eiois200_core. However, this version does not yet implement the watchdog timer's functionality. Signed-off-by: Wenkai --- drivers/watchdog/eiois200_wdt.c | 114 ++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c index bf132a75a2ec..ce4435ac62f2 100644 --- a/drivers/watchdog/eiois200_wdt.c +++ b/drivers/watchdog/eiois200_wdt.c @@ -16,6 +16,40 @@ #define WATCHDOG_TIMEOUT 60 #define WATCHDOG_PRETIMEOUT 10 +/* Support Flags */ +#define SUPPORT_AVAILABLE BIT(0) +#define SUPPORT_RESET BIT(7) + +/* PMC registers */ +#define REG_STATUS 0x00 +#define REG_CONTROL 0x02 +#define REG_EVENT 0x10 +#define REG_RESET_EVENT_TIME 0x14 +#define REG_IRQ_NUMBER 0x17 + +/* PMC command and control */ +#define CMD_WDT_WRITE 0x2A +#define CMD_WDT_READ 0x2B +#define CTRL_STOP 0x00 +#define CTRL_START 0x01 +#define CTRL_TRIGGER 0x02 + +/* I/O register and its flags */ +#define IOREG_UNLOCK 0x87 +#define IOREG_LOCK 0xAA +#define IOREG_LDN 0x07 +#define IOREG_LDN_PMCIO 0x0F +#define IOREG_IRQ 0x70 +#define IOREG_WDT_STATUS 0x30 + +/* Flags */ +#define FLAG_WDT_ENABLED 0x01 +#define FLAG_TRIGGER_IRQ BIT(4) + +/* PMC read and write a value */ +#define PMC_WRITE(cmd, data) pmc(CMD_WDT_WRITE, cmd, data) +#define PMC_READ(cmd, data) pmc(CMD_WDT_READ, cmd, data) + static struct _wdt { u32 support; long last_time; @@ -47,6 +81,48 @@ static int wdt_set_timeout(struct watchdog_device *dev, return 0; } +static int pmc(u8 cmd, u8 ctrl, void *payload) +{ + struct pmc_op op = { + .cmd = cmd, + .control = ctrl, + .size = ctrl <= REG_EVENT ? 1 : + ctrl >= REG_IRQ_NUMBER ? 1 : 4, + .payload = payload, + }; + + return eiois200_core_pmc_operation(wdt.dev, &op); +} + +static int get_time(u8 ctrl, u32 *val) +{ + int ret; + + ret = PMC_READ(ctrl, val); + + /* ms to sec */ + *val /= 1000; + + return ret; +} + + +static int wdt_get_config(void) +{ + int ret; + u32 reset_time; + + /* Get Reset Time */ + ret = get_time(REG_RESET_EVENT_TIME, &reset_time); + if (ret) + return ret; + + dev_info(wdt.dev, "Timeout H/W default timeout: %d secs\n", reset_time); + wddev.timeout = reset_time; + + return 0; +} + static int wdt_start(struct watchdog_device *dev) { return 0; @@ -67,6 +143,40 @@ static unsigned int wdt_get_timeleft(struct watchdog_device *dev) return 0; } +static int wdt_support(void) +{ + u8 support; + + if (PMC_READ(REG_STATUS, &support)) + return -EIO; + + if ((support & SUPPORT_AVAILABLE) == 0) + return -EIO; + + /* Must support reset */ + if ((support & SUPPORT_RESET) != SUPPORT_RESET) + return -EIO; + + /* Must has support event **/ + wdt.support = support; + + return 0; +} +static int wdt_init(struct device *dev) +{ + int ret = 0; + + ret = wdt_support(); + if (ret) + return ret; + + ret = wdt_get_config(); + if (ret) + return ret; + + return ret; +} + static const struct watchdog_ops wdt_ops = { .owner = THIS_MODULE, .start = wdt_start, @@ -91,6 +201,10 @@ static int wdt_probe(struct platform_device *pdev) wdt.iomap = dev_get_regmap(dev->parent, NULL); if (!wdt.iomap) return dev_err_probe(dev, -ENOMEM, "Query parent regmap fail\n"); + + /* Initialize EC watchdog */ + if (wdt_init(dev)) + return dev_err_probe(dev, -EIO, "wdt_init fail\n"); /* Inform watchdog info */ wddev.ops = &wdt_ops; From patchwork Thu Oct 5 08:51:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenkai X-Patchwork-Id: 13410134 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3557E92707 for ; Thu, 5 Oct 2023 14:30:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233041AbjJEO3j (ORCPT ); Thu, 5 Oct 2023 10:29:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233972AbjJEO1v (ORCPT ); Thu, 5 Oct 2023 10:27:51 -0400 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E557893D4; Thu, 5 Oct 2023 01:52:18 -0700 (PDT) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-694ed847889so592865b3a.2; Thu, 05 Oct 2023 01:52:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696495938; x=1697100738; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xl5VP0Ue06tT2oZw2pmITNbqF1XXDB7xjU0jlwfhUG8=; b=Z7Y0jjl/BPXvAY2fmEa9YeYoa9tnw+P9lTgf733kjNIyWRwXZiuDz4D1L5gvyyW0at phZC9AZGudyrxYtSVbZwzYnI/r3xcOZWwb1oT8x3TpweotFDowuR9viWB5RfmICvJtum aLS9OPmtGlHsmmUl07fmLMFXjQ1/N5itzRGReCNsJd9QdaOyrKa5qoYA+YVa5eS3OgUf dBxm6BzvJEX/jsiTHzr6BfRaIXyo0zkStZo/Fsfy8IQtOX9mChikfEPTuZ3gl1PrXn7+ y/rMYLyuEvIBpkMm6wgSPOphKYUEEKtwAMoV5NalMlvhoxqWE45xCnq1BPnpkSCHX2uv f/aA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696495938; x=1697100738; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xl5VP0Ue06tT2oZw2pmITNbqF1XXDB7xjU0jlwfhUG8=; b=DkAfFEeFTAdxJvCoVI2WxBHJnap7Q+mVGjC32mjvmhPlfGGnBklXQASGfHwh8/qJzq k/wTslGs1BoKB1Ad1jYMDtblHoHOYLVqM3uk2ntEk+vDl9F1Tx1S/gcz07+s6jM8fvNp 2wUBHofE+hwQ6HQOQF0v5Vx9HgsNfUw1+jCynu68VqfHquqMY9TFk2Wflye6SbM4OutB YTvIwfggl9XWKYCxDsYCabQnqp3dsvge9Mqm/rJCZ+6zISr3zPPXkckTNNgWraLIyehN opXS6D9tBjyIw4ZYRWZJFoGPd0/YkgS6K10y7Yv9T+MAyAKm78jgKXQERCO3IbSZONNU V+7A== X-Gm-Message-State: AOJu0Yy2GlAzRMvaJ9vt+zmeBHFghpUGBpsvI0IBzZh7XxfioAxLkUIh BUOCyPAhN4EKD2IiKp7+Ox/btdeY3bH+Xw== X-Google-Smtp-Source: AGHT+IFWb3e8Qkv9Al2zbLz4MisKt24rRWCU4okXfthP2HIKN0R3OMVQAY1CGJPlRYGVGR1qNxRjzg== X-Received: by 2002:a05:6a00:a08:b0:691:2d4:23a2 with SMTP id p8-20020a056a000a0800b0069102d423a2mr5430428pfh.31.1696495937915; Thu, 05 Oct 2023 01:52:17 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id p20-20020aa78614000000b006933f657db3sm872773pfn.21.2023.10.05.01.52.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 01:52:17 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Wim Van Sebroeck , Guenter Roeck , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org Subject: [PATCH 3/5] watchdog: eiois200_wdt: Implement basic watchdog functionalities Date: Thu, 5 Oct 2023 16:51:21 +0800 Message-Id: <61d7009003a08d47a3e5efc2906eb2e76d02cdb3.1696495372.git.advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Wenkai In this patch, the driver has been extended to include basic watchdog functionality, allowing users to configure the watchdog timeout duration, start and stop the watchdog timer, and ping it to prevent system resets. The driver also reports the remaining time until a watchdog reset is triggered. Signed-off-by: Wenkai --- drivers/watchdog/eiois200_wdt.c | 64 ++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c index ce4435ac62f2..569e619448e5 100644 --- a/drivers/watchdog/eiois200_wdt.c +++ b/drivers/watchdog/eiois200_wdt.c @@ -106,6 +106,29 @@ static int get_time(u8 ctrl, u32 *val) return ret; } +static int set_time(u8 ctl, u32 time) +{ + /* sec to sec */ + time *= 1000; + + return PMC_WRITE(ctl, &time); +} + +static int wdt_set_config(void) +{ + int ret; + u32 reset_time = 0; + + reset_time = wddev.timeout; + + ret = set_time(REG_RESET_EVENT_TIME, reset_time); + if (ret) + return ret; + + dev_info(wdt.dev, "Config wdt reset time %d\n", reset_time); + + return ret; +} static int wdt_get_config(void) { @@ -123,24 +146,57 @@ static int wdt_get_config(void) return 0; } +static int set_ctrl(u8 data) +{ + return PMC_WRITE(REG_CONTROL, &data); +} + static int wdt_start(struct watchdog_device *dev) { - return 0; + int ret; + + ret = wdt_set_config(); + if (ret) + return ret; + + ret = set_ctrl(CTRL_START); + if (ret == 0) { + wdt.last_time = jiffies; + dev_dbg(wdt.dev, "Watchdog started\n"); + } + + return ret; } static int wdt_stop(struct watchdog_device *dev) { - return 0; + dev_dbg(wdt.dev, "Watchdog stopped\n"); + wdt.last_time = 0; + + return set_ctrl(CTRL_STOP); } static int wdt_ping(struct watchdog_device *dev) { - return 0; + int ret; + + dev_dbg(wdt.dev, "Watchdog pings\n"); + + ret = set_ctrl(CTRL_TRIGGER); + if (ret == 0) + wdt.last_time = jiffies; + + return ret; } static unsigned int wdt_get_timeleft(struct watchdog_device *dev) { - return 0; + unsigned int timeleft = 0; + + if (wdt.last_time != 0) + timeleft = wddev.timeout - ((jiffies - wdt.last_time) / HZ); + + return timeleft; } static int wdt_support(void) From patchwork Thu Oct 5 08:51:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenkai X-Patchwork-Id: 13410141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2767E92706 for ; Thu, 5 Oct 2023 14:38:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235097AbjJEOiS (ORCPT ); Thu, 5 Oct 2023 10:38:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235525AbjJEOfl (ORCPT ); Thu, 5 Oct 2023 10:35:41 -0400 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4973893D5; Thu, 5 Oct 2023 01:52:22 -0700 (PDT) Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-1c77449a6daso5734525ad.0; Thu, 05 Oct 2023 01:52:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696495941; x=1697100741; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f3fQjf5cs2rm/iEMimmENJo42F+TkJd9co+ck/259yc=; b=l0iQp7tqbnpBI8GxOi6T38BAW6/9qZTQE8T9ihP6wdI1PrdMDC/xjoDuH0XyAkJu9B Wzrgq5rM6cPm+Npd3VEiwCVKF5l3GZdmHhawLe/1M/q+fYwMSd4aYEbumDCrBJ6/vYqb PUyZt6m7w648NjBrBsHFD4TcsMtuFF/UaACuZytxiGDfdlTYBNKink6a/y0HBoRnhWfZ SDHcdjFsViOVI9i5nEGe8JTRRLzhBWC63VLm4RJhBkZyjeOv1ZUrjQ9WXX6ckl4tqdwJ 4ENBNiNMtitRluQuKqnf96ui8x4B4ufDcOvKiLCeKVe0p+GpSpSbzp6/34lGh4CN62Ik yQFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696495941; x=1697100741; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f3fQjf5cs2rm/iEMimmENJo42F+TkJd9co+ck/259yc=; b=gFdlpDIzmSuc2cUyuZQ1qtmzTWvbpx0XVeufwzA7o2z4bstmqzR6vQ0cHf4NfDrxiz O2VqCu16HiBpF/RwErPj3Lbbi7upiVksIRRiOA2KitIvPN8A3llFQVkIbmLPxyXVhQaJ 1fW1LwMQl+Qfb2dTI3slfPVSK+WPFFGPYj21tAXKW5Luw8f3qRgq5Iyhl9rFVgvruDFE nxrWWq63VRyslKxHc09Z6TBcekJUKF4zq8kNODhnzYTX2bkRaMEobJcycpVb1Io7OHyj c+zVXIRtyfiYs1hvpL6LSmejQyZ0sUK8YvJTMECOBuIGaJElhTXxHYmzz1JP9LeypGMZ rRgA== X-Gm-Message-State: AOJu0YxmNKoNnysy3Ca1dRMtnyA7fg6DR9v/GtTKBNhOXZcnKHQKqpCm sjWbUlgGHjTWvA5ePYKVBwPNTBbXx4oPXw== X-Google-Smtp-Source: AGHT+IF6mb+ioo521ahBySgh3snge5CKgwce3ikjlRRjW6R24u0p1GE3GquI8TVEVB2YPT8rqQD9sg== X-Received: by 2002:a17:902:9f8e:b0:1c5:b808:7fc8 with SMTP id g14-20020a1709029f8e00b001c5b8087fc8mr4406122plq.33.1696495941229; Thu, 05 Oct 2023 01:52:21 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id h9-20020a170902f54900b001c47541ecd7sm1059937plf.250.2023.10.05.01.52.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 01:52:20 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Wim Van Sebroeck , Guenter Roeck , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org Subject: [PATCH 4/5] watchdog: eiois200_wdt: Enhanced watchdog functionality and pretimeout Date: Thu, 5 Oct 2023 16:51:22 +0800 Message-Id: <9dc5114ec819588c5ba957bd9e365329533ac191.1696495372.git.advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Wenkai This patch extends the Advantech EIO-IS200 Watchdog Driver to provide advanced watchdog functionality, including pretimeout support. It allows the user to specify a timeout or pre-timeout trigger event, let the event pin output level switches from high to low. The event pin which can be one of the following: - PWRBTN (Power button) - SCI (ACPI System Control Interrupt) - IRQ - GPIO If the pretimeout is specified, when the pretimeout time expires, it triggers the associated pin. If the timeout expires, it triggers a reset. If the pretimeout is not specified, the timeout expiration triggers the associated pin or the reset pin. This addition to basic watchdog functionality. It ensures proper integration with the watchdog framework and provides a flexible watchdog solution for Advantech EIO-IS200-based systems. Signed-off-by: Wenkai --- drivers/watchdog/eiois200_wdt.c | 159 ++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 7 deletions(-) diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c index 569e619448e5..85179806ab7e 100644 --- a/drivers/watchdog/eiois200_wdt.c +++ b/drivers/watchdog/eiois200_wdt.c @@ -18,13 +18,21 @@ /* Support Flags */ #define SUPPORT_AVAILABLE BIT(0) +#define SUPPORT_PWRBTN BIT(3) +#define SUPPORT_IRQ BIT(4) +#define SUPPORT_SCI BIT(5) +#define SUPPORT_PIN BIT(6) #define SUPPORT_RESET BIT(7) /* PMC registers */ #define REG_STATUS 0x00 #define REG_CONTROL 0x02 #define REG_EVENT 0x10 +#define REG_PWR_EVENT_TIME 0x12 +#define REG_IRQ_EVENT_TIME 0x13 #define REG_RESET_EVENT_TIME 0x14 +#define REG_PIN_EVENT_TIME 0x15 +#define REG_SCI_EVENT_TIME 0x16 #define REG_IRQ_NUMBER 0x17 /* PMC command and control */ @@ -50,20 +58,53 @@ #define PMC_WRITE(cmd, data) pmc(CMD_WDT_WRITE, cmd, data) #define PMC_READ(cmd, data) pmc(CMD_WDT_READ, cmd, data) +/* Mapping event type to supported bit */ +#define EVENT_BIT(type) BIT(type + 2) + +enum event_type { + EVENT_NONE, + EVENT_PWRBTN, + EVENT_IRQ, + EVENT_SCI, + EVENT_PIN +}; + static struct _wdt { + u32 event_type; u32 support; long last_time; struct regmap *iomap; struct device *dev; } wdt; +static char * const type_strs[] = { + "NONE", + "PWRBTN", + "IRQ", + "SCI", + "PIN", +}; + +static u32 type_regs[] = { + REG_RESET_EVENT_TIME, + REG_PWR_EVENT_TIME, + REG_IRQ_EVENT_TIME, + REG_SCI_EVENT_TIME, + REG_PIN_EVENT_TIME, +}; + /* Pointer to the eiois200_core device structure */ static struct eiois200_dev *eiois200_dev; +/* Specify the pin triggered on pretimeout or timeout */ +static char *event_type = "NONE"; +module_param(event_type, charp, 0); +MODULE_PARM_DESC(event_type, + "Watchdog timeout event type (RESET, PWRBTN, SCI, IRQ, GPIO)"); static struct watchdog_info wdinfo = { .identity = KBUILD_MODNAME, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, + WDIOF_PRETIMEOUT | WDIOF_MAGICCLOSE, }; static struct watchdog_device wddev = { @@ -76,8 +117,42 @@ static int wdt_set_timeout(struct watchdog_device *dev, unsigned int _timeout) { dev->timeout = _timeout; - dev_dbg(wdt.dev, "Set timeout: %d\n", _timeout); + dev_info(wdt.dev, "Set timeout: %d\n", _timeout); + + return 0; +} + +static int wdt_set_pretimeout(struct watchdog_device *dev, + unsigned int _pretimeout) +{ + dev->pretimeout = _pretimeout; + + dev_info(wdt.dev, "Set pretimeout: %d\n", _pretimeout); + + return 0; +} + +static int wdt_get_type(void) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(type_strs); i++) + if (strcasecmp(event_type, type_strs[i]) == 0) { + if ((wdt.support & EVENT_BIT(i)) == 0) { + dev_err(wdt.dev, + "This board doesn't support %s trigger type\n", + event_type); + return -EINVAL; + } + + dev_info(wdt.dev, "Trigger type is %d:%s\n", + i, type_strs[i]); + wdt.event_type = i; + + return 0; + } + dev_info(wdt.dev, "Event type: %s\n", type_strs[wdt.event_type]); return 0; } @@ -116,33 +191,98 @@ static int set_time(u8 ctl, u32 time) static int wdt_set_config(void) { - int ret; + int ret, type; + u32 event_time = 0; u32 reset_time = 0; + /* event_type should never out of range */ + if (wdt.event_type > EVENT_PIN) + return -EFAULT; + + /* Calculate event time and reset time */ + if (wddev.pretimeout && wddev.timeout) { + if (wddev.timeout < wddev.pretimeout) + return -EINVAL; + reset_time = wddev.timeout; + event_time = wddev.timeout - wddev.pretimeout; + } else if (wddev.timeout) { + reset_time = wdt.event_type ? 0 : wddev.timeout; + event_time = wdt.event_type ? wddev.timeout : 0; + } + + /* Set reset time */ ret = set_time(REG_RESET_EVENT_TIME, reset_time); if (ret) return ret; - dev_info(wdt.dev, "Config wdt reset time %d\n", reset_time); + /* Set every other times */ + for (type = 1; type < ARRAY_SIZE(type_regs); type++) { + ret = set_time(type_regs[type], + wdt.event_type == type ? event_time : 0); + if (ret) + return ret; + } + + dev_dbg(wdt.dev, "Config wdt reset time %d\n", reset_time); + dev_dbg(wdt.dev, "Config wdt event time %d\n", event_time); + dev_dbg(wdt.dev, "Config wdt event type %s\n", + type_strs[wdt.event_type]); return ret; } static int wdt_get_config(void) { - int ret; - u32 reset_time; + int ret, type; + u32 event_time, reset_time; /* Get Reset Time */ ret = get_time(REG_RESET_EVENT_TIME, &reset_time); if (ret) return ret; - dev_info(wdt.dev, "Timeout H/W default timeout: %d secs\n", reset_time); + dev_dbg(wdt.dev, "Timeout H/W default timeout: %d secs\n", reset_time); + + /* Get every other times **/ + for (type = 1; type < ARRAY_SIZE(type_regs); type++) { + if ((wdt.support & EVENT_BIT(type)) == 0) + continue; + + ret = get_time(type_regs[type], &event_time); + if (ret) + return ret; + + if (event_time == 0) + continue; + + if (reset_time) { + if (reset_time < event_time) + continue; + wddev.timeout = reset_time; + wddev.pretimeout = reset_time - event_time; + + dev_dbg(wdt.dev, "Pretimeout H/W enabled with event %s of %d secs\n", + type_strs[type], wddev.pretimeout); + } else { + wddev.timeout = event_time; + wddev.pretimeout = 0; + } + + wdt.event_type = type; + + dev_dbg(wdt.dev, "Timeout H/W enabled of %d secs\n", + wddev.timeout); + return 0; + } + + wdt.event_type = EVENT_NONE; + wddev.pretimeout = reset_time ? 0 : WATCHDOG_PRETIMEOUT; + wddev.timeout = reset_time ? reset_time : WATCHDOG_TIMEOUT; + dev_dbg(wdt.dev, "Pretimeout H/W disabled"); return 0; } @@ -218,6 +358,7 @@ static int wdt_support(void) return 0; } + static int wdt_init(struct device *dev) { int ret = 0; @@ -230,6 +371,9 @@ static int wdt_init(struct device *dev) if (ret) return ret; + ret = wdt_get_type(); + if (ret) + return ret; return ret; } @@ -240,6 +384,7 @@ static const struct watchdog_ops wdt_ops = { .ping = wdt_ping, .set_timeout = wdt_set_timeout, .get_timeleft = wdt_get_timeleft, + .set_pretimeout = wdt_set_pretimeout, }; static int wdt_probe(struct platform_device *pdev) From patchwork Thu Oct 5 08:51:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenkai X-Patchwork-Id: 13410142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5534E92709 for ; Thu, 5 Oct 2023 14:38:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235389AbjJEOiS (ORCPT ); Thu, 5 Oct 2023 10:38:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235569AbjJEOfo (ORCPT ); Thu, 5 Oct 2023 10:35:44 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3ABFD93D7; Thu, 5 Oct 2023 01:52:26 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-690f7bf73ddso534514b3a.2; Thu, 05 Oct 2023 01:52:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696495945; x=1697100745; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PUkS6wMtaxA5uunPctyTHaq2tck/+416ywTiH4ESHuo=; b=TTsqWI78oOJtzCRYVOYSCP3Xha/LC8LB5iNwb1tkhlfAmpD88c4z5WnznfPWK1PB26 eJnl/4T/zYdDnmhz4p8BxdoSvWgbY4ndPGwVH+mV2kjJiozphBmPtuMYFzm0OExEXwh2 hmQwWse+X2jw7FBpaHM2ZupS0LOV/efnWe88DSTgjQfnf3EsEDxld3iH4ggRU9OcnFSn ZuL5FAvswBPZIUCQC5rZGpOup7vi2Ks6QaHWpV/M5ifVtZLimblBYRnu9Zi4fYs21b8v nQjBExGN8bBhRYdxKGK87HQt/EiSpj6Arf0uvCl7e7yFUMqbfSfiwf9YSQ/4rcPjU0I+ j2xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696495945; x=1697100745; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PUkS6wMtaxA5uunPctyTHaq2tck/+416ywTiH4ESHuo=; b=Apl6IHARVYXHoHop97P/IPL1g/XXT4SvPV63Scty791mmHj+AkhsIexmUe/pZ1NrvW H27xS/j+hSPzlPZ/hZIGPHQPLrd9JQ2qZ1q8r2uuMaaG16tjPtsAJ0cGf9bTagKpo+gO rAanKuMVAxHXgHH/nz5bflM86sSvFHsJ9/XJUl72iJ3Tjjz4UzFGEtWKwWD8SmpPFAsO +AYXwotLlv8VsKIFcXzZnqjchMFKbt79VAAKnU8+5XS42WfNgSkIbNB5rb9hh12cax3q h6hKuLwc8Knypzl5SshSCGBCjSCREs7qOXBBF+owb1EHXI/i96O7edv+hVDgCJMrfIxp AyAA== X-Gm-Message-State: AOJu0YxTiNZjkVky1REL1F7M+XJp76Q+KWJAnuHl7FLwOqWE+cElscdA UYh5AXXazPba/VoPXhOkZZZtWqh7mLsuTg== X-Google-Smtp-Source: AGHT+IGSDhxxF/QhqslmQbhj6F5951BdKdtUFUCEty2MOQx/wlntJDKMgJRjMW8MSUvGSCr4SZ8Pfw== X-Received: by 2002:a05:6a00:23ce:b0:68e:3eb6:d45 with SMTP id g14-20020a056a0023ce00b0068e3eb60d45mr5052132pfc.30.1696495945126; Thu, 05 Oct 2023 01:52:25 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id e18-20020aa78c52000000b0068fb8080939sm865701pfd.65.2023.10.05.01.52.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 01:52:24 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Wim Van Sebroeck , Guenter Roeck , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org Subject: [PATCH 5/5] watchdog: eiois200_wdt: Enhanced IRQ trigger behavior Date: Thu, 5 Oct 2023 16:51:23 +0800 Message-Id: <0ddce182fa353592979be2a6762e89a1dc436985.1696495372.git.advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Wenkai This patch improved functionality when IRQ is used as the trigger event. When the IRQ event selected. If the pretimeout is specified, when the pretimeout time expires, it will trigger the associated IRQ event and invoke the pretimeout governor's actions. And, if the pretimeout is not specified, when the timeout time expires, the driver initiates an emergency system restart. Signed-off-by: Wenkai --- drivers/watchdog/eiois200_wdt.c | 237 ++++++++++++++++++++++++++++++-- 1 file changed, 228 insertions(+), 9 deletions(-) diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c index 85179806ab7e..c9acb63b1152 100644 --- a/drivers/watchdog/eiois200_wdt.c +++ b/drivers/watchdog/eiois200_wdt.c @@ -2,10 +2,34 @@ /* * Advantech EIO-IS200 Watchdog Driver * + * This driver enables watchdog functionality for the Advantech EIO-IS200 + * embedded controller. Its has a dependency on the eiois200_core module. + * It allows the specification of a timeout or pretimeout associated trigger + * event, which can be one of the following pins: + * - PWRBTN (Power button) + * - SCI (ACPI System Control Interrupt) + * - IRQ + * - GPIO + * + * If the pretimeout is specified, when the pretimeout time expires, it + * triggers the associated pin; if the timeout expires, it always triggers + * a reset. If the associated pin is IRQ, the IRQ will trigger the system's + * original pretimeout behavior through the pretimeout governor. + * + * If the pretimeout is not specified, the timeout expiration triggers the + * associated pin only. If the associated pin is IRQ, it triggers a system + * emergency restart. + * + * NOTE: Advantech machines are shipped with proper IRQ and related event + * configurations. If you are unsure about these settings, just keep the + * device's default settings, and load this module without specifying any + * parameters. + * * Copyright (C) 2023 Advantech Co., Ltd. * Author: wenkai */ +#include #include #include #include @@ -59,7 +83,7 @@ #define PMC_READ(cmd, data) pmc(CMD_WDT_READ, cmd, data) /* Mapping event type to supported bit */ -#define EVENT_BIT(type) BIT(type + 2) +#define EVENT_BIT(type) BIT(type + 2) enum event_type { EVENT_NONE, @@ -72,6 +96,7 @@ enum event_type { static struct _wdt { u32 event_type; u32 support; + u32 irq; long last_time; struct regmap *iomap; struct device *dev; @@ -101,6 +126,12 @@ static char *event_type = "NONE"; module_param(event_type, charp, 0); MODULE_PARM_DESC(event_type, "Watchdog timeout event type (RESET, PWRBTN, SCI, IRQ, GPIO)"); + +/* Specify the IRQ number when the IRQ event is triggered */ +static int irq; +module_param(irq, int, 0); +MODULE_PARM_DESC(irq, "The IRQ number for IRQ event"); + static struct watchdog_info wdinfo = { .identity = KBUILD_MODNAME, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | @@ -145,8 +176,8 @@ static int wdt_get_type(void) return -EINVAL; } - dev_info(wdt.dev, "Trigger type is %d:%s\n", - i, type_strs[i]); + dev_info(wdt.dev, "Trigger type is %d:%s\n", + i, type_strs[i]); wdt.event_type = i; return 0; @@ -204,7 +235,7 @@ static int wdt_set_config(void) if (wddev.timeout < wddev.pretimeout) return -EINVAL; - reset_time = wddev.timeout; + reset_time = wddev.timeout; event_time = wddev.timeout - wddev.pretimeout; } else if (wddev.timeout) { @@ -228,7 +259,7 @@ static int wdt_set_config(void) dev_dbg(wdt.dev, "Config wdt reset time %d\n", reset_time); dev_dbg(wdt.dev, "Config wdt event time %d\n", event_time); dev_dbg(wdt.dev, "Config wdt event type %s\n", - type_strs[wdt.event_type]); + type_strs[wdt.event_type]); return ret; } @@ -261,11 +292,11 @@ static int wdt_get_config(void) if (reset_time < event_time) continue; - wddev.timeout = reset_time; + wddev.timeout = reset_time; wddev.pretimeout = reset_time - event_time; dev_dbg(wdt.dev, "Pretimeout H/W enabled with event %s of %d secs\n", - type_strs[type], wddev.pretimeout); + type_strs[type], wddev.pretimeout); } else { wddev.timeout = event_time; wddev.pretimeout = 0; @@ -274,7 +305,7 @@ static int wdt_get_config(void) wdt.event_type = type; dev_dbg(wdt.dev, "Timeout H/W enabled of %d secs\n", - wddev.timeout); + wddev.timeout); return 0; } @@ -359,6 +390,180 @@ static int wdt_support(void) return 0; } +static int wdt_get_irq_io(void) +{ + int ret = 0; + int idx = EIOIS200_PNP_INDEX; + int data = EIOIS200_PNP_DATA; + struct regmap *map = wdt.iomap; + + mutex_lock(&eiois200_dev->mutex); + + /* Unlock EC IO port */ + ret |= regmap_write(map, idx, IOREG_UNLOCK); + ret |= regmap_write(map, idx, IOREG_UNLOCK); + + /* Select logical device to PMC */ + ret |= regmap_write(map, idx, IOREG_LDN); + ret |= regmap_write(map, data, IOREG_LDN_PMCIO); + + /* Get IRQ number */ + ret |= regmap_write(map, idx, IOREG_IRQ); + ret |= regmap_read(map, data, &wdt.irq); + + /* Lock up */ + ret |= regmap_write(map, idx, IOREG_LOCK); + + mutex_unlock(&eiois200_dev->mutex); + + return ret ? -EIO : 0; +} + +static int wdt_get_irq_pmc(void) +{ + return PMC_READ(REG_IRQ_NUMBER, &wdt.irq); +} + +static int wdt_get_irq(struct device *dev) +{ + int ret; + + if ((wdt.support & BIT(EVENT_IRQ)) == 0) + return -ENODEV; + + /* Get IRQ number through PMC */ + ret = wdt_get_irq_pmc(); + if (ret) + return dev_err_probe(dev, ret, "Error get irq by pmc\n"); + + if (wdt.irq) + return 0; + + /* Get IRQ number from the watchdog device in EC */ + ret = wdt_get_irq_io(); + if (ret) + return dev_err_probe(dev, ret, "Error get irq by io\n"); + + if (wdt.irq == 0) + return dev_err_probe(dev, ret, "Error IRQ number = 0\n"); + + return ret; +} + +static int wdt_set_irq_io(void) +{ + int ret = 0; + int idx = EIOIS200_PNP_INDEX; + int data = EIOIS200_PNP_DATA; + struct regmap *map = wdt.iomap; + + mutex_lock(&eiois200_dev->mutex); + + /* Unlock EC IO port */ + ret |= regmap_write(map, idx, IOREG_UNLOCK); + ret |= regmap_write(map, idx, IOREG_UNLOCK); + + /* Select logical device to PMC */ + ret |= regmap_write(map, idx, IOREG_LDN); + ret |= regmap_write(map, data, IOREG_LDN_PMCIO); + + /* Enable WDT */ + ret |= regmap_write(map, idx, IOREG_WDT_STATUS); + ret |= regmap_write(map, data, FLAG_WDT_ENABLED); + + /* Set IRQ number */ + ret |= regmap_write(map, idx, IOREG_IRQ); + ret |= regmap_write(map, data, wdt.irq); + + /* Lock up */ + ret |= regmap_write(map, idx, IOREG_LOCK); + + mutex_unlock(&eiois200_dev->mutex); + + return ret ? -EIO : 0; +} + +static int wdt_set_irq_pmc(void) +{ + return PMC_WRITE(REG_IRQ_NUMBER, &wdt.irq); +} + +static int wdt_set_irq(struct device *dev) +{ + int ret; + + if ((wdt.support & BIT(EVENT_IRQ)) == 0) + return -ENODEV; + + /* Set IRQ number to the watchdog device in EC */ + ret = wdt_set_irq_io(); + if (ret) + return dev_err_probe(dev, ret, + "Error set irq by io\n"); + + /* Notice EC that watchdog IRQ changed */ + ret = wdt_set_irq_pmc(); + if (ret) + return dev_err_probe(dev, ret, + "Error set irq by pmc\n"); + + return ret; +} + +/** + * wdt_get_irq_event - Check if IRQ been triggered + * Returns: The current status read from the PMC, + * or 0 if there was an error. + */ +static int wdt_get_irq_event(void) +{ + u8 status; + + if (PMC_READ(REG_EVENT, &status)) + return 0; + + return status; +} + +static irqreturn_t wdt_isr(int irq, void *arg) +{ + return IRQ_WAKE_THREAD; +} + +static irqreturn_t wdt_threaded_isr(int irq, void *arg) +{ + u8 status = wdt_get_irq_event() & FLAG_TRIGGER_IRQ; + + if (!status) + return IRQ_NONE; + + if (wddev.pretimeout) { + watchdog_notify_pretimeout(&wddev); + } else { + pr_crit("Watchdog Timer expired. Initiating system reboot\n"); + emergency_restart(); + } + + return IRQ_HANDLED; +} + +static int query_irq(struct device *dev) +{ + int ret; + + if (irq) { + wdt.irq = irq; + } else { + ret = wdt_get_irq(dev); + if (ret) + return ret; + } + + dev_dbg(wdt.dev, "IRQ = %d\n", wdt.irq); + + return wdt_set_irq(dev); +} + static int wdt_init(struct device *dev) { int ret = 0; @@ -374,6 +579,10 @@ static int wdt_init(struct device *dev) ret = wdt_get_type(); if (ret) return ret; + + if (wdt.event_type == EVENT_IRQ) + ret = query_irq(dev); + return ret; } @@ -402,11 +611,21 @@ static int wdt_probe(struct platform_device *pdev) wdt.iomap = dev_get_regmap(dev->parent, NULL); if (!wdt.iomap) return dev_err_probe(dev, -ENOMEM, "Query parent regmap fail\n"); - + /* Initialize EC watchdog */ if (wdt_init(dev)) return dev_err_probe(dev, -EIO, "wdt_init fail\n"); + /* Request IRQ */ + if (wdt.event_type == EVENT_IRQ) + ret = devm_request_threaded_irq(dev, wdt.irq, wdt_isr, + wdt_threaded_isr, + IRQF_SHARED, pdev->name, dev); + if (ret) + return dev_err_probe(dev, ret, + "IRQ %d request fail:%d. Disabled.\n", + wdt.irq, ret); + /* Inform watchdog info */ wddev.ops = &wdt_ops; ret = watchdog_init_timeout(&wddev, wddev.timeout, dev);