From: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
Cc: "Atharva Tiwari" <atharvatiwarilinuxdev@gmail.com>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Thomas Gleixner" <tglx@kernel.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Len Brown" <lenb@kernel.org>,
"Linus Walleij" <linusw@kernel.org>,
"Bartosz Golaszewski" <brgl@kernel.org>,
"Sven Peter" <sven@kernel.org>, "Janne Grunau" <j@jannau.net>,
"Neal Gompa" <neal@gompa.dev>,
"Guenter Roeck" <linux@roeck-us.net>,
"Jonathan Cameron" <jic23@kernel.org>,
"David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>, "Lee Jones" <lee@kernel.org>,
"Pavel Machek" <pavel@kernel.org>,
"Griffin Kroah-Hartman" <griffin@kroah.com>,
"Hans de Goede" <hansg@kernel.org>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Sebastian Reichel" <sre@kernel.org>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Wim Van Sebroeck" <wim@linux-watchdog.org>,
"Jarkko Sakkinen" <jarkko@kernel.org>,
"Mimi Zohar" <zohar@linux.ibm.com>,
"Roberto Sassu" <roberto.sassu@huawei.com>,
"Dmitry Kasatkin" <dmitry.kasatkin@gmail.com>,
"Eric Snowberg" <eric.snowberg@oracle.com>,
"Paul Moore" <paul@paul-moore.com>,
"James Morris" <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
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 07/14] rtc: add support for x86 macs in macsmc-rtc
Date: Thu, 29 Oct 2026 04:52:04 -0400 [thread overview]
Message-ID: <20261029085504.3547-8-atharvatiwarilinuxdev@gmail.com> (raw)
In-Reply-To: <20261029085504.3547-1-atharvatiwarilinuxdev@gmail.com>
Make macsmc-rtc work on Intel Macs. The ACPI RTC doesn't
work correctly on T2 Macs, so the clock from the SMC is
used instead.
On these machines the time offset is kept in the SMC instead
of NVMEM, and the clock rate is read from the SMC too.
Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
---
drivers/rtc/rtc-macsmc.c | 126 ++++++++++++++++++++++++++++++++-------
1 file changed, 106 insertions(+), 20 deletions(-)
diff --git a/drivers/rtc/rtc-macsmc.c b/drivers/rtc/rtc-macsmc.c
index 8fe883066..37395c64c 100644
--- a/drivers/rtc/rtc-macsmc.c
+++ b/drivers/rtc/rtc-macsmc.c
@@ -2,9 +2,12 @@
/*
* Apple SMC RTC driver
* Copyright The Asahi Linux Contributors
+ *
+ * Copyright (C) 2026 Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>
*/
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <linux/mfd/macsmc.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
@@ -20,13 +23,54 @@
/* 32768 Hz clock */
#define RTC_SEC_SHIFT 15
+static bool force_clkm;
+module_param(force_clkm, bool, 0644);
+MODULE_PARM_DESC(force_clkm, "Force CLKM Key, instead of trying to use CLKL");
+
struct macsmc_rtc {
struct device *dev;
struct apple_smc *smc;
struct rtc_device *rtc_dev;
struct nvmem_cell *rtc_offset;
+ uint8_t shift;
+ bool async_rtc;
};
+static int macsmc_rtc_read_clkl(struct macsmc_rtc *rtc, u64 *ctr)
+{
+ u64 request = 0xffffffffffffULL;
+ u64 response = 0;
+ int i, j, ret;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 40; j++) {
+ ret = apple_smc_write(rtc->smc, SMC_KEY(CLKL), &request, RTC_BYTES);
+ if (ret == RTC_BYTES)
+ break;
+ }
+ if (ret != RTC_BYTES)
+ continue;
+
+ msleep(20);
+
+ for (j = 0; j < 20; j++) {
+ ret = apple_smc_read(rtc->smc, SMC_KEY(CLKL), &response, RTC_BYTES);
+ if (ret == RTC_BYTES) {
+ if ((response & 0x7fff) == 5 || (response & 0x7fff) == 6)
+ return -EAGAIN;
+
+ if (response != 0xffffffffffffULL) {
+ *ctr = response;
+ return RTC_BYTES;
+ }
+ }
+ fsleep(1000);
+ }
+ }
+
+ return -EIO;
+}
+
static int macsmc_rtc_get_time(struct device *dev, struct rtc_time *tm)
{
struct macsmc_rtc *rtc = dev_get_drvdata(dev);
@@ -36,25 +80,36 @@ static int macsmc_rtc_get_time(struct device *dev, struct rtc_time *tm)
size_t len;
int ret;
- ret = apple_smc_read(rtc->smc, SMC_KEY(CLKM), &ctr, RTC_BYTES);
+ if (rtc->async_rtc && !force_clkm)
+ ret = macsmc_rtc_read_clkl(rtc, &ctr);
+ else
+ ret = apple_smc_read(rtc->smc, SMC_KEY(CLKM), &ctr, RTC_BYTES);
+
if (ret < 0)
return ret;
if (ret != RTC_BYTES)
return -EIO;
- p_off = nvmem_cell_read(rtc->rtc_offset, &len);
- if (IS_ERR(p_off))
- return PTR_ERR(p_off);
- if (len < RTC_BYTES) {
+ if (rtc->smc->is_acpi) {
+ ret = apple_smc_read(rtc->smc, SMC_KEY(CLKO), &off, RTC_BYTES);
+ if (ret < 0)
+ return ret;
+ if (ret != RTC_BYTES)
+ return -EIO;
+ } else {
+ p_off = nvmem_cell_read(rtc->rtc_offset, &len);
+ if (IS_ERR(p_off))
+ return PTR_ERR(p_off);
+ if (len < RTC_BYTES) {
+ kfree(p_off);
+ return -EIO;
+ }
+
+ memcpy(&off, p_off, RTC_BYTES);
kfree(p_off);
- return -EIO;
}
-
- memcpy(&off, p_off, RTC_BYTES);
- kfree(p_off);
-
/* Sign extend from 48 to 64 bits, then arithmetic shift right 15 bits to get seconds */
- now = sign_extend64(ctr + off, RTC_BITS - 1) >> RTC_SEC_SHIFT;
+ now = sign_extend64(ctr + off, RTC_BITS - 1) >> rtc->shift;
rtc_time64_to_tm(now, tm);
return ret;
@@ -66,14 +121,20 @@ static int macsmc_rtc_set_time(struct device *dev, struct rtc_time *tm)
u64 ctr = 0, off = 0;
int ret;
- ret = apple_smc_read(rtc->smc, SMC_KEY(CLKM), &ctr, RTC_BYTES);
+ if (rtc->async_rtc && !force_clkm)
+ ret = macsmc_rtc_read_clkl(rtc, &ctr);
+ else
+ ret = apple_smc_read(rtc->smc, SMC_KEY(CLKM), &ctr, RTC_BYTES);
if (ret < 0)
return ret;
if (ret != RTC_BYTES)
return -EIO;
/* This sets the offset such that the set second begins now */
- off = (rtc_tm_to_time64(tm) << RTC_SEC_SHIFT) - ctr;
+ off = (rtc_tm_to_time64(tm) << rtc->shift) - ctr;
+ if (rtc->smc->is_acpi)
+ return (apple_smc_write(rtc->smc, SMC_KEY(CLKO), &off, RTC_BYTES) != RTC_BYTES);
+
return nvmem_cell_write(rtc->rtc_offset, &off, RTC_BYTES);
}
@@ -86,13 +147,15 @@ static int macsmc_rtc_probe(struct platform_device *pdev)
{
struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent);
struct macsmc_rtc *rtc;
+ int ret;
+ uint32_t clkr = 0xFFFFFFFF;
/*
* MFD will probe this device even without a node in the device tree,
* thus bail out early if the SMC on the current machines does not
* support RTC and has no node in the device tree.
*/
- if (!pdev->dev.of_node)
+ if (!pdev->dev.of_node && !smc->is_acpi)
return -ENODEV;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@@ -102,18 +165,40 @@ static int macsmc_rtc_probe(struct platform_device *pdev)
rtc->dev = &pdev->dev;
rtc->smc = smc;
- rtc->rtc_offset = devm_nvmem_cell_get(&pdev->dev, "rtc_offset");
- if (IS_ERR(rtc->rtc_offset))
- return dev_err_probe(&pdev->dev, PTR_ERR(rtc->rtc_offset),
- "Failed to get rtc_offset NVMEM cell\n");
+ if (!rtc->smc->is_acpi) {
+ rtc->rtc_offset = devm_nvmem_cell_get(&pdev->dev, "rtc_offset");
+ if (IS_ERR(rtc->rtc_offset))
+ return dev_err_probe(&pdev->dev, PTR_ERR(rtc->rtc_offset),
+ "Failed to get rtc_offset NVMEM cell\n");
+ }
+
+ if (rtc->smc->is_acpi) {
+ ret = apple_smc_read_u32(rtc->smc, SMC_KEY(CLKR), &clkr);
+ if (ret < 0 || clkr == 0xFFFFFFFF)
+ rtc->shift = RTC_SEC_SHIFT;
+ else
+ rtc->shift = ffs(clkr) - 1;
+
+ if (apple_smc_key_exists(rtc->smc, SMC_KEY(CLKL))) {
+ u64 clkl;
+
+ ret = apple_smc_read(rtc->smc, SMC_KEY(CLKL), &clkl, RTC_BYTES);
+ if (ret == RTC_BYTES && clkl != 0xFFFFFFFFFFFFFFFFULL)
+ rtc->async_rtc = true;
+ }
+ } else
+ rtc->shift = RTC_SEC_SHIFT;
+
+ dev_info(&pdev->dev, "%u clock, using %s key\n", (clkr != 0xFFFFFFFF) ? clkr : 32768,
+ rtc->async_rtc ? "CLKL" : "CLKM");
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
rtc->rtc_dev->ops = &macsmc_rtc_ops;
- rtc->rtc_dev->range_min = S64_MIN >> (RTC_SEC_SHIFT + (64 - RTC_BITS));
- rtc->rtc_dev->range_max = S64_MAX >> (RTC_SEC_SHIFT + (64 - RTC_BITS));
+ rtc->rtc_dev->range_min = S64_MIN >> (rtc->shift + (64 - RTC_BITS));
+ rtc->rtc_dev->range_max = S64_MAX >> (rtc->shift + (64 - RTC_BITS));
platform_set_drvdata(pdev, rtc);
@@ -138,3 +223,4 @@ module_platform_driver(macsmc_rtc_driver);
MODULE_LICENSE("Dual MIT/GPL");
MODULE_DESCRIPTION("Apple SMC RTC driver");
MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
+MODULE_ALIAS("platform:macsmc-rtc");
--
2.55.0
next prev parent reply other threads:[~2026-10-29 8:59 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 8:51 [RFC PATCH 00/14] Add macsmc support for Intel Macs, replacing applesmc Atharva Tiwari
2026-10-29 8:51 ` [RFC PATCH 01/14] treewide: Add backend for macsmc Atharva Tiwari
2026-10-29 9:20 ` sashiko-bot
2026-10-29 8:51 ` [RFC PATCH 02/14] platform/x86: add backend for macsmc in intel macs Atharva Tiwari
2026-10-29 9:23 ` sashiko-bot
2026-10-29 12:59 ` Ilpo Järvinen
2026-10-29 8:52 ` [RFC PATCH 03/14] watchdog: add driver for apple smc Atharva Tiwari
2026-10-29 9:17 ` sashiko-bot
2026-10-29 13:30 ` Andy Shevchenko
2026-10-29 8:52 ` [RFC PATCH 04/14] iio/light: add new driver for macsmc Atharva Tiwari
2026-10-29 9:17 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 05/14] iio/accel: add driver for apple SMS Atharva Tiwari
2026-10-29 9:20 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 06/14] leds: add support for macsmc kbl Atharva Tiwari
2026-10-29 9:16 ` sashiko-bot
2026-10-29 8:52 ` Atharva Tiwari [this message]
2026-10-29 9:15 ` [RFC PATCH 07/14] rtc: add support for x86 macs in macsmc-rtc sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 08/14] treewide: Add a flag to detect the Apple T2 chip Atharva Tiwari
2026-10-29 9:11 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 09/14] treewide: disable other rtc's in t2 macs Atharva Tiwari
2026-10-29 9:16 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 10/14] power/supply: add support for x86 macs in macsmc-power Atharva Tiwari
2026-10-29 9:19 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 11/14] acpi: disable battery and adapter for x86 apple machines Atharva Tiwari
2026-10-29 9:13 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 12/14] hwmon/macsmc: add more types Atharva Tiwari
2026-10-29 9:18 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 13/14] hwmon: add support for x86 macs in macsmc-hwmon Atharva Tiwari
2026-10-29 9:20 ` sashiko-bot
2026-10-29 8:52 ` [RFC PATCH 14/14] mfd/macsmc: add ioctl to access smc keys Atharva Tiwari
2026-10-29 9:22 ` Sasha Finkelstein
2026-10-29 14:39 ` Atharva Tiwari
2026-10-29 14:53 ` Sasha Finkelstein
2026-10-29 15:25 ` Aditya Garg
2026-10-29 15:42 ` Sasha Finkelstein
2026-10-29 9:26 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029085504.3547-8-atharvatiwarilinuxdev@gmail.com \
--to=atharvatiwarilinuxdev@gmail.com \
--cc=alexandre.belloni@bootlin.com \
--cc=andy@kernel.org \
--cc=asahi@lists.linux.dev \
--cc=bhelgaas@google.com \
--cc=bp@alien8.de \
--cc=brgl@kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=dlechner@baylibre.com \
--cc=dmitry.kasatkin@gmail.com \
--cc=eric.snowberg@oracle.com \
--cc=griffin@kroah.com \
--cc=hansg@kernel.org \
--cc=hpa@zytor.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=j@jannau.net \
--cc=jarkko@kernel.org \
--cc=jic23@kernel.org \
--cc=jmorris@namei.org \
--cc=keyrings@vger.kernel.org \
--cc=lee@kernel.org \
--cc=lenb@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=linux-watchdog@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mfd@lists.linux.dev \
--cc=mingo@redhat.com \
--cc=neal@gompa.dev \
--cc=nuno.sa@analog.com \
--cc=paul@paul-moore.com \
--cc=pavel@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=roberto.sassu@huawei.com \
--cc=serge@hallyn.com \
--cc=sre@kernel.org \
--cc=sven@kernel.org \
--cc=tglx@kernel.org \
--cc=wim@linux-watchdog.org \
--cc=x86@kernel.org \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox