Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1393364ybv; Thu, 13 Feb 2020 22:28:55 -0800 (PST) X-Google-Smtp-Source: APXvYqyyvIiuHbv0fwdsQ4Fyzu3BIa3MHFsVifGhGTlFhH4peyR/qYXxQOLBNsnK+bjwtBs90sEm X-Received: by 2002:a05:6830:4a7:: with SMTP id l7mr987987otd.372.1581661735840; Thu, 13 Feb 2020 22:28:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581661735; cv=none; d=google.com; s=arc-20160816; b=Cajz/TqGIx3JWEAPy0rNhmt1lbyX4Ets4faMimrliZP2vwz26J3+9EsYm8tDAiNS9E utzxsUQifN7YVu+0U4PEk2XF/uMlAIZj7YxlbRaPtfWR1vgw+tlTBc+UQGredCAkKauf YTfGp08dIrObfXkIjMw+86/idvoHkqtrG9K9Nk3qTTBkN0xKfdIPs0G4B2+s+9q2rAeK AV/GdoYOOvBJwyZSL4/RVJWodbYx4AsrduG8miGb3YvlF+6tVzG3qZboLWm96kaZFo1K 7P2H6SUu0zBoSRoBXjx+IHjWPz7kKQ3o96TeyyWVDMQ7uM7RuVZSkiFmjtKnCSJauh6o ovkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6m0wKT11+R7CJOjoRsWO8Pr4RXElruZP9dFH32DME6A=; b=oYjT+zr0mZfAG9OjT4E/0yhaAmNWYjqEtGg6A0K86JPuabEFJ+AMVSjLiebJUgf4iY vLgeqmgNtqaGhl7zb6biaBio4EsHsmRA0Wg7YwFZiXpHvbbdCy3014Lh2SfRXz5eIPrJ 6etP07pWkSJAtLiQvcmJ5ivzX7+aoh/xUJIqeyWHGJlMnV//zJLl4RBA7bY8mEk+3K+d 0zZMC2xpDmqEJ7AwjD8cT+pWlBQXcy3QhHpkf4MVqXKsjLqqTkJSVhgbaanXmLbSPmZf BCvuEKPCIoSAsAqe9Rnw9C8VTEARmMb5sA53Y+Xgfw8gnK+MVMDFSKKq0+cJrEWZhDZL 8O9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=TImDPxVE; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a7si2204822otp.11.2020.02.13.22.28.43; Thu, 13 Feb 2020 22: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; dkim=pass header.i=@chromium.org header.s=google header.b=TImDPxVE; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728865AbgBNG1G (ORCPT + 99 others); Fri, 14 Feb 2020 01:27:06 -0500 Received: from mail-pj1-f65.google.com ([209.85.216.65]:38630 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728540AbgBNG1G (ORCPT ); Fri, 14 Feb 2020 01:27:06 -0500 Received: by mail-pj1-f65.google.com with SMTP id j17so3500147pjz.3 for ; Thu, 13 Feb 2020 22:27:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6m0wKT11+R7CJOjoRsWO8Pr4RXElruZP9dFH32DME6A=; b=TImDPxVECGTtF6BbPylZ9cw+7NQkr+joHRgULdu0By3TTXb4F3KG8t6hy6dky7kcmM mjtwJntZfDFB5K0WjL3OPrRlq9B7UiXAlsgz4kW38cqqZ3qIMOPvG1sKuKCa4rE5Q2r0 c13VPYxVc72XVLRF27VITFldOyhLHaZKqv5bo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6m0wKT11+R7CJOjoRsWO8Pr4RXElruZP9dFH32DME6A=; b=Qn1vIS3+wpZtlKYLuRo53ywd8M805I67Q9czUJKATa0nO2TEDWPCTenFJETTx/m8z5 Jh7jm1XdAsjZMSgC8eg4h4Ckiqkc/hpE+jNcQehw9ywM0DJBPri1BqeQtqYvCvqUdOr5 dfM2d6PC/prTwY7+X/+G+k0YDqKSMtsLfDNcksTKFW6+wDkGm0qokPEPhYySThi6lQ51 VzXQ93KxkEz9/CMQd1wPqR3GXu6DSLcW8Z9FaA9YyCpRWb8C+UyCWzU7Ph5mVt3t+F2w RioA7Yn6YZ2fFu5eU2P3nYOtfEvTaEQaqu2t58sNIxcNJ03Tgy8aeU0/mPOAHdq2R+70 zTZg== X-Gm-Message-State: APjAAAW8qqcQ6SK3UFel1w0SmT1hUmu5Dxax4VUg3ncL2SbIfh+88Z/D Aij3OZjES0RDUkZmiuj1PLYmclTml0nfLw== X-Received: by 2002:a17:90a:c389:: with SMTP id h9mr1757635pjt.128.1581661625273; Thu, 13 Feb 2020 22:27:05 -0800 (PST) Received: from localhost ([2401:fa00:9:14:1105:3e8a:838d:e326]) by smtp.gmail.com with ESMTPSA id r198sm5660030pfr.54.2020.02.13.22.26.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 Feb 2020 22:27:04 -0800 (PST) From: Evan Benn To: LKML Cc: jwerner@chromium.org, Evan Benn , Bjorn Andersson , Guenter Roeck , Mauro Carvalho Chehab , Marcin Juszkiewicz , Catalin Marinas , Olof Johansson , Leonard Crestez , Jonathan Cameron , Dinh Nguyen , linux-arm-kernel@lists.infradead.org, Greg Kroah-Hartman , Will Deacon , linux-watchdog@vger.kernel.org, Rob Herring , Wim Van Sebroeck , =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= , Shawn Guo , "David S. Miller" , Anson Huang Subject: [PATCH 2/2] watchdog: Add new arm_smc_wdt watchdog driver Date: Fri, 14 Feb 2020 17:26:37 +1100 Message-Id: <20200214172512.2.I7c8247c29891a538f258cb47828d58acf22c95a2@changeid> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200214062637.216209-1-evanbenn@chromium.org> References: <20200214062637.216209-1-evanbenn@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Julius Werner This patch adds a stub watchdog driver that can be used on ARM systems with a Secure Monitor firmware to forward watchdog operations to firmware via a Secure Monitor Call. This may be useful for platforms using TrustZone that want the Secure Monitor firmware to have the final control over the watchdog. Signed-off-by: Julius Werner Signed-off-by: Evan Benn --- MAINTAINERS | 1 + arch/arm64/configs/defconfig | 1 + drivers/watchdog/Kconfig | 12 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/arm_smc_wdt.c | 191 +++++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+) create mode 100644 drivers/watchdog/arm_smc_wdt.c diff --git a/MAINTAINERS b/MAINTAINERS index 5c45536e1177..71df3c110fdb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1426,6 +1426,7 @@ M: Julius Werner R: Evan Benn S: Maintained F: devicetree/bindings/watchdog/arm,smc-wdt.yaml +F: drivers/watchdog/arm_smc_wdt.c ARM SMMU DRIVERS M: Will Deacon diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b2f667307f82..8527db9e92a6 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -451,6 +451,7 @@ CONFIG_QCOM_TSENS=y CONFIG_UNIPHIER_THERMAL=y CONFIG_WATCHDOG=y CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ARM_SMC_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_DW_WATCHDOG=y CONFIG_SUNXI_WATCHDOG=m diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index cec868f8db3f..0f7f93342051 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -857,6 +857,18 @@ config DIGICOLOR_WATCHDOG To compile this driver as a module, choose M here: the module will be called digicolor_wdt. +config ARM_SMC_WATCHDOG + tristate "ARM Secure Monitor Call based watchdog support" + depends on ARM || ARM64 + select WATCHDOG_CORE + help + Say Y here to include support for a watchdog timer + implemented by the EL3 Secure Monitor on ARM platforms. + Requires firmware support. + To compile this driver as a module, choose M here: the + module will be called arm_smc_wdt. + + config LPC18XX_WATCHDOG tristate "LPC18xx/43xx Watchdog" depends on ARCH_LPC18XX || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 2ee352bf3372..a1e6d83a7659 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -92,6 +92,7 @@ obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o obj-$(CONFIG_SPRD_WATCHDOG) += sprd_wdt.o +obj-$(CONFIG_ARM_SMC_WATCHDOG) += arm_smc_wdt.o obj-$(CONFIG_PM8916_WATCHDOG) += pm8916_wdt.o # X86 (i386 + ia64 + x86_64) Architecture diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c new file mode 100644 index 000000000000..58e7294136ef --- /dev/null +++ b/drivers/watchdog/arm_smc_wdt.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ARM Secure Monitor Call watchdog driver + * + * Copyright 2018 The Chromium OS Authors. All rights reserved. + * + * Julius Werner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Based on mtk_wdt.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "arm_smc_wdt" +#define DRV_VERSION "1.0" + +#define SMCWD_FUNC_ID 0x82003d06 + +enum smcwd_call { + SMCWD_INFO = 0, + SMCWD_SET_TIMEOUT = 1, + SMCWD_ENABLE = 2, + SMCWD_PET = 3, +}; + +static bool nowayout = WATCHDOG_NOWAYOUT; +static unsigned int timeout; + +static int smcwd_call(enum smcwd_call call, unsigned long arg, + struct arm_smccc_res *res) +{ + struct arm_smccc_res local_res; + + if (!res) + res = &local_res; + + arm_smccc_smc(SMCWD_FUNC_ID, call, arg, 0, 0, 0, 0, 0, res); + + if ((int)res->a0 == PSCI_RET_NOT_SUPPORTED) + return -ENOTSUPP; + if ((int)res->a0 == PSCI_RET_INVALID_PARAMS) + return -EINVAL; + if ((int)res->a0 < 0) + return -EIO; + return res->a0; +} + +static int smcwd_ping(struct watchdog_device *wdd) +{ + return smcwd_call(SMCWD_PET, 0, NULL); +} + +static int smcwd_set_timeout(struct watchdog_device *wdd, + unsigned int timeout) +{ + int res; + + res = smcwd_call(SMCWD_SET_TIMEOUT, timeout, NULL); + if (!res) + wdd->timeout = timeout; + return res; +} + +static int smcwd_stop(struct watchdog_device *wdd) +{ + return smcwd_call(SMCWD_ENABLE, 0, NULL); +} + +static int smcwd_start(struct watchdog_device *wdd) +{ + return smcwd_call(SMCWD_ENABLE, 1, NULL); +} + +static const struct watchdog_info smcwd_info = { + .identity = DRV_NAME, + .options = WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, +}; + +static const struct watchdog_ops smcwd_ops = { + .owner = THIS_MODULE, + .start = smcwd_start, + .stop = smcwd_stop, + .ping = smcwd_ping, + .set_timeout = smcwd_set_timeout, +}; + +static int smcwd_probe(struct platform_device *pdev) +{ + struct watchdog_device *wdd; + int err; + struct arm_smccc_res res; + + err = smcwd_call(SMCWD_INFO, 0, &res); + if (err < 0) + return err; + + wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL); + if (!wdd) + return -ENOMEM; + + platform_set_drvdata(pdev, wdd); + + wdd->info = &smcwd_info; + wdd->ops = &smcwd_ops; + wdd->timeout = res.a2; + wdd->max_timeout = res.a2; + wdd->min_timeout = res.a1; + wdd->parent = &pdev->dev; + + watchdog_set_nowayout(wdd, nowayout); + watchdog_init_timeout(wdd, timeout, &pdev->dev); + err = smcwd_set_timeout(wdd, wdd->timeout); + if (err) + return err; + + err = watchdog_register_device(wdd); + if (err) + return err; + + dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", + wdd->timeout, nowayout); + + return 0; +} + +static void smcwd_shutdown(struct platform_device *pdev) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + + if (watchdog_active(wdd)) + smcwd_stop(wdd); +} + +static int smcwd_remove(struct platform_device *pdev) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + + watchdog_unregister_device(wdd); + + return 0; +} + +static const struct of_device_id smcwd_dt_ids[] = { + { .compatible = "arm,smc-wdt" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, smcwd_dt_ids); + +static struct platform_driver smcwd_driver = { + .probe = smcwd_probe, + .remove = smcwd_remove, + .shutdown = smcwd_shutdown, + .driver = { + .name = DRV_NAME, + .of_match_table = smcwd_dt_ids, + }, +}; + +module_platform_driver(smcwd_driver); + +module_param(timeout, uint, 0); +MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); + +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Julius Werner "); +MODULE_DESCRIPTION("ARM Secure Monitor Call Watchdog Driver"); +MODULE_VERSION(DRV_VERSION); -- 2.25.0.265.gbab2e86ba0-goog