From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=74.125.82.175 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793264241; b=mnH/wsnyx633sDpLEa85jVIPJPK6Rsav/Zslb1FaKNJquNJepBD9kZGU0oXYX03wGaQA T8e8i6j9FGwbYClAvyrR0Bd9bPSLWzC9C2mOCMJkxuSseDQ+aQoncdjWaZULHOEpIXfco CUYFEaNKM1nWgV4VdAWmSxvbS43g/tzvWQUh/lYp3FVcqgE8kS0DnEuGg/byweic/OYWq LcTohqW0b9gduSXjZ0vkyE5svRepLme2ONkkgfDQBFlMm1bp+fdWyvqK0qx15ZW4MATkO jfxnUC42TMdpOoFevQRpj1VzXTXw4EyNJKSPWYL9mSAD/hhufeIlbRr2J/aLfgLpMBQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793264241; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; bh=l2H0bFieZXxd5jJJlL+lwbMkDWOOduyv3s8IOA4GnsU=; b=KGTI8fmTm4Ex2rmSOAWniAPCpUfwDRo7aaR7izQGG5pFdpoUeO6aKlylvqiE5jiJoivG K1u/yp07yCBaFizXbzhmyy6RZzyrh3HRxlsiexxR1SIYqyU+JEi8+jiYlhq9q+KX0qeFh 7nEj7KYfEkxU7De6u4VxllIYkdkNpIAaYEaEi+3Pw8hrvEJl9XBOdLp+/ScjCLblxun1+ xnOCFU2HJ41rZVADxn83vhyw9KL3KnPSbIb1J1Y2rSgu6SW2PSwiK0kwFljFxGlOwLCKb RW9xnB5Xt3WsmU1ZvnOCwrsnpOkV22+QTxl958pCuPIYC1OdnMUQKqd/yl9Yiu+8xpw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=CaWvT125; arc=none smtp.remote-ip=74.125.82.175 Received: from mail-dy1-f175.google.com (mail-dy1-f175.google.com [74.125.82.175]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA1A9606A325 for ; Thu, 29 Oct 2026 08:57:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org AA1A9606A325 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=CaWvT125 Received: by mail-dy1-f175.google.com with SMTP id 5a478bee46e88-3535a54bed9so2733344eec.1 for ; Thu, 29 Oct 2026 01:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793264240; x=1793869040; darn=lists.linux.dev; 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:content-type; bh=l2H0bFieZXxd5jJJlL+lwbMkDWOOduyv3s8IOA4GnsU=; b=CaWvT125NxS2RzgMXvKHxdhcITg7SoXZvqbpMSJrAST9AcrmIjIlVVsaceRnXYj9er 6qZqCrfeCJ1fwvSEwDqiWe84TQcOClvmjGhOwAEqvqs1vcvLrvjhFLVzgq13yUPhKT6u zFwMznKsRS5BPW/8B06+AtZUzus+iQmw+eY3ea2mUM2W5JW08fJuma4boVeSIAVB4ALu ugMskJ10ZfVSpfVH41Sxo1nt+WFEIT1HRk4y5qiIo1Oh1eqzlu5s6XCu0MSutj2A/xT3 vsr4y5vAAN+/mv3t0L94J875LWDNxaRhcIduLSLec0O5okNfuJROGlgS9LFv0pGY13Xc 7wOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793264240; x=1793869040; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=l2H0bFieZXxd5jJJlL+lwbMkDWOOduyv3s8IOA4GnsU=; b=s6aRqCM5eQUqQ3ul8PaScyxnAwn9n1ttQ358TQqv0h45aj5XcGKJf1ej87j4ap2IYT O/cYK1w+cOeWNw18dBRR4GI4/UNiD5Od8200BBWYiPTbRF0b1XCTmgzC1nbpjXg7FOOC 9AolhQeAcRBWsqoKH1sAD36vpphu0s/QfUbs9abmTKFldKWjidp00GstzzmO57lJwhfo I0q1iMjxNtjEAl3PfhfWsi89m+cwS1MfIY6KOeBrKwM3p8uk+SuDwLKkzD9xABwFhsRI GKSC9Ctajw7EyiwGjiddERie+wWwNqlR0mIFIagAeCZDX2Cf82Bm1gT1AxJnIPEHjPf2 gOuQ== X-Forwarded-Encrypted: i=1; AKwUvBypViPO7SYCyI1uJWR9hkdFSGlecGwBFMV3a2dKhOQ+JboU/8rZX2IU9Uos5NEL6uKFJxJueg==@lists.linux.dev X-Gm-Message-State: AFq9FYI13x5D/oAX6kquiVdgl5A8XypzkXkGBP0N8Ha1uTz8eVuJ9xat /jFy5rbc7poPEixLgGJMoW0JAKFIVtYdHyqD7oSQYGMtiZOydoQX4q0= X-Gm-Gg: AYBFou3Eq0dnz0k1EPjzieKD5gKHboXPmDkZBQ5V/bFp4moQzWaisH8/xj3m9ABEkAU QQNHezYV1Omab55EMCQoWQOO/7BSQBK/M6q2N6kL+quZKq/X3Ohs08PBzYVfYVwFl9Tg3jdxxDp WVqyovyXN8hzJYu1PVbME2bDQA5MnD7iVUqFHIXjh0BP+j4ojs18aS8A2VG7UqWzDcC+/Emu9HK rSvff9J2BqWdqqQzNpTrwdWxfoyDW3SyL3qDoHS9EhrGStfqYt0Se9ib/QRwWXTslP/9lxKUYr4 KZos/uJf+G7mVrS/uuXE+wshyjl8FbfGZi5JcLBAJRIOs5Zmp7yorpN90OqR4U3oHGvBHEC4+xR lVfWlt+GXZvT0ckigqhWg9qfAuK8ZzTmCm4FsU5U7Uk7Y9WnkGVz5+r+6L/r2X4ULL2zFnzZAPq b+SRljUwXiEdwgBlsWAFi/k18fS8APav+Rkzpif2V9LSVi8BWNXr/niDhjsQ506e4TEH1K5KzQz qTSPzM0qQgDN0TfTSFmwvccPwzf71KxAfoPFLEnktSIyBGpgMLOptw0AZRGL8WVtpH6tH57o4DW b3qbwBYa7SivI5uJyil/NyJsdsTJAJ9wagRmd80iSAlEzuhINrkR1ZfvMQamJA== X-Received: by 2002:a05:7300:e9c4:20b0:36a:13e1:c889 with SMTP id 5a478bee46e88-36a20427d57mr7840856eec.36.1793264239420; Thu, 29 Oct 2026 01:57:19 -0700 (PDT) Received: from at-Standard-PC-Q35-ICH9-2009 ([27.60.20.232]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-36a23641e78sm16497937eec.0.2026.10.29.01.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Oct 2026 01:57:19 -0700 (PDT) From: Atharva Tiwari To: Cc: Atharva Tiwari , Bjorn Helgaas , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , "Rafael J. Wysocki" , Len Brown , Linus Walleij , Bartosz Golaszewski , Sven Peter , Janne Grunau , Neal Gompa , Guenter Roeck , Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Lee Jones , Pavel Machek , Griffin Kroah-Hartman , Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Sebastian Reichel , Alexandre Belloni , Wim Van Sebroeck , Jarkko Sakkinen , Mimi Zohar , Roberto Sassu , Dmitry Kasatkin , Eric Snowberg , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-hwmon@vger.kernel.org, linux-iio@vger.kernel.org, linux-leds@vger.kernel.org, mfd@lists.linux.dev, platform-driver-x86@vger.kernel.org, linux-pm@vger.kernel.org, linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org, linux-integrity@vger.kernel.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [RFC PATCH 03/14] watchdog: add driver for apple smc Date: Thu, 29 Oct 2026 04:52:00 -0400 Message-ID: <20261029085504.3547-4-atharvatiwarilinuxdev@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261029085504.3547-1-atharvatiwarilinuxdev@gmail.com> References: <20261029085504.3547-1-atharvatiwarilinuxdev@gmail.com> X-Mailing-List: asahi@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add a watchdog driver for the SMC on Intel Macs. It can reset the machine if the system stops responding. It works on both newer and older SMC versions. Signed-off-by: Atharva Tiwari --- drivers/mfd/macsmc-core.c | 11 +++ drivers/watchdog/Kconfig | 11 +++ drivers/watchdog/Makefile | 2 +- drivers/watchdog/macsmc_wdt.c | 140 ++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 drivers/watchdog/macsmc_wdt.c diff --git a/drivers/mfd/macsmc-core.c b/drivers/mfd/macsmc-core.c index b8905c834..1c1469828 100644 --- a/drivers/mfd/macsmc-core.c +++ b/drivers/mfd/macsmc-core.c @@ -33,6 +33,10 @@ static const struct mfd_cell apple_smc_acpi_rtc[] = { MFD_CELL_NAME("macsmc-rtc"), }; +static const struct mfd_cell apple_smc_acpi_wdt[] = { + MFD_CELL_NAME("macsmc-wdt"), +}; + int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size) { guard(mutex)(&smc->mutex); @@ -147,6 +151,13 @@ int apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops, return ret; } + if (apple_smc_key_exists(smc, SMC_KEY(NATJ))) { + ret = devm_mfd_add_devices(dev, -1, apple_smc_acpi_wdt, + ARRAY_SIZE(apple_smc_acpi_wdt), NULL, 0, NULL); + if (ret < 0) + return ret; + } + } else ret = devm_mfd_add_devices(dev, -1, apple_smc_rtkit_devs, ARRAY_SIZE(apple_smc_rtkit_devs), NULL, 0, NULL); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index f7d0a0c2c..854ab772f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1810,6 +1810,17 @@ config SIEMENS_SIMATIC_IPC_WDT To compile this driver as a module, choose M here: the module will be called simatic-ipc-wdt. +config MACSMC_WDT + tristate "Apple SMC Watchdog" + depends on X86 && MACSMC_ACPI + select WATCHDOG_CORE + help + This driver adds support for Watchdogs in Intel macs Using + Apple SMC. + + To compile this driver as a module, choose M here: the module will be + called macsmc_wdt. + # M68K Architecture config M54xx_WATCHDOG diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 9ac406677..f142a5d8d 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -158,7 +158,7 @@ obj-$(CONFIG_NIC7018_WDT) += nic7018_wdt.o obj-$(CONFIG_MLX_WDT) += mlx_wdt.o obj-$(CONFIG_KEEMBAY_WATCHDOG) += keembay_wdt.o obj-$(CONFIG_SIEMENS_SIMATIC_IPC_WDT) += simatic-ipc-wdt.o - +obj-$(CONFIG_MACSMC_WDT) += macsmc_wdt.o # M68K Architecture obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o diff --git a/drivers/watchdog/macsmc_wdt.c b/drivers/watchdog/macsmc_wdt.c new file mode 100644 index 000000000..38f68d0d8 --- /dev/null +++ b/drivers/watchdog/macsmc_wdt.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Apple SMC Watchdog Driver + * + * Copyright (C) 2026 Atharva Tiwari + */ + +#include +#include +#include + +#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static int timeout = WATCHDOG_TIMEOUT; /* in secounds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, + "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" + __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + +struct macsmc_wdt { + struct apple_smc *smc; + bool has_oswd; /* Newer version of watchdogs in macsmc */ + struct watchdog_device wdd; +}; + +static int macsmc_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout) +{ + struct macsmc_wdt *drv = watchdog_get_drvdata(wdd); + int ret; + + if (timeout) + wdd->timeout = timeout; + + if (drv->has_oswd) { + ret = apple_smc_write_u16(drv->smc, SMC_KEY(OSWD), (u16)(timeout << 8)); + if (ret < 0) + return ret; + } else { + /* + * NATJ = 2, makes the watchdog do force restart if NATi == 0 + * NATJ = 0, makes the watchdog do nothing if NATi == 0 + */ + if (timeout == 0) { + ret = apple_smc_write_u16(drv->smc, SMC_KEY(NATJ), 0); + if (ret < 0) + return ret; + } + ret = apple_smc_write_u16(drv->smc, SMC_KEY(NATi), (u16)(timeout << 8)); + if (ret < 0) + return ret; + + if (timeout != 0) { + ret = apple_smc_write_u16(drv->smc, SMC_KEY(NATJ), 2); + if (ret < 0) + return ret; + } + } + + return 0; +} +static int macsmc_wdt_start(struct watchdog_device *wdd) +{ + return macsmc_wdt_set_timeout(wdd, wdd->timeout); +} +static int macsmc_wdt_stop(struct watchdog_device *wdd) +{ + return macsmc_wdt_set_timeout(wdd, 0); +} + +static int macsmc_wdt_ping(struct watchdog_device *wdd) +{ + struct macsmc_wdt *drv = watchdog_get_drvdata(wdd); + int ret; + + if (drv->has_oswd) + ret = apple_smc_write_u16(drv->smc, SMC_KEY(OSWD), (u16)(wdd->timeout << 8)); + else + ret = apple_smc_write_u16(drv->smc, SMC_KEY(NATi), (u16)(wdd->timeout << 8)); + + if (ret < 0) + return ret; + + return 0; +} + +static const struct watchdog_ops macsmc_wdt_ops = { + .owner = THIS_MODULE, + .start = macsmc_wdt_start, + .stop = macsmc_wdt_stop, + .set_timeout = macsmc_wdt_set_timeout, + .ping = macsmc_wdt_ping, +}; + +static const struct watchdog_info macsmc_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "Macsmc Watchdog timer", +}; + +static int macsmc_wdt_probe(struct platform_device *pdev) +{ + struct macsmc_wdt *drv; + + drv = devm_kzalloc(&pdev->dev, sizeof(struct macsmc_wdt), GFP_KERNEL); + if (!drv) + return -ENOMEM; + + drv->smc = dev_get_drvdata(pdev->dev.parent); + if (apple_smc_key_exists(drv->smc, SMC_KEY(OSWD))) + drv->has_oswd = true; + else + drv->has_oswd = false; + + drv->wdd.ops = &macsmc_wdt_ops; + drv->wdd.info = &macsmc_wdt_info; + drv->wdd.min_timeout = 1; + drv->wdd.max_timeout = 255; + watchdog_init_timeout(&drv->wdd, timeout, &pdev->dev); + watchdog_set_nowayout(&drv->wdd, nowayout); + watchdog_set_drvdata(&drv->wdd, drv); + + return devm_watchdog_register_device(&pdev->dev, &drv->wdd); +} + +static struct platform_driver macsmc_wdt_driver = { + .probe = macsmc_wdt_probe, + .driver = { + .name = "macsmc-wdt" + }, +}; +module_platform_driver(macsmc_wdt_driver); + +MODULE_AUTHOR("Atharva Tiwari "); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Apple SMC Watchdog Driver"); +MODULE_ALIAS("platform:macsmc-wdt"); -- 2.55.0