* [PATCH] rtc: nvvrs: Add ARCH_TEGRA to the NV VRS RTC driver
From: Peter Robinson @ 2025-12-22 3:56 UTC (permalink / raw)
To: Alexandre Belloni, linux-rtc; +Cc: Peter Robinson, Shubhi Garg, Jon Hunter
The NV VRS RTC driver currently is only supported on the
Tegra platform so add a dep for ARCH_TEGRA and compile test
so it doesn't show up universally across all arches/platforms.
Fixes: 9d6d6b06933c8 ("rtc: nvvrs: add NVIDIA VRS RTC device driver")
Cc: Shubhi Garg <shgarg@nvidia.com>
Cc: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
---
drivers/rtc/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 50dc779f7f983..50ba48609d74e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -418,6 +418,7 @@ config RTC_DRV_SPACEMIT_P1
config RTC_DRV_NVIDIA_VRS10
tristate "NVIDIA VRS10 RTC device"
+ depends on ARCH_TEGRA || COMPILE_TEST
help
If you say yes here you will get support for the battery backed RTC device
of NVIDIA VRS (Voltage Regulator Specification). The RTC is connected via
--
2.52.0
^ permalink raw reply related
* Re: [PATCH v3 0/4] fix the SpacemiT P1 Kconfig and resend the K1 I2C ILCR patch.
From: Troy Mitchell @ 2025-12-22 9:36 UTC (permalink / raw)
To: Lee Jones, patchwork-bot+linux-riscv, Konstantin Ryabitsev, tools
Cc: Troy Mitchell, linux-riscv, dlan, elder, andi.shyti,
alexandre.belloni, lgirdwood, broonie, linux-kernel, spacemit,
linux-i2c, linux-rtc
In-Reply-To: <20251219112634.GJ9275@google.com>
On Fri, Dec 19, 2025 at 11:26:34AM +0000, Lee Jones wrote:
> Hi Konstantin,
>
> > This series was applied to riscv/linux.git (fixes)
> > by Alexandre Belloni <alexandre.belloni@bootlin.com>:
> >
> > On Tue, 18 Nov 2025 14:08:04 +0800 you wrote:
> > > Since P1 Kconfig directly selects K1_I2C, after the I2C ILCR patch was
> > > merged, the driver would fail [1] when COMMON_CLK was not selected.
> > >
> > > This series fixes the P1 Kconfig and resends the I2C ILCR patch(This
> > > patch has reverted by maintainer [2]).
> > >
> > > Now, P1 Kconfig patch has been merged[3], so I2C ILCR patch can be
> > > merged as well.
> > >
> > > [...]
> >
> > Here is the summary with links:
> > - [v3,1/4] i2c: spacemit: configure ILCR for accurate SCL frequency
> > (no matching commit)
> > - [v3,2/4] rtc: spacemit: MFD_SPACEMIT_P1 as dependencies
> > https://git.kernel.org/riscv/c/16bd954c9336
> > - [v3,3/4] regulator: spacemit: MFD_SPACEMIT_P1 as dependencies
> > (no matching commit)
>
> > - [v3,4/4] mfd: simple-mfd-i2c: add default value
> > (no matching commit)
>
> I was just about to send another snot-o-gram about people picking up
> patches without the correct Acks, but I just realised this is the same
> Patchwork issue we spoke about a couple of weeks ago.
>
> This formatting is very confusing, since at first blush it looks as
> though the whole patch-set was applied.
>
> Please can we only list patches that were merged?
I agree. At first glance, I also thought the entire series was applied.
- Troy
>
> --
> Lee Jones [李琼斯]
>
^ permalink raw reply
* Re: [PATCH v5 08/11] input: macsmc-input: New driver to handle the Apple Mac SMC buttons/lid
From: Nick Chan @ 2025-12-22 13:50 UTC (permalink / raw)
To: James Calligeros, Sven Peter, Janne Grunau, Alyssa Rosenzweig,
Neal Gompa, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, Jean Delvare, Guenter Roeck,
Dmitry Torokhov, Jonathan Corbet
Cc: asahi, linux-arm-kernel, devicetree, linux-kernel, linux-rtc,
linux-hwmon, linux-input, linux-doc, Hector Martin
In-Reply-To: <20251112-macsmc-subdevs-v5-8-728e4b91fe81@gmail.com>
Hi,
On 12/11/2025 19:16, James Calligeros wrote:
> From: Hector Martin <marcan@marcan.st>
>
> This driver implements power button and lid switch support for Apple Mac
> devices using SMC controllers driven by the macsmc driver.
>
> In addition to basic input support, this also responds to the final
> shutdown warning (when the power button is held down long enough) by
> doing an emergency kernel poweroff. This allows the NVMe controller to
> be cleanly shut down, which prevents data loss for in-cache data.
>
> Reviewed-by: Neal Gompa <neal@gompa.dev>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Co-developed-by: Sven Peter <sven@kernel.org>
> Signed-off-by: Sven Peter <sven@kernel.org>
> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
> ---
> MAINTAINERS | 1 +
> drivers/input/misc/Kconfig | 11 ++
> drivers/input/misc/Makefile | 1 +
> drivers/input/misc/macsmc-input.c | 207 +++++++++++++++++++++++++
> 4 files changed, 220 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fb55a167699e..48bdca6943f3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2455,6 +2455,7 @@ F: drivers/hwmon/macsmc-hwmon.c
> F: drivers/pmdomain/apple/
> F: drivers/i2c/busses/i2c-pasemi-core.c
> F: drivers/i2c/busses/i2c-pasemi-platform.c
> +F: drivers/input/misc/macsmc-input.c
> F: drivers/input/touchscreen/apple_z2.c
> F: drivers/iommu/apple-dart.c
> F: drivers/iommu/io-pgtable-dart.c
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index cc2558630797..1144ba151dbf 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -992,4 +992,15 @@ config INPUT_STPMIC1_ONKEY
> To compile this driver as a module, choose M here: the
> module will be called stpmic1_onkey.
>
> +config INPUT_MACSMC
> + tristate "Apple Mac SMC lid/buttons"
> + depends on MFD_MACSMC
> + help
> + Say Y here if you want to use the input events delivered via the
> + SMC controller on Apple Mac machines using the macsmc driver.
> + This includes lid open/close and the power button.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called macsmc-input.
> +
> endif
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index f5ebfa9d9983..c6394105252f 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT_IQS7222) += iqs7222.o
> obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
> obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
> obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
> +obj-$(CONFIG_INPUT_MACSMC_INPUT) += macsmc-input.o
should be CONFIG_INPUT_MACSMC (alternatively change Kconfig instead)
> obj-$(CONFIG_INPUT_MAX7360_ROTARY) += max7360-rotary.o
> obj-$(CONFIG_INPUT_MAX77650_ONKEY) += max77650-onkey.o
> obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o
> diff --git a/drivers/input/misc/macsmc-input.c b/drivers/input/misc/macsmc-input.c
> new file mode 100644
> index 000000000000..f4598e65fc80
> --- /dev/null
> +++ b/drivers/input/misc/macsmc-input.c
> @@ -0,0 +1,207 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple SMC input event driver
> + * Copyright The Asahi Linux Contributors
> + *
> + * This driver exposes certain events from the SMC as an input device.
> + * This includes the lid open/close and power button notifications.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/input.h>
> +#include <linux/mfd/macsmc.h>
Missing #include <linux/mfd/core.h>
> +#include <linux/module.h>
> +#include <linux/reboot.h>
> +
> +/**
> + * struct macsmc_input
> + * @dev: Underlying struct device for the input sub-device
> + * @smc: Pointer to apple_smc struct of the mfd parent
> + * @input: Allocated input_dev; devres managed
> + * @nb: Notifier block used for incoming events from SMC (e.g. button pressed down)
> + * @wakeup_mode: Set to true when system is suspended and power button events should wake it
> + */
> +struct macsmc_input {
> + struct device *dev;
> + struct apple_smc *smc;
> + struct input_dev *input;
> + struct notifier_block nb;
> + bool wakeup_mode;
> +};
> +
> +#define SMC_EV_BTN 0x7201
> +#define SMC_EV_LID 0x7203
> +
> +#define BTN_POWER 0x01 /* power button on e.g. Mac Mini chasis pressed */
> +#define BTN_TOUCHID 0x06 /* combined TouchID / power button on MacBooks pressed */
> +#define BTN_POWER_HELD_SHORT 0xfe /* power button briefly held down */
> +#define BTN_POWER_HELD_LONG 0x00 /* power button held down; sent just before forced poweroff */
> +
> +static void macsmc_input_event_button(struct macsmc_input *smcin, unsigned long event)
> +{
> + u8 button = (event >> 8) & 0xff;
> + u8 state = !!(event & 0xff);
> +
> + switch (button) {
> + case BTN_POWER:
> + case BTN_TOUCHID:
> + pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && state));
> +
> + /* Suppress KEY_POWER event to prevent immediate shutdown on wake */
> + if (smcin->wakeup_mode)
> + return;
> +
> + input_report_key(smcin->input, KEY_POWER, state);
> + input_sync(smcin->input);
> + break;
> + case BTN_POWER_HELD_SHORT: /* power button held down; ignore */
> + break;
> + case BTN_POWER_HELD_LONG:
> + /*
> + * If we get here the power button has been held down for a while and
> + * we have about 4 seconds before forced power-off is triggered by SMC.
> + * Try to do an emergency shutdown to make sure the NVMe cache is
> + * flushed. macOS actually does this by panicing (!)...
> + */
> + if (state) {
> + dev_crit(smcin->dev, "Triggering forced shutdown!\n");
> + if (kernel_can_power_off())
> + kernel_power_off();
> + else /* Missing macsmc-reboot driver? */
> + kernel_restart("SMC power button triggered restart");
> + }
> + break;
> + default:
> + dev_warn(smcin->dev, "Unknown SMC button event: %04lx\n", event & 0xffff);
> + }
> +}
> +
> +static void macsmc_input_event_lid(struct macsmc_input *smcin, unsigned long event)
> +{
> + u8 lid_state = !!((event >> 8) & 0xff);
> +
> + pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && !lid_state));
> + input_report_switch(smcin->input, SW_LID, lid_state);
> + input_sync(smcin->input);
> +}
> +
> +static int macsmc_input_event(struct notifier_block *nb, unsigned long event, void *data)
> +{
> + struct macsmc_input *smcin = container_of(nb, struct macsmc_input, nb);
> + u16 type = event >> 16;
> +
> + switch (type) {
> + case SMC_EV_BTN:
> + macsmc_input_event_button(smcin, event);
> + return NOTIFY_OK;
> + case SMC_EV_LID:
> + macsmc_input_event_lid(smcin, event);
> + return NOTIFY_OK;
> + default:
> + /* SMC event meant for another driver */
> + return NOTIFY_DONE;
> + }
> +}
> +
> +static int macsmc_input_probe(struct platform_device *pdev)
> +{
> + struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent);
> + struct macsmc_input *smcin;
> + bool have_lid, have_power;
> + int error;
> +
> + /* Bail early if this SMC neither supports power button nor lid events */
> + have_lid = apple_smc_key_exists(smc, SMC_KEY(MSLD));
> + have_power = apple_smc_key_exists(smc, SMC_KEY(bHLD));
> + if (!have_lid && !have_power)
> + return -ENODEV;
> +
> + smcin = devm_kzalloc(&pdev->dev, sizeof(*smcin), GFP_KERNEL);
> + if (!smcin)
> + return -ENOMEM;
> +
> + smcin->dev = &pdev->dev;
> + smcin->smc = smc;
> + platform_set_drvdata(pdev, smcin);
> +
> + smcin->input = devm_input_allocate_device(&pdev->dev);
> + if (!smcin->input)
> + return -ENOMEM;
> +
> + smcin->input->phys = "macsmc-input (0)";
> + smcin->input->name = "Apple SMC power/lid events";
> +
> + if (have_lid)
> + input_set_capability(smcin->input, EV_SW, SW_LID);
> + if (have_power)
> + input_set_capability(smcin->input, EV_KEY, KEY_POWER);
> +
> + if (have_lid) {
> + u8 val;
> +
> + error = apple_smc_read_u8(smc, SMC_KEY(MSLD), &val);
> + if (error < 0)
> + dev_warn(&pdev->dev, "Failed to read initial lid state\n");
> + else
> + input_report_switch(smcin->input, SW_LID, val);
> + }
> +
> + if (have_power) {
> + u32 val;
> +
> + error = apple_smc_read_u32(smc, SMC_KEY(bHLD), &val);
> + if (error < 0)
> + dev_warn(&pdev->dev, "Failed to read initial power button state\n");
> + else
> + input_report_key(smcin->input, KEY_POWER, val & 1);
> + }
> +
> + error = input_register_device(smcin->input);
> + if (error) {
> + dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
> + return error;
> + }
> +
> + input_sync(smcin->input);
> +
> + smcin->nb.notifier_call = macsmc_input_event;
> + blocking_notifier_chain_register(&smc->event_handlers, &smcin->nb);
> +
> + device_init_wakeup(&pdev->dev, true);
> +
> + return 0;
> +}
> +
> +static int macsmc_input_pm_prepare(struct device *dev)
> +{
> + struct macsmc_input *smcin = dev_get_drvdata(dev);
> +
> + smcin->wakeup_mode = true;
> + return 0;
> +}
> +
> +static void macsmc_input_pm_complete(struct device *dev)
> +{
> + struct macsmc_input *smcin = dev_get_drvdata(dev);
> +
> + smcin->wakeup_mode = false;
> +}
> +
> +static const struct dev_pm_ops macsmc_input_pm_ops = {
> + .prepare = macsmc_input_pm_prepare,
> + .complete = macsmc_input_pm_complete,
> +};
> +
> +static struct platform_driver macsmc_input_driver = {
> + .driver = {
> + .name = "macsmc-input",
> + .pm = &macsmc_input_pm_ops,
> + },
> + .probe = macsmc_input_probe,
> +};
> +module_platform_driver(macsmc_input_driver);
> +
> +MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
> +MODULE_LICENSE("Dual MIT/GPL");
> +MODULE_DESCRIPTION("Apple SMC input driver");
> +MODULE_ALIAS("platform:macsmc-input");
>
Best regards,
Nick Chan
^ permalink raw reply
* [PATCH v1 0/2] RTC: Add Loongson-2K0300 support
From: Binbin Zhou @ 2025-12-23 6:42 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc
Cc: Xiaochuang Mao, Huacai Chen, Xuerui Wang, loongarch, devicetree,
linux-mips, Keguang Zhang, Binbin Zhou
Hi all:
This patch set introduces the Loongson-2K0300 RTC, which has a similar
hardware design to the Loongson-1B, but without the alarm feature.
To Keguang:
Would you have time to test the driver on a Loongson-1?
Thanks.
Binbin
Binbin Zhou (2):
dt-binding: rtc: loongson: Document Loongson-2K0300 compatible
rtc: loongson: Add Loongson-2K0300 support
.../devicetree/bindings/rtc/loongson,rtc.yaml | 13 ++++
drivers/rtc/rtc-loongson.c | 65 +++++++++++++------
2 files changed, 57 insertions(+), 21 deletions(-)
base-commit: 16bd954c93360145bc77cc601e350913fc28182d
--
2.47.3
^ permalink raw reply
* [PATCH v1 1/2] dt-binding: rtc: loongson: Document Loongson-2K0300 compatible
From: Binbin Zhou @ 2025-12-23 6:42 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc
Cc: Xiaochuang Mao, Huacai Chen, Xuerui Wang, loongarch, devicetree,
linux-mips, Keguang Zhang, Binbin Zhou
In-Reply-To: <cover.1766471839.git.zhoubinbin@loongson.cn>
Add "loongson,ls2k0300-rtc" dedicated compatible to represent the RTC
interface of the Loongson-2K0300 chip.
Its hardware design is similar to that of the Loongson-1B, but it does
not support the alarm feature.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
.../devicetree/bindings/rtc/loongson,rtc.yaml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml
index f89c1f660aee..aac91c79ffdb 100644
--- a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml
@@ -23,6 +23,7 @@ properties:
- loongson,ls1b-rtc
- loongson,ls1c-rtc
- loongson,ls7a-rtc
+ - loongson,ls2k0300-rtc
- loongson,ls2k1000-rtc
- items:
- enum:
@@ -42,6 +43,18 @@ required:
unevaluatedProperties: false
+if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - loongson,ls1c-rtc
+ - loongson,ls2k0300-rtc
+
+then:
+ properties:
+ interrupts: false
+
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
--
2.47.3
^ permalink raw reply related
* [PATCH v1 2/2] rtc: loongson: Add Loongson-2K0300 support
From: Binbin Zhou @ 2025-12-23 6:42 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc
Cc: Xiaochuang Mao, Huacai Chen, Xuerui Wang, loongarch, devicetree,
linux-mips, Keguang Zhang, Binbin Zhou
In-Reply-To: <cover.1766471839.git.zhoubinbin@loongson.cn>
The Loongson-2K0300's rtc hardware design is similar to that of the
Loongson-1B, but it does not support the alarm feature.
Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that
does not support the alarm function, and rewritethe related logic in
`loongson_rtc_alarm_setting()`
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/rtc/rtc-loongson.c | 65 ++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 21 deletions(-)
diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
index 2ca7ffd5d7a9..6b076bd4e24e 100644
--- a/drivers/rtc/rtc-loongson.c
+++ b/drivers/rtc/rtc-loongson.c
@@ -67,6 +67,7 @@
* Accessing the relevant registers will cause the system to hang.
*/
#define LS1C_RTC_CTRL_WORKAROUND BIT(0)
+#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1)
struct loongson_rtc_config {
u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */
@@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = {
static const struct loongson_rtc_config ls1c_rtc_config = {
.pm_offset = 0,
- .flags = LS1C_RTC_CTRL_WORKAROUND,
+ .flags = LS1C_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND,
};
static const struct loongson_rtc_config generic_rtc_config = {
@@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = {
.flags = 0,
};
+static const struct loongson_rtc_config ls2k0300_rtc_config = {
+ .pm_offset = 0x0,
+ .flags = LOONGSON_RTC_ALARM_WORKAROUND,
+};
+
static const struct loongson_rtc_config ls2k1000_rtc_config = {
.pm_offset = 0x800,
.flags = 0,
@@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = {
.alarm_irq_enable = loongson_rtc_alarm_irq_enable,
};
+static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs)
+{
+ int ret = 0, alarm_irq;
+ struct device *dev = &pdev->dev;
+ struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) {
+ /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */
+ clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
+ return 0;
+ }
+
+ /* Get RTC alarm irq */
+ alarm_irq = platform_get_irq(pdev, 0);
+ if (alarm_irq < 0)
+ return alarm_irq;
+
+ ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm",
+ priv);
+ if (ret < 0)
+ return ret;
+
+ priv->pm_base = regs - priv->config->pm_offset;
+ device_init_wakeup(dev, true);
+
+ if (has_acpi_companion(dev))
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
+ loongson_rtc_handler, priv);
+
+ return ret;
+}
+
static int loongson_rtc_probe(struct platform_device *pdev)
{
- int ret, alarm_irq;
+ int ret;
void __iomem *regs;
struct loongson_rtc_priv *priv;
struct device *dev = &pdev->dev;
@@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->rtcdev),
"devm_rtc_allocate_device failed\n");
- /* Get RTC alarm irq */
- alarm_irq = platform_get_irq(pdev, 0);
- if (alarm_irq > 0) {
- ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr,
- 0, "loongson-alarm", priv);
- if (ret < 0)
- return dev_err_probe(dev, ret, "Unable to request irq %d\n",
- alarm_irq);
-
- priv->pm_base = regs - priv->config->pm_offset;
- device_init_wakeup(dev, true);
-
- if (has_acpi_companion(dev))
- acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
- loongson_rtc_handler, priv);
- } else {
- /* Loongson-1C RTC does not support alarm */
- clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
- }
+ ret = loongson_rtc_alarm_setting(pdev, regs);
+ if (ret)
+ return ret;
/* Loongson RTC does not support UIE */
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features);
@@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = {
{ .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config },
{ .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config },
{ .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config },
+ { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config },
{ .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config },
{ /* sentinel */ }
};
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v1 2/2] rtc: loongson: Add Loongson-2K0300 support
From: Huacai Chen @ 2025-12-23 8:40 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc, Xiaochuang Mao,
Xuerui Wang, loongarch, devicetree, linux-mips, Keguang Zhang
In-Reply-To: <6e10c70653b32f1f79e3f98116924e1aad7154bf.1766471839.git.zhoubinbin@loongson.cn>
Hi, Binbin,
On Tue, Dec 23, 2025 at 2:42 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> The Loongson-2K0300's rtc hardware design is similar to that of the
> Loongson-1B, but it does not support the alarm feature.
>
> Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that
> does not support the alarm function, and rewritethe related logic in
> `loongson_rtc_alarm_setting()`
>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
> drivers/rtc/rtc-loongson.c | 65 ++++++++++++++++++++++++++------------
> 1 file changed, 44 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
> index 2ca7ffd5d7a9..6b076bd4e24e 100644
> --- a/drivers/rtc/rtc-loongson.c
> +++ b/drivers/rtc/rtc-loongson.c
> @@ -67,6 +67,7 @@
> * Accessing the relevant registers will cause the system to hang.
> */
> #define LS1C_RTC_CTRL_WORKAROUND BIT(0)
> +#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1)
Can we reuse existing logic, which means "alarm_irq =
platform_get_irq(pdev, 0)" return 0 for LS2K0300?
Huacai
>
> struct loongson_rtc_config {
> u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */
> @@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = {
>
> static const struct loongson_rtc_config ls1c_rtc_config = {
> .pm_offset = 0,
> - .flags = LS1C_RTC_CTRL_WORKAROUND,
> + .flags = LS1C_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND,
> };
>
> static const struct loongson_rtc_config generic_rtc_config = {
> @@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = {
> .flags = 0,
> };
>
> +static const struct loongson_rtc_config ls2k0300_rtc_config = {
> + .pm_offset = 0x0,
> + .flags = LOONGSON_RTC_ALARM_WORKAROUND,
> +};
> +
> static const struct loongson_rtc_config ls2k1000_rtc_config = {
> .pm_offset = 0x800,
> .flags = 0,
> @@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = {
> .alarm_irq_enable = loongson_rtc_alarm_irq_enable,
> };
>
> +static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs)
> +{
> + int ret = 0, alarm_irq;
> + struct device *dev = &pdev->dev;
> + struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
> +
> + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) {
> + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */
> + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> + return 0;
> + }
> +
> + /* Get RTC alarm irq */
> + alarm_irq = platform_get_irq(pdev, 0);
> + if (alarm_irq < 0)
> + return alarm_irq;
> +
> + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm",
> + priv);
> + if (ret < 0)
> + return ret;
> +
> + priv->pm_base = regs - priv->config->pm_offset;
> + device_init_wakeup(dev, true);
> +
> + if (has_acpi_companion(dev))
> + acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> + loongson_rtc_handler, priv);
> +
> + return ret;
> +}
> +
> static int loongson_rtc_probe(struct platform_device *pdev)
> {
> - int ret, alarm_irq;
> + int ret;
> void __iomem *regs;
> struct loongson_rtc_priv *priv;
> struct device *dev = &pdev->dev;
> @@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev)
> return dev_err_probe(dev, PTR_ERR(priv->rtcdev),
> "devm_rtc_allocate_device failed\n");
>
> - /* Get RTC alarm irq */
> - alarm_irq = platform_get_irq(pdev, 0);
> - if (alarm_irq > 0) {
> - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr,
> - 0, "loongson-alarm", priv);
> - if (ret < 0)
> - return dev_err_probe(dev, ret, "Unable to request irq %d\n",
> - alarm_irq);
> -
> - priv->pm_base = regs - priv->config->pm_offset;
> - device_init_wakeup(dev, true);
> -
> - if (has_acpi_companion(dev))
> - acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> - loongson_rtc_handler, priv);
> - } else {
> - /* Loongson-1C RTC does not support alarm */
> - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> - }
> + ret = loongson_rtc_alarm_setting(pdev, regs);
> + if (ret)
> + return ret;
>
> /* Loongson RTC does not support UIE */
> clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features);
> @@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = {
> { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config },
> { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config },
> { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config },
> + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config },
> { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config },
> { /* sentinel */ }
> };
> --
> 2.47.3
>
>
^ permalink raw reply
* Re: [PATCH v1 2/2] rtc: loongson: Add Loongson-2K0300 support
From: Binbin Zhou @ 2025-12-23 9:06 UTC (permalink / raw)
To: Huacai Chen
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc, Xiaochuang Mao,
Xuerui Wang, loongarch, devicetree, linux-mips, Keguang Zhang
In-Reply-To: <CAAhV-H5WfEhsV4fEzThR-C95cg0nPpJ+OfQ10NXEsFKneJQQ5A@mail.gmail.com>
Hi:
On Tue, Dec 23, 2025 at 4:40 PM Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Binbin,
>
> On Tue, Dec 23, 2025 at 2:42 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
> >
> > The Loongson-2K0300's rtc hardware design is similar to that of the
> > Loongson-1B, but it does not support the alarm feature.
> >
> > Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that
> > does not support the alarm function, and rewritethe related logic in
> > `loongson_rtc_alarm_setting()`
> >
> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > ---
> > drivers/rtc/rtc-loongson.c | 65 ++++++++++++++++++++++++++------------
> > 1 file changed, 44 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
> > index 2ca7ffd5d7a9..6b076bd4e24e 100644
> > --- a/drivers/rtc/rtc-loongson.c
> > +++ b/drivers/rtc/rtc-loongson.c
> > @@ -67,6 +67,7 @@
> > * Accessing the relevant registers will cause the system to hang.
> > */
> > #define LS1C_RTC_CTRL_WORKAROUND BIT(0)
> > +#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1)
> Can we reuse existing logic, which means "alarm_irq =
> platform_get_irq(pdev, 0)" return 0 for LS2K0300?
First of all, as I understand it, platform_get_irq() doesn't normally
return 0 unless interrupt 0 is configured in the DTS, which doesn't
seem appropriate.
Also, the return value of platform_get_irq() was previously used to
determine if the alarm feature was supported, which is not
particularly accurate. It should be an inherent feature of the chip,
and I think it would be more appropriate to define it in
loongson_rtc_config.
>
> Huacai
>
> >
> > struct loongson_rtc_config {
> > u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */
> > @@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = {
> >
> > static const struct loongson_rtc_config ls1c_rtc_config = {
> > .pm_offset = 0,
> > - .flags = LS1C_RTC_CTRL_WORKAROUND,
> > + .flags = LS1C_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND,
> > };
> >
> > static const struct loongson_rtc_config generic_rtc_config = {
> > @@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = {
> > .flags = 0,
> > };
> >
> > +static const struct loongson_rtc_config ls2k0300_rtc_config = {
> > + .pm_offset = 0x0,
> > + .flags = LOONGSON_RTC_ALARM_WORKAROUND,
> > +};
> > +
> > static const struct loongson_rtc_config ls2k1000_rtc_config = {
> > .pm_offset = 0x800,
> > .flags = 0,
> > @@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = {
> > .alarm_irq_enable = loongson_rtc_alarm_irq_enable,
> > };
> >
> > +static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs)
> > +{
> > + int ret = 0, alarm_irq;
> > + struct device *dev = &pdev->dev;
> > + struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
> > +
> > + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) {
> > + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */
> > + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> > + return 0;
> > + }
> > +
> > + /* Get RTC alarm irq */
> > + alarm_irq = platform_get_irq(pdev, 0);
> > + if (alarm_irq < 0)
> > + return alarm_irq;
> > +
> > + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm",
> > + priv);
> > + if (ret < 0)
> > + return ret;
> > +
> > + priv->pm_base = regs - priv->config->pm_offset;
> > + device_init_wakeup(dev, true);
> > +
> > + if (has_acpi_companion(dev))
> > + acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> > + loongson_rtc_handler, priv);
> > +
> > + return ret;
> > +}
> > +
> > static int loongson_rtc_probe(struct platform_device *pdev)
> > {
> > - int ret, alarm_irq;
> > + int ret;
> > void __iomem *regs;
> > struct loongson_rtc_priv *priv;
> > struct device *dev = &pdev->dev;
> > @@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev)
> > return dev_err_probe(dev, PTR_ERR(priv->rtcdev),
> > "devm_rtc_allocate_device failed\n");
> >
> > - /* Get RTC alarm irq */
> > - alarm_irq = platform_get_irq(pdev, 0);
> > - if (alarm_irq > 0) {
> > - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr,
> > - 0, "loongson-alarm", priv);
> > - if (ret < 0)
> > - return dev_err_probe(dev, ret, "Unable to request irq %d\n",
> > - alarm_irq);
> > -
> > - priv->pm_base = regs - priv->config->pm_offset;
> > - device_init_wakeup(dev, true);
> > -
> > - if (has_acpi_companion(dev))
> > - acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> > - loongson_rtc_handler, priv);
> > - } else {
> > - /* Loongson-1C RTC does not support alarm */
> > - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> > - }
> > + ret = loongson_rtc_alarm_setting(pdev, regs);
> > + if (ret)
> > + return ret;
> >
> > /* Loongson RTC does not support UIE */
> > clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features);
> > @@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = {
> > { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config },
> > { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config },
> > { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config },
> > + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config },
> > { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config },
> > { /* sentinel */ }
> > };
> > --
> > 2.47.3
> >
> >
--
Thanks.
Binbin
^ permalink raw reply
* Re: [PATCH v1 2/2] rtc: loongson: Add Loongson-2K0300 support
From: Huacai Chen @ 2025-12-23 9:09 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc, Xiaochuang Mao,
Xuerui Wang, loongarch, devicetree, linux-mips, Keguang Zhang
In-Reply-To: <CAMpQs4LMkq6BpsrnS+e+cvh2hJshO4=41vX4ETq+tkJEMZ7zdA@mail.gmail.com>
On Tue, Dec 23, 2025 at 5:06 PM Binbin Zhou <zhoubb.aaron@gmail.com> wrote:
>
> Hi:
>
>
> On Tue, Dec 23, 2025 at 4:40 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > Hi, Binbin,
> >
> > On Tue, Dec 23, 2025 at 2:42 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
> > >
> > > The Loongson-2K0300's rtc hardware design is similar to that of the
> > > Loongson-1B, but it does not support the alarm feature.
> > >
> > > Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that
> > > does not support the alarm function, and rewritethe related logic in
> > > `loongson_rtc_alarm_setting()`
> > >
> > > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > > ---
> > > drivers/rtc/rtc-loongson.c | 65 ++++++++++++++++++++++++++------------
> > > 1 file changed, 44 insertions(+), 21 deletions(-)
> > >
> > > diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
> > > index 2ca7ffd5d7a9..6b076bd4e24e 100644
> > > --- a/drivers/rtc/rtc-loongson.c
> > > +++ b/drivers/rtc/rtc-loongson.c
> > > @@ -67,6 +67,7 @@
> > > * Accessing the relevant registers will cause the system to hang.
> > > */
> > > #define LS1C_RTC_CTRL_WORKAROUND BIT(0)
> > > +#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1)
> > Can we reuse existing logic, which means "alarm_irq =
> > platform_get_irq(pdev, 0)" return 0 for LS2K0300?
>
> First of all, as I understand it, platform_get_irq() doesn't normally
> return 0 unless interrupt 0 is configured in the DTS, which doesn't
> seem appropriate.
>
> Also, the return value of platform_get_irq() was previously used to
> determine if the alarm feature was supported, which is not
> particularly accurate. It should be an inherent feature of the chip,
> and I think it would be more appropriate to define it in
> loongson_rtc_config.
OK, then I think it is better to rename LS1C_RTC_CTRL_WORKAROUND to
LOONGSON_RTC_CTRL_WORKAROUND for consistency.
Huacai
> >
> > Huacai
> >
> > >
> > > struct loongson_rtc_config {
> > > u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */
> > > @@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = {
> > >
> > > static const struct loongson_rtc_config ls1c_rtc_config = {
> > > .pm_offset = 0,
> > > - .flags = LS1C_RTC_CTRL_WORKAROUND,
> > > + .flags = LS1C_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND,
> > > };
> > >
> > > static const struct loongson_rtc_config generic_rtc_config = {
> > > @@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = {
> > > .flags = 0,
> > > };
> > >
> > > +static const struct loongson_rtc_config ls2k0300_rtc_config = {
> > > + .pm_offset = 0x0,
> > > + .flags = LOONGSON_RTC_ALARM_WORKAROUND,
> > > +};
> > > +
> > > static const struct loongson_rtc_config ls2k1000_rtc_config = {
> > > .pm_offset = 0x800,
> > > .flags = 0,
> > > @@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = {
> > > .alarm_irq_enable = loongson_rtc_alarm_irq_enable,
> > > };
> > >
> > > +static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs)
> > > +{
> > > + int ret = 0, alarm_irq;
> > > + struct device *dev = &pdev->dev;
> > > + struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
> > > +
> > > + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) {
> > > + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */
> > > + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> > > + return 0;
> > > + }
> > > +
> > > + /* Get RTC alarm irq */
> > > + alarm_irq = platform_get_irq(pdev, 0);
> > > + if (alarm_irq < 0)
> > > + return alarm_irq;
> > > +
> > > + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm",
> > > + priv);
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + priv->pm_base = regs - priv->config->pm_offset;
> > > + device_init_wakeup(dev, true);
> > > +
> > > + if (has_acpi_companion(dev))
> > > + acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> > > + loongson_rtc_handler, priv);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > static int loongson_rtc_probe(struct platform_device *pdev)
> > > {
> > > - int ret, alarm_irq;
> > > + int ret;
> > > void __iomem *regs;
> > > struct loongson_rtc_priv *priv;
> > > struct device *dev = &pdev->dev;
> > > @@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev)
> > > return dev_err_probe(dev, PTR_ERR(priv->rtcdev),
> > > "devm_rtc_allocate_device failed\n");
> > >
> > > - /* Get RTC alarm irq */
> > > - alarm_irq = platform_get_irq(pdev, 0);
> > > - if (alarm_irq > 0) {
> > > - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr,
> > > - 0, "loongson-alarm", priv);
> > > - if (ret < 0)
> > > - return dev_err_probe(dev, ret, "Unable to request irq %d\n",
> > > - alarm_irq);
> > > -
> > > - priv->pm_base = regs - priv->config->pm_offset;
> > > - device_init_wakeup(dev, true);
> > > -
> > > - if (has_acpi_companion(dev))
> > > - acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
> > > - loongson_rtc_handler, priv);
> > > - } else {
> > > - /* Loongson-1C RTC does not support alarm */
> > > - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
> > > - }
> > > + ret = loongson_rtc_alarm_setting(pdev, regs);
> > > + if (ret)
> > > + return ret;
> > >
> > > /* Loongson RTC does not support UIE */
> > > clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features);
> > > @@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = {
> > > { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config },
> > > { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config },
> > > { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config },
> > > + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config },
> > > { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config },
> > > { /* sentinel */ }
> > > };
> > > --
> > > 2.47.3
> > >
> > >
>
> --
> Thanks.
> Binbin
^ permalink raw reply
* [PATCH] rtc: s35390a: implement nvmem support
From: Lorenz Brun @ 2025-12-23 12:57 UTC (permalink / raw)
To: Alexandre Belloni; +Cc: linux-rtc, linux-kernel
This RTC has one "free" register which can be used to store arbitrary
data. Expose it as a nvmem resource in Linux.
Signed-off-by: Lorenz Brun <lorenz@monogon.tech>
---
drivers/rtc/rtc-s35390a.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index 3408d2ab2741..2ed39d1c8142 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -18,6 +18,7 @@
#define S35390A_CMD_TIME1 2
#define S35390A_CMD_TIME2 3
#define S35390A_CMD_INT2_REG1 5
+#define S35390A_CMD_FREE_REG 7
#define S35390A_BYTE_YEAR 0
#define S35390A_BYTE_MONTH 1
@@ -416,6 +417,23 @@ static const struct rtc_class_ops s35390a_rtc_ops = {
.ioctl = s35390a_rtc_ioctl,
};
+static int s35390a_nvmem_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct s35390a *s35390a = priv;
+
+ /* The offset is ignored because the NVMEM region is only 1 byte */
+ return s35390a_get_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes);
+}
+
+static int s35390a_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct s35390a *s35390a = priv;
+
+ return s35390a_set_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes);
+}
+
static int s35390a_probe(struct i2c_client *client)
{
int err, err_read;
@@ -424,6 +442,15 @@ static int s35390a_probe(struct i2c_client *client)
struct rtc_device *rtc;
char buf, status1;
struct device *dev = &client->dev;
+ struct nvmem_config nvmem_cfg = {
+ .name = "s35390a_nvram",
+ .type = NVMEM_TYPE_BATTERY_BACKED,
+ .word_size = 1,
+ .stride = 1,
+ .size = 1,
+ .reg_read = s35390a_nvmem_read,
+ .reg_write = s35390a_nvmem_write,
+ };
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
@@ -490,6 +517,11 @@ static int s35390a_probe(struct i2c_client *client)
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(rtc, 1, RTC_AF);
+ nvmem_cfg.priv = s35390a;
+ err = devm_rtc_nvmem_register(rtc, &nvmem_cfg);
+ if (err)
+ return err;
+
return devm_rtc_register_device(rtc);
}
--
2.49.0
^ permalink raw reply related
* RE: [PATCH 3/4] rtc: ds1307: Add Driver for Epson RX8901CE
From: nobuhiro.iwamatsu.x90 @ 2025-12-24 5:05 UTC (permalink / raw)
To: fredrik.m.olsson, alexandre.belloni, robh, krzk+dt, conor+dt
Cc: linux-rtc, devicetree, linux-kernel, kernel
In-Reply-To: <20251219-ds1307-rx8901-add-v1-3-b13f346ebe93@axis.com>
Hi Fredrik,
> -----Original Message-----
> From: Fredrik M Olsson <fredrik.m.olsson@axis.com>
> Sent: Friday, December 19, 2025 9:11 PM
> To: Alexandre Belloni <alexandre.belloni@bootlin.com>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> <conor+dt@kernel.org>; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org; Fredrik M Olsson <fredrik.m.olsson@axis.com>;
> kernel@axis.com
> Subject: [PATCH 3/4] rtc: ds1307: Add Driver for Epson RX8901CE
>
> Adds Support for:
> - Reading and writing time to/from the RTC.
> - Switching to backup battery supply when primary supply disappears.
> - Optionally enabling battery charging.
>
> Signed-off-by: Fredrik M Olsson <fredrik.m.olsson@axis.com>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.x90@mail.toshiba>
Best regards,
Nobuhiro
> ---
> drivers/rtc/rtc-ds1307.c | 62
> ++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 60 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index
> bf42c250ea7d..99d95e520108 100644
> --- a/drivers/rtc/rtc-ds1307.c
> +++ b/drivers/rtc/rtc-ds1307.c
> @@ -48,6 +48,7 @@ enum ds_type {
> mcp794xx,
> rx_8025,
> rx_8130,
> + rx_8901,
> last_ds_type /* always last */
> /* rs5c372 too? different address... */ }; @@ -129,6 +130,12 @@
> enum ds_type {
> #define RX8130_REG_CONTROL1_INIEN BIT(4)
> #define RX8130_REG_CONTROL1_CHGEN BIT(5)
>
> +#define RX8901_REG_INTF 0x0e
> +#define RX8901_REG_INTF_VLF BIT(1)
> +#define RX8901_REG_PWSW_CFG 0x37
> +#define RX8901_REG_PWSW_CFG_INIEN BIT(6)
> +#define RX8901_REG_PWSW_CFG_CHGEN BIT(7)
> +
> #define MCP794XX_REG_CONTROL 0x07
> # define MCP794XX_BIT_ALM0_EN 0x10
> # define MCP794XX_BIT_ALM1_EN 0x20
> @@ -226,6 +233,19 @@ static int ds1307_get_time(struct device *dev, struct
> rtc_time *t)
> dev_warn_once(dev, "oscillator failed, set time!\n");
> return -EINVAL;
> }
> + } else if (ds1307->type == rx_8901) {
> + unsigned int regflag;
> +
> + ret = regmap_read(ds1307->regmap, RX8901_REG_INTF,
> ®flag);
> + if (ret) {
> + dev_err(dev, "%s error %d\n", "read", ret);
> + return ret;
> + }
> +
> + if (regflag & RX8901_REG_INTF_VLF) {
> + dev_warn_once(dev, "oscillator failed, set time!\n");
> + return -EINVAL;
> + }
> }
>
> /* read the RTC date and time registers all at once */ @@ -307,7
> +327,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
> tmp = regs[DS1307_REG_HOUR] & 0x3f;
> t->tm_hour = bcd2bin(tmp);
> /* rx8130 is bit position, not BCD */
> - if (ds1307->type == rx_8130)
> + if (ds1307->type == rx_8130 || ds1307->type == rx_8901)
> t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f) - 1;
> else
> t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
> @@ -358,7 +378,7 @@ static int ds1307_set_time(struct device *dev, struct
> rtc_time *t)
> regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
> regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
> /* rx8130 is bit position, not BCD */
> - if (ds1307->type == rx_8130)
> + if (ds1307->type == rx_8130 || ds1307->type == rx_8901)
> regs[DS1307_REG_WDAY] = 1 << t->tm_wday;
> else
> regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); @@
> -422,6 +442,17 @@ static int ds1307_set_time(struct device *dev, struct
> rtc_time *t)
> dev_err(dev, "%s error %d\n", "write", result);
> return result;
> }
> + } else if (ds1307->type == rx_8901) {
> + /*
> + * clear Voltage Loss Flag as data is available now (writing 1
> + * to the other bits in the INTF register has no effect)
> + */
> + result = regmap_write(ds1307->regmap, RX8901_REG_INTF,
> + 0xff ^ RX8901_REG_INTF_VLF);
> + if (result) {
> + dev_err(dev, "%s error %d\n", "write", result);
> + return result;
> + }
> }
>
> return 0;
> @@ -568,6 +599,17 @@ static u8 do_trickle_setup_rx8130(struct ds1307
> *ds1307, u32 ohms, bool diode)
> return setup;
> }
>
> +static u8 do_trickle_setup_rx8901(struct ds1307 *ds1307, u32 ohms, bool
> +diode) {
> + /* make sure that the backup battery is enabled */
> + u8 setup = RX8901_REG_PWSW_CFG_INIEN;
> +
> + if (diode)
> + setup |= RX8901_REG_PWSW_CFG_CHGEN;
> +
> + return setup;
> +}
> +
> static irqreturn_t rx8130_irq(int irq, void *dev_id) {
> struct ds1307 *ds1307 = dev_id;
> @@ -960,6 +1002,11 @@ static const struct rtc_class_ops rx8130_rtc_ops = {
> .alarm_irq_enable = rx8130_alarm_irq_enable, };
>
> +static const struct rtc_class_ops rx8901_rtc_ops = {
> + .read_time = ds1307_get_time,
> + .set_time = ds1307_set_time,
> +};
> +
> static const struct rtc_class_ops mcp794xx_rtc_ops = {
> .read_time = ds1307_get_time,
> .set_time = ds1307_set_time,
> @@ -1040,6 +1087,12 @@ static const struct chip_desc chips[last_ds_type] = {
> .trickle_charger_reg = RX8130_REG_CONTROL1,
> .do_trickle_setup = &do_trickle_setup_rx8130,
> },
> + [rx_8901] = {
> + .offset = 0x0,
> + .rtc_ops = &rx8901_rtc_ops,
> + .trickle_charger_reg = RX8901_REG_PWSW_CFG,
> + .do_trickle_setup = &do_trickle_setup_rx8901,
> + },
> [m41t0] = {
> .rtc_ops = &m41txx_rtc_ops,
> },
> @@ -1081,6 +1134,7 @@ static const struct i2c_device_id ds1307_id[] = {
> { "rx8025", rx_8025 },
> { "isl12057", ds_1337 },
> { "rx8130", rx_8130 },
> + { "rx8901", rx_8901 },
> { }
> };
> MODULE_DEVICE_TABLE(i2c, ds1307_id);
> @@ -1158,6 +1212,10 @@ static const struct of_device_id ds1307_of_match[]
> = {
> .compatible = "epson,rx8130",
> .data = (void *)rx_8130
> },
> + {
> + .compatible = "epson,rx8901",
> + .data = (void *)rx_8901
> + },
> { }
> };
> MODULE_DEVICE_TABLE(of, ds1307_of_match);
>
> --
> 2.43.0
^ permalink raw reply
* RE: [PATCH 4/4] rtc: ds1307: Add support for reading RX8901CE battery VL status
From: nobuhiro.iwamatsu.x90 @ 2025-12-24 5:07 UTC (permalink / raw)
To: fredrik.m.olsson, alexandre.belloni, robh, krzk+dt, conor+dt
Cc: linux-rtc, devicetree, linux-kernel, kernel
In-Reply-To: <20251219-ds1307-rx8901-add-v1-4-b13f346ebe93@axis.com>
Hi Fredrik,
> -----Original Message-----
> From: Fredrik M Olsson <fredrik.m.olsson@axis.com>
> Sent: Friday, December 19, 2025 9:11 PM
> To: Alexandre Belloni <alexandre.belloni@bootlin.com>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> <conor+dt@kernel.org>; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org; Fredrik M Olsson <fredrik.m.olsson@axis.com>;
> kernel@axis.com
> Subject: [PATCH 4/4] rtc: ds1307: Add support for reading RX8901CE battery
> VL status
>
> Adds support for:
> - Reading the battery voltage low status using the RTC_VL_READ ioctl,
> which also reports invalid time information if the VLF flag is set.
>
> Signed-off-by: Fredrik M Olsson <fredrik.m.olsson@axis.com>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.x90@mail.toshiba>
Best regards,
Nobuhiro
> ---
> drivers/rtc/rtc-ds1307.c | 46
> +++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index
> 99d95e520108..ca062ed0c867 100644
> --- a/drivers/rtc/rtc-ds1307.c
> +++ b/drivers/rtc/rtc-ds1307.c
> @@ -133,8 +133,11 @@ enum ds_type {
> #define RX8901_REG_INTF 0x0e
> #define RX8901_REG_INTF_VLF BIT(1)
> #define RX8901_REG_PWSW_CFG 0x37
> +#define RX8901_REG_PWSW_CFG_VBATLDETEN BIT(4)
> #define RX8901_REG_PWSW_CFG_INIEN BIT(6)
> #define RX8901_REG_PWSW_CFG_CHGEN BIT(7)
> +#define RX8901_REG_BUF_INTF 0x46
> +#define RX8901_REG_BUF_INTF_VBATLF BIT(3)
>
> #define MCP794XX_REG_CONTROL 0x07
> # define MCP794XX_BIT_ALM0_EN 0x10
> @@ -458,6 +461,39 @@ static int ds1307_set_time(struct device *dev, struct
> rtc_time *t)
> return 0;
> }
>
> +#ifdef CONFIG_RTC_INTF_DEV
> +static int rx8901_ioctl(struct device *dev, unsigned int cmd, unsigned
> +long arg) {
> + struct ds1307 *ds1307 = dev_get_drvdata(dev);
> + unsigned int regflag, tmp = 0;
> + int ret = 0;
> +
> + switch (cmd) {
> + case RTC_VL_READ:
> + ret = regmap_read(ds1307->regmap, RX8901_REG_INTF,
> ®flag);
> + if (ret)
> + return ret;
> +
> + if (regflag & RX8901_REG_INTF_VLF)
> + tmp |= RTC_VL_DATA_INVALID;
> +
> + ret = regmap_read(ds1307->regmap, RX8901_REG_BUF_INTF,
> ®flag);
> + if (ret)
> + return ret;
> +
> + if (regflag & RX8901_REG_BUF_INTF_VBATLF)
> + tmp |= RTC_VL_BACKUP_LOW;
> +
> + return put_user(tmp, (unsigned int __user *)arg);
> + default:
> + return -ENOIOCTLCMD;
> + }
> + return ret;
> +}
> +#else
> +#define rx8901_ioctl NULL
> +#endif
> +
> static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) {
> struct ds1307 *ds1307 = dev_get_drvdata(dev);
> @@ -599,10 +635,13 @@ static u8 do_trickle_setup_rx8130(struct ds1307
> *ds1307, u32 ohms, bool diode)
> return setup;
> }
>
> -static u8 do_trickle_setup_rx8901(struct ds1307 *ds1307, u32 ohms, bool
> diode)
> +static u8 do_trickle_setup_rx8901(struct ds1307 *ds1307, u32 ohms
> +__always_unused, bool diode)
> {
> - /* make sure that the backup battery is enabled */
> - u8 setup = RX8901_REG_PWSW_CFG_INIEN;
> + /*
> + * make sure that the backup battery is enabled and that battery
> + * voltage detection is performed
> + */
> + u8 setup = RX8901_REG_PWSW_CFG_INIEN |
> RX8901_REG_PWSW_CFG_VBATLDETEN;
>
> if (diode)
> setup |= RX8901_REG_PWSW_CFG_CHGEN;
> @@ -1005,6 +1044,7 @@ static const struct rtc_class_ops rx8130_rtc_ops =
> { static const struct rtc_class_ops rx8901_rtc_ops = {
> .read_time = ds1307_get_time,
> .set_time = ds1307_set_time,
> + .ioctl = rx8901_ioctl,
> };
>
> static const struct rtc_class_ops mcp794xx_rtc_ops = {
>
> --
> 2.43.0
^ permalink raw reply
* RE: [PATCH 2/4] rtc: ds1307: Fix off-by-one issue with wday for rx8130
From: nobuhiro.iwamatsu.x90 @ 2025-12-24 5:06 UTC (permalink / raw)
To: fredrik.m.olsson, alexandre.belloni, robh, krzk+dt, conor+dt
Cc: linux-rtc, devicetree, linux-kernel, kernel
In-Reply-To: <20251219-ds1307-rx8901-add-v1-2-b13f346ebe93@axis.com>
Hi Fredrik,
> -----Original Message-----
> From: Fredrik M Olsson <fredrik.m.olsson@axis.com>
> Sent: Friday, December 19, 2025 9:11 PM
> To: Alexandre Belloni <alexandre.belloni@bootlin.com>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> <conor+dt@kernel.org>; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org; Fredrik M Olsson <fredrik.m.olsson@axis.com>;
> kernel@axis.com
> Subject: [PATCH 2/4] rtc: ds1307: Fix off-by-one issue with wday for rx8130
>
> The RTC represent each weekday with a individual bit set in the WDAY register,
> where the 0th bit represent the first day of the week and the 6th bit represents
> the last day of the week. For each passed day the chip performs a
> rotary-left-shift by one to advance the weekday by one.
>
> The tm_wday field represent weekdays by a value in the range of 0-6.
>
> The fls() function return the bit index of the last bit set. To handle when there
> are no bits set it will return 0, and if the 0th bit is set it will return 1, and if the
> 1st bit is set it will return 2, and so on.
>
> In order to make the result of the fls() function fall into the expected range of
> 0-6 (instead of 1-7) this patch subtracts one from the result (which matches
> how the value is written in ds1307_set_time()).
>
> Fixes: 204756f016726 ("rtc: ds1307: Fix wday settings for rx8130")
> Signed-off-by: Fredrik M Olsson <fredrik.m.olsson@axis.com>
Thanks for fixing.
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.x90@mail.toshiba>
Best regards,
Nobuhiro
> ---
> drivers/rtc/rtc-ds1307.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index
> 7205c59ff729..bf42c250ea7d 100644
> --- a/drivers/rtc/rtc-ds1307.c
> +++ b/drivers/rtc/rtc-ds1307.c
> @@ -308,7 +308,7 @@ static int ds1307_get_time(struct device *dev, struct
> rtc_time *t)
> t->tm_hour = bcd2bin(tmp);
> /* rx8130 is bit position, not BCD */
> if (ds1307->type == rx_8130)
> - t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f);
> + t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f) - 1;
> else
> t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
> t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
>
> --
> 2.43.0
^ permalink raw reply
* RE: [PATCH 1/4] dt-bindings: rtc: ds1307: Add epson,rx8901
From: nobuhiro.iwamatsu.x90 @ 2025-12-24 5:04 UTC (permalink / raw)
To: fredrik.m.olsson, alexandre.belloni, robh, krzk+dt, conor+dt
Cc: linux-rtc, devicetree, linux-kernel, kernel
In-Reply-To: <20251219-ds1307-rx8901-add-v1-1-b13f346ebe93@axis.com>
Hi Fredrik,
> -----Original Message-----
> From: Fredrik M Olsson <fredrik.m.olsson@axis.com>
> Sent: Friday, December 19, 2025 9:11 PM
> To: Alexandre Belloni <alexandre.belloni@bootlin.com>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> <conor+dt@kernel.org>; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org; Fredrik M Olsson <fredrik.m.olsson@axis.com>;
> kernel@axis.com
> Subject: [PATCH 1/4] dt-bindings: rtc: ds1307: Add epson,rx8901
>
> Add compatible string epson,rx8901 for the Epson RX8901CE RTC.
>
> Signed-off-by: Fredrik M Olsson <fredrik.m.olsson@axis.com>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@mail.toshiba>
Best regards,
Nobuhiro
> ---
> Documentation/devicetree/bindings/rtc/rtc-ds1307.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1307.yaml
> b/Documentation/devicetree/bindings/rtc/rtc-ds1307.yaml
> index 98d10e680144..9b2796804f07 100644
> --- a/Documentation/devicetree/bindings/rtc/rtc-ds1307.yaml
> +++ b/Documentation/devicetree/bindings/rtc/rtc-ds1307.yaml
> @@ -31,6 +31,7 @@ properties:
> - epson,rx8025
> - isil,isl12057
> - epson,rx8130
> + - epson,rx8901
>
> - items:
> - enum:
>
> --
> 2.43.0
^ permalink raw reply
* [PATCH v4 0/3] spacemit: fix P1 sub-device Kconfig defaults and dependencies
From: Troy Mitchell @ 2025-12-25 7:46 UTC (permalink / raw)
To: Lee Jones, Yixun Lan, Alex Elder, Andi Shyti, Alexandre Belloni,
Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc,
Troy Mitchell
This series fixes Kconfig default value and dependency handling for
the SpacemiT P1 PMIC and its sub-devices.
Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
---
Troy Mitchell (3):
regulator: spacemit: MFD_SPACEMIT_P1 as dependencies
mfd: simple-mfd-i2c: add default value
rtc: spacemit: default module when MFD_SPACEMIT_P1 is enabled
drivers/mfd/Kconfig | 1 +
drivers/regulator/Kconfig | 5 ++---
drivers/rtc/Kconfig | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
---
base-commit: b87881a3c93345252ce8559ad763369febfdb75d
change-id: 20251021-p1-kconfig-fix-6d2b59d03b8f
Best regards,
--
Troy Mitchell <troy.mitchell@linux.spacemit.com>
^ permalink raw reply
* [PATCH v4 1/3] regulator: spacemit: MFD_SPACEMIT_P1 as dependencies
From: Troy Mitchell @ 2025-12-25 7:46 UTC (permalink / raw)
To: Lee Jones, Yixun Lan, Alex Elder, Andi Shyti, Alexandre Belloni,
Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc,
Troy Mitchell
In-Reply-To: <20251225-p1-kconfig-fix-v4-0-44b6728117c1@linux.spacemit.com>
REGULATOR_SPACEMIT_P1 is a subdevice of P1 and should depend on
MFD_SPACEMIT_P1 rather than selecting it directly. Using 'select'
does not always respect the parent's dependencies, so 'depends on'
is the safer and more correct choice.
Since MFD_SPACEMIT_P1 already depends on I2C_K1, the dependency
in REGULATOR_SPACEMIT_P1 is now redundant.
Additionally, the default value depends on MFD_SPACEMIT_P1 rather
than ARCH_SPACEMIT.
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Alex Elder <elder@riscstar.com>
Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
---
Change log in v4:
- default m if MFD_SPACEMIT_P1 instead of default MFD_SPACEMIT_P1
Link to v3: https://lore.kernel.org/all/20251118-p1-kconfig-fix-v3-3-8839c5ac5db3@linux.spacemit.com/
Changelog in v3:
- modify commit message
- change default value from ARCH_SPACEMIT to MFD_SPACEMIT_P1
- Link to v2: https://lore.kernel.org/all/20251027-p1-kconfig-fix-v2-4-49688f30bae8@linux.spacemit.com/
---
drivers/regulator/Kconfig | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index d2335276cce5ffbd500bbaf251d1761a9116aee9..b51888a9a78f399a6af3294fc19f60792576332c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1496,9 +1496,8 @@ config REGULATOR_SLG51000
config REGULATOR_SPACEMIT_P1
tristate "SpacemiT P1 regulators"
depends on ARCH_SPACEMIT || COMPILE_TEST
- depends on I2C
- select MFD_SPACEMIT_P1
- default ARCH_SPACEMIT
+ depends on MFD_SPACEMIT_P1
+ default m if MFD_SPACEMIT_P1
help
Enable support for regulators implemented by the SpacemiT P1
power controller. The P1 implements 6 high-efficiency buck
--
2.52.0
^ permalink raw reply related
* [PATCH v4 2/3] mfd: simple-mfd-i2c: add default value
From: Troy Mitchell @ 2025-12-25 7:46 UTC (permalink / raw)
To: Lee Jones, Yixun Lan, Alex Elder, Andi Shyti, Alexandre Belloni,
Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc,
Troy Mitchell
In-Reply-To: <20251225-p1-kconfig-fix-v4-0-44b6728117c1@linux.spacemit.com>
The default value of the P1 sub-device depends on the value
of P1, so P1 should have a default value here.
Acked-by: Alex Elder <elder@riscstar.com>
Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
---
Change log in v4:
- default m if ARCH_SPACEMIT instead of default ARCH_SPACEMIT
- Link to v3: https://lore.kernel.org/all/20251118-p1-kconfig-fix-v3-4-8839c5ac5db3@linux.spacemit.com/
---
drivers/mfd/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index aace5766b38aa5e46e32a8a7b42eea238159fbcf..c757bc365029dc794c658fc5b10084a0f29ac9b6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1276,6 +1276,7 @@ config MFD_SPACEMIT_P1
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on I2C
select MFD_SIMPLE_MFD_I2C
+ default m if ARCH_SPACEMIT
help
This option supports the I2C-based SpacemiT P1 PMIC, which
contains regulators, a power switch, GPIOs, an RTC, and more.
--
2.52.0
^ permalink raw reply related
* [PATCH v4 3/3] rtc: spacemit: default module when MFD_SPACEMIT_P1 is enabled
From: Troy Mitchell @ 2025-12-25 7:46 UTC (permalink / raw)
To: Lee Jones, Yixun Lan, Alex Elder, Andi Shyti, Alexandre Belloni,
Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc,
Troy Mitchell
In-Reply-To: <20251225-p1-kconfig-fix-v4-0-44b6728117c1@linux.spacemit.com>
The RTC driver defaulted to the same value as MFD_SPACEMIT_P1, which
caused it to be built-in automatically whenever the PMIC support was
set to y.
This is not always desirable, as the RTC function is not required on
all platforms using the SpacemiT P1 PMIC.
Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
---
drivers/rtc/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 50dc779f7f983074df7882200c90f0df21d142f2..53866493e9bbaf35ff0de85cbfe43e8343eadc1e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -410,7 +410,7 @@ config RTC_DRV_SPACEMIT_P1
tristate "SpacemiT P1 RTC"
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on MFD_SPACEMIT_P1
- default MFD_SPACEMIT_P1
+ default m if MFD_SPACEMIT_P1
help
Enable support for the RTC function in the SpacemiT P1 PMIC.
This driver can also be built as a module, which will be called
--
2.52.0
^ permalink raw reply related
* Re: [PATCH v4 3/3] rtc: spacemit: default module when MFD_SPACEMIT_P1 is enabled
From: Alexandre Belloni @ 2025-12-25 16:53 UTC (permalink / raw)
To: Troy Mitchell
Cc: Lee Jones, Yixun Lan, Alex Elder, Andi Shyti, Liam Girdwood,
Mark Brown, linux-kernel, linux-riscv, spacemit, linux-i2c,
linux-rtc
In-Reply-To: <20251225-p1-kconfig-fix-v4-3-44b6728117c1@linux.spacemit.com>
On 25/12/2025 15:46:33+0800, Troy Mitchell wrote:
> The RTC driver defaulted to the same value as MFD_SPACEMIT_P1, which
> caused it to be built-in automatically whenever the PMIC support was
> set to y.
>
> This is not always desirable, as the RTC function is not required on
> all platforms using the SpacemiT P1 PMIC.
But then, can't people simply change the config? I don't feel like
this is an improvement.
>
> Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> ---
> drivers/rtc/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 50dc779f7f983074df7882200c90f0df21d142f2..53866493e9bbaf35ff0de85cbfe43e8343eadc1e 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -410,7 +410,7 @@ config RTC_DRV_SPACEMIT_P1
> tristate "SpacemiT P1 RTC"
> depends on ARCH_SPACEMIT || COMPILE_TEST
> depends on MFD_SPACEMIT_P1
> - default MFD_SPACEMIT_P1
> + default m if MFD_SPACEMIT_P1
> help
> Enable support for the RTC function in the SpacemiT P1 PMIC.
> This driver can also be built as a module, which will be called
>
> --
> 2.52.0
>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v3 1/4] i2c: spacemit: configure ILCR for accurate SCL frequency
From: Troy Mitchell @ 2025-12-26 5:58 UTC (permalink / raw)
To: Alex Elder, Troy Mitchell, Lee Jones, Yixun Lan, Andi Shyti,
Alexandre Belloni, Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc
In-Reply-To: <81eca0ab-47a3-4b12-98ae-fbd46a15ff93@riscstar.com>
On Tue, Nov 18, 2025 at 11:32:44AM -0600, Alex Elder wrote:
> On 11/18/25 12:08 AM, Troy Mitchell wrote:
> > The SpacemiT I2C controller's SCL (Serial Clock Line) frequency for
> > master mode operations is determined by the ILCR (I2C Load Count Register).
> > Previously, the driver relied on the hardware's reset default
> > values for this register.
> >
> > The hardware's default ILCR values (SLV=0x156, FLV=0x5d) yield SCL
> > frequencies lower than intended. For example, with the default
> > 31.5 MHz input clock, these default settings result in an SCL
> > frequency of approximately 93 kHz (standard mode) when targeting 100 kHz,
> > and approximately 338 kHz (fast mode) when targeting 400 kHz.
> > These frequencies are below the 100 kHz/400 kHz nominal speeds.
> >
> > This patch integrates the SCL frequency management into
> > the Common Clock Framework (CCF). Specifically, the ILCR register,
> > which acts as a frequency divider for the SCL clock, is now registered
> > as a managed clock (scl_clk) within the CCF.
> >
> > This patch also cleans up unnecessary whitespace
> > in the included header files.
>
> I have a few comments below. Sorry I didn't comment on
> earlier versions. > Reviewed-by: Yixun Lan <dlan@gentoo.org>
> > Link: https://lore.kernel.org/all/176244506110.1925720.10807118665958896958.b4-ty@kernel.org/ [1]
> > Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> > ---
> > This patch was affected by the P1 Kconfig, which caused the maintainer
> > to revert it.
> > The current commit is a direct cherry-pick and reserves the original changelog.
> > This note is to clarify for anyone who sees the cover letter marked as v2
> > while the changelog entries reach v4.
> > ---
> > Changelog in v4:
> > - initialize clk_init_data with {} so that init.flags is implicitly set to 0
> > - minor cleanup and style fixes for better readability
> > - remove unused spacemit_i2c_scl_clk_exclusive_put() cleanup callback
> > - replace clk_set_rate_exclusive()/clk_rate_exclusive_put() pair with clk_set_rate()
> > - simplify LCR LV field macros by using FIELD_GET/FIELD_MAX helpers
> > - Link to v3: https://lore.kernel.org/all/20250814-k1-i2c-ilcr-v3-1-317723e74bcd@linux.spacemit.com/
> >
> > Changelog in v3:
> > - use MASK macro in `recalc_rate` function
> > - rename clock name
> > - Link to v2: https://lore.kernel.org/r/20250718-k1-i2c-ilcr-v2-1-b4c68f13dcb1@linux.spacemit.com
> >
> > Changelog in v2:
> > - Align line breaks.
> > - Check `lv` in `clk_set_rate` function.
> > - Force fast mode when SCL frequency is illegal or unavailable.
> > - Change "linux/bits.h" to <linux/bits.h>
> > - Kconfig: Add dependency on CCF.
> > - Link to v1: https://lore.kernel.org/all/20250710-k1-i2c-ilcr-v1-1-188d1f460c7d@linux.spacemit.com/
> > ---
> > drivers/i2c/busses/Kconfig | 2 +-
> > drivers/i2c/busses/i2c-k1.c | 159 ++++++++++++++++++++++++++++++++++++++++----
> > 2 files changed, 146 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> > index fd81e49638aaa161ae264a722e9e06adc7914cda..fedf5d31f9035b73a27a7f8a764bf5c26975d0e1 100644
> > --- a/drivers/i2c/busses/Kconfig
> > +++ b/drivers/i2c/busses/Kconfig
> > @@ -798,7 +798,7 @@ config I2C_JZ4780
> > config I2C_K1
> > tristate "SpacemiT K1 I2C adapter"
> > depends on ARCH_SPACEMIT || COMPILE_TEST
> > - depends on OF
> > + depends on OF && COMMON_CLK
> > help
> > This option enables support for the I2C interface on the SpacemiT K1
> > platform.
> > diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
> > index 6b918770e612e098b8ad17418f420d87c94df166..e38a0ba71734ca602854c85672dcb61423453515 100644
> > --- a/drivers/i2c/busses/i2c-k1.c
> > +++ b/drivers/i2c/busses/i2c-k1.c
> > @@ -4,18 +4,21 @@
> > */
> > #include <linux/bitfield.h>
> > - #include <linux/clk.h>
> > - #include <linux/i2c.h>
> > - #include <linux/iopoll.h>
> > - #include <linux/module.h>
> > - #include <linux/of_address.h>
> > - #include <linux/platform_device.h>
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/i2c.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > /* spacemit i2c registers */
> > #define SPACEMIT_ICR 0x0 /* Control register */
> > #define SPACEMIT_ISR 0x4 /* Status register */
> > #define SPACEMIT_IDBR 0xc /* Data buffer register */
> > #define SPACEMIT_IRCR 0x18 /* Reset cycle counter */
> > +#define SPACEMIT_ILCR 0x10 /* Load Count Register */
> > #define SPACEMIT_IBMR 0x1c /* Bus monitor register */
> > /* SPACEMIT_ICR register fields */
> > @@ -87,6 +90,13 @@
> > #define SPACEMIT_BMR_SDA BIT(0) /* SDA line level */
> > #define SPACEMIT_BMR_SCL BIT(1) /* SCL line level */
> > +#define SPACEMIT_LCR_LV_STANDARD_SHIFT 0
> > +#define SPACEMIT_LCR_LV_FAST_SHIFT 9
>
> Why do you need these SHIFT symbols? Just use the masks
> and FIELD_GET() related macros. I'll provide examples below.
>
> > +#define SPACEMIT_LCR_LV_STANDARD_MASK GENMASK(8, 0)
> > +#define SPACEMIT_LCR_LV_FAST_MASK GENMASK(17, 9)
> > +#define SPACEMIT_LCR_LV_STANDARD_MAX_VALUE FIELD_MAX(SPACEMIT_LCR_LV_STANDARD_MASK)
> > +#define SPACEMIT_LCR_LV_FAST_MAX_VALUE FIELD_MAX(SPACEMIT_LCR_LV_FAST_MASK)
> > +
> > /* i2c bus recover timeout: us */
> > #define SPACEMIT_I2C_BUS_BUSY_TIMEOUT 100000
> > @@ -104,11 +114,20 @@ enum spacemit_i2c_state {
> > SPACEMIT_STATE_WRITE,
> > };
> > +enum spacemit_i2c_mode {
> > + SPACEMIT_MODE_STANDARD,
> > + SPACEMIT_MODE_FAST
> > +};
>
> Will there ever be more than two i2c modes? If not, this
> could simply be a Boolean.
Yes, Will. See below.
>
> > +
> > /* i2c-spacemit driver's main struct */
> > struct spacemit_i2c_dev {
> > struct device *dev;
> > struct i2c_adapter adapt;
> > + struct clk_hw scl_clk_hw;
> > + struct clk *scl_clk;
> > + enum spacemit_i2c_mode mode;
>
> Perhaps this could be:
>
> bool fast_mode;
hardware also supports high-speed mode.
>
> > +
> > /* hardware resources */
> > void __iomem *base;
> > int irq;
> > @@ -129,6 +148,79 @@ struct spacemit_i2c_dev {
> > u32 status;
> > };
> > +static void spacemit_i2c_scl_clk_disable_unprepare(void *data)
> > +{
> > + struct spacemit_i2c_dev *i2c = data;
> > +
> > + clk_disable_unprepare(i2c->scl_clk);
> > +}
> > +
> > +static int spacemit_i2c_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long parent_rate)
> > +{
> > + struct spacemit_i2c_dev *i2c = container_of(hw, struct spacemit_i2c_dev, scl_clk_hw);
> > + u32 lv, lcr, mask, shift, max_lv;
> > +
> > + lv = DIV_ROUND_UP(parent_rate, rate);
>
> Would DIV_ROUND_CLOSEST() give a more accurate value?
I'll test it.
>
> > +
> > + if (i2c->mode == SPACEMIT_MODE_STANDARD) {
> > + mask = SPACEMIT_LCR_LV_STANDARD_MASK;
> > + shift = SPACEMIT_LCR_LV_STANDARD_SHIFT;
> > + max_lv = SPACEMIT_LCR_LV_STANDARD_MAX_VALUE;
> > + } else if (i2c->mode == SPACEMIT_MODE_FAST) {
> > + mask = SPACEMIT_LCR_LV_FAST_MASK;
> > + shift = SPACEMIT_LCR_LV_FAST_SHIFT;
> > + max_lv = SPACEMIT_LCR_LV_FAST_MAX_VALUE;
> > + }
> > +
> > + if (!lv || lv > max_lv) {
> > + dev_err(i2c->dev, "set scl clock failed: lv 0x%x", lv);
> > + return -EINVAL;
> > + }
> > +
> > + lcr = readl(i2c->base + SPACEMIT_ILCR);
> > + lcr &= ~mask;
> > + lcr |= lv << shift;
> > + writel(lcr, i2c->base + SPACEMIT_ILCR);
>
> FIELD_MODIFY(mask, &lcr, lv);
>
> I suppose this might give you trouble because the mask isn't
> constant at compile time, but anyway I think something like
> this is simpler:
>
> lv = DIV_ROUND_CLOSEST(parent_rate, rate);
> lcr = readl(i2c->base + SPACEMIT_ILCR);
> if (i2c->fast_mode)
> FIELD_MODIFY(SPACEMIT_LCR_LV_FAST_MASK, &lcr, lv);
> else
> FIELD_MODIFY(SPACEMIT_LCR_LV_STANDARD_MASK, &lcr, lv);
> writel(lcr, i2c->base + SPACEMIT_ILCR);
>
> Note: I've never used FIELD_MODIFY(), but it looks like this is
> how it's supposed to be used.
Thanks! I'll give it a go.
>
> > + return 0;
> > +}
> > +
> > +static long spacemit_i2c_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long *parent_rate)
> > +{
> > + u32 lv, freq;
> > +
> > + lv = DIV_ROUND_UP(*parent_rate, rate);
> > + freq = DIV_ROUND_UP(*parent_rate, lv);
>
> Consider whether DIV_ROUND_CLOSEST() (in one or both of
> these) provides a rate that is as close as possible to the
> requested rate.
>
> > +
> > + return freq;
> > +}
> > +
> > +static unsigned long spacemit_i2c_clk_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct spacemit_i2c_dev *i2c = container_of(hw, struct spacemit_i2c_dev, scl_clk_hw);
> > + u32 lcr, lv = 0;
> > +
> > + lcr = readl(i2c->base + SPACEMIT_ILCR);
> > +
> > + if (i2c->mode == SPACEMIT_MODE_STANDARD)
> > + lv = FIELD_GET(SPACEMIT_LCR_LV_STANDARD_MASK, lcr);
> > + else if (i2c->mode == SPACEMIT_MODE_FAST)
> > + lv = FIELD_GET(SPACEMIT_LCR_LV_FAST_MASK, lcr);
> > + else
> > + return 0;
>
> You shouldn't need the last else here. You can probably tell
> by inspection that it will always be one mode or the other.
> And a Boolean reinforces that.
I'll drop else here.
>
> > +
> > + return DIV_ROUND_UP(parent_rate, lv);
> > +}
> > +
> > +static const struct clk_ops spacemit_i2c_clk_ops = {
> > + .set_rate = spacemit_i2c_clk_set_rate,
> > + .round_rate = spacemit_i2c_clk_round_rate,
> > + .recalc_rate = spacemit_i2c_clk_recalc_rate,
> > +};
> > +
> > static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
> > {
> > u32 val;
> > @@ -147,6 +239,26 @@ static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
> > writel(val, i2c->base + SPACEMIT_ICR);
> > }
> > +static struct clk *spacemit_i2c_register_scl_clk(struct spacemit_i2c_dev *i2c,
> > + struct clk *parent)
> > +{
> > + struct clk_init_data init = {};
> > + char name[32];
> > +
> > + snprintf(name, sizeof(name), "%s_scl_clk", dev_name(i2c->dev));
>
> What if dev_name(i2c->dev) is longer than 24? You should
> be checking the return value here.
Thanks! I'll check the return value and extend the array size to 64.
>
> > +
> > + init.name = name;
> > + init.ops = &spacemit_i2c_clk_ops;
> > + init.parent_data = (struct clk_parent_data[]) {
> > + { .fw_name = "func" },
> > + };
> > + init.num_parents = 1;
> > +
> > + i2c->scl_clk_hw.init = &init;
> > +
> > + return devm_clk_register(i2c->dev, &i2c->scl_clk_hw);
> > +}
> > +
> > static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
> > {
> > writel(SPACEMIT_CR_UR, i2c->base + SPACEMIT_ICR);
> > @@ -246,7 +358,7 @@ static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
> > */
> > val |= SPACEMIT_CR_DRFIE;
> > - if (i2c->clock_freq == SPACEMIT_I2C_MAX_FAST_MODE_FREQ)
> > + if (i2c->mode == SPACEMIT_MODE_FAST)
> > val |= SPACEMIT_CR_MODE_FAST;
> > /* disable response to general call */
> > @@ -538,14 +650,15 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
> > dev_warn(dev, "failed to read clock-frequency property: %d\n", ret);
>
> I don't think there's any need to warn when the "clock-frequency"
> property is not found. It's an optional property, and the default
> is specified in the binding to be 400 KHz.
I will fix it in another patch.
>
> > /* For now, this driver doesn't support high-speed. */
> > - if (!i2c->clock_freq || i2c->clock_freq > SPACEMIT_I2C_MAX_FAST_MODE_FREQ) {
> > - dev_warn(dev, "unsupported clock frequency %u; using %u\n",
> > - i2c->clock_freq, SPACEMIT_I2C_MAX_FAST_MODE_FREQ);
> > + if (i2c->clock_freq > SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ &&
> > + i2c->clock_freq <= SPACEMIT_I2C_MAX_FAST_MODE_FREQ) {
> > + i2c->mode = SPACEMIT_MODE_FAST;
> > + } else if (i2c->clock_freq && i2c->clock_freq <= SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ) {
> > + i2c->mode = SPACEMIT_MODE_STANDARD;
> So this I2C driver will literally support *either* the standard
> speed *or* the high speed frequency. Is this a necessary
> restriction? If it is, perhaps the DT binding should be
> clear that the speeds should be one of those supported
> (because anything else will result in using a supported
> speed, not the one provided).
I think there may be a misunderstanding here.
The documentation already states that:
K1 supports three different modes running at different frequencies:
- standard speed mode: up to 100000 (100 kHz)
- fast speed mode : up to 400000 (400 kHz)
- high speed mode........
The mode only defines the valid frequency range.
In standard mode, the maximum frequency is 100 kHz; in fast mode,
the valid range is 100 kHz to 400 kHz.
The exact operating frequency is determined by the ILCR register.
This is precisely the motivation for this patch: without it, once
the mode is selected, the actual bus frequency depends solely on the
ILCR reset value rather than the clock-frequency provided by DT.
- Troy
>
>
> (Sorry, these last two comments are not about your patch,
> but about the driver that's already accepted.)
>
> -Alex
>
> > + } else {
> > + dev_warn(i2c->dev, "invalid clock-frequency, fallback to fast mode");
> > + i2c->mode = SPACEMIT_MODE_FAST;
> > i2c->clock_freq = SPACEMIT_I2C_MAX_FAST_MODE_FREQ;
> > - } else if (i2c->clock_freq < SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ) {
> > - dev_warn(dev, "unsupported clock frequency %u; using %u\n",
> > - i2c->clock_freq, SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ);
> > - i2c->clock_freq = SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ;
> > }
> > i2c->dev = &pdev->dev;
> > @@ -567,10 +680,28 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
> > if (IS_ERR(clk))
> > return dev_err_probe(dev, PTR_ERR(clk), "failed to enable func clock");
> > + i2c->scl_clk = spacemit_i2c_register_scl_clk(i2c, clk);
> > + if (IS_ERR(i2c->scl_clk))
> > + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->scl_clk),
> > + "failed to register scl clock\n");
> > +
> > clk = devm_clk_get_enabled(dev, "bus");
> > if (IS_ERR(clk))
> > return dev_err_probe(dev, PTR_ERR(clk), "failed to enable bus clock");
> > + ret = clk_set_rate(i2c->scl_clk, i2c->clock_freq);
> > + if (ret)
> > + return dev_err_probe(&pdev->dev, ret, "failed to set rate for SCL clock");
> > +
> > + ret = clk_prepare_enable(i2c->scl_clk);
> > + if (ret)
> > + return dev_err_probe(&pdev->dev, ret, "failed to prepare and enable clock");
> > +
> > + ret = devm_add_action_or_reset(dev, spacemit_i2c_scl_clk_disable_unprepare, i2c);
> > + if (ret)
> > + return dev_err_probe(&pdev->dev, ret,
> > + "failed to register cleanup action for clk disable and unprepare");
> > +
> > spacemit_i2c_reset(i2c);
> > i2c_set_adapdata(&i2c->adapt, i2c);
> >
>
^ permalink raw reply
* Re: [PATCH v3 1/4] i2c: spacemit: configure ILCR for accurate SCL frequency
From: Troy Mitchell @ 2025-12-26 7:52 UTC (permalink / raw)
To: Alex Elder, Troy Mitchell, Lee Jones, Yixun Lan, Andi Shyti,
Alexandre Belloni, Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc
In-Reply-To: <BD74A47E5BB66010+aU4j6CgGxebcBV5I@kernel.org>
> > > +static int spacemit_i2c_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > > + unsigned long parent_rate)
> > > +{
> > > + struct spacemit_i2c_dev *i2c = container_of(hw, struct spacemit_i2c_dev, scl_clk_hw);
> > > + u32 lv, lcr, mask, shift, max_lv;
> > > +
> > > + lv = DIV_ROUND_UP(parent_rate, rate);
> >
> > Would DIV_ROUND_CLOSEST() give a more accurate value?
> I'll test it.
Same result. So I'll keep it.
- Troy
^ permalink raw reply
* Re: [PATCH v1 0/2] RTC: Add Loongson-2K0300 support
From: Keguang Zhang @ 2025-12-26 10:03 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexandre Belloni, linux-rtc, Xiaochuang Mao,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-mips
In-Reply-To: <cover.1766471839.git.zhoubinbin@loongson.cn>
For the whole series:
Reviewed-by: Keguang Zhang <keguang.zhang@gmail.com>
Tested-by: Keguang Zhang <keguang.zhang@gmail.com> # on LS1B & LS1C
On Tue, Dec 23, 2025 at 2:42 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> Hi all:
>
> This patch set introduces the Loongson-2K0300 RTC, which has a similar
> hardware design to the Loongson-1B, but without the alarm feature.
>
> To Keguang:
> Would you have time to test the driver on a Loongson-1?
>
> Thanks.
> Binbin
>
> Binbin Zhou (2):
> dt-binding: rtc: loongson: Document Loongson-2K0300 compatible
> rtc: loongson: Add Loongson-2K0300 support
>
> .../devicetree/bindings/rtc/loongson,rtc.yaml | 13 ++++
> drivers/rtc/rtc-loongson.c | 65 +++++++++++++------
> 2 files changed, 57 insertions(+), 21 deletions(-)
>
>
> base-commit: 16bd954c93360145bc77cc601e350913fc28182d
> --
> 2.47.3
>
--
Best regards,
Keguang Zhang
^ permalink raw reply
* Re: [PATCH v3 1/4] i2c: spacemit: configure ILCR for accurate SCL frequency
From: Alex Elder @ 2025-12-29 0:58 UTC (permalink / raw)
To: Troy Mitchell, Lee Jones, Yixun Lan, Andi Shyti,
Alexandre Belloni, Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc
In-Reply-To: <569E6DA87DE510D5+aU4-1Jl9XxjAWQq4@kernel.org>
On 12/26/25 1:52 AM, Troy Mitchell wrote:
>>>> +static int spacemit_i2c_clk_set_rate(struct clk_hw *hw, unsigned long rate,
>>>> + unsigned long parent_rate)
>>>> +{
>>>> + struct spacemit_i2c_dev *i2c = container_of(hw, struct spacemit_i2c_dev, scl_clk_hw);
>>>> + u32 lv, lcr, mask, shift, max_lv;
>>>> +
>>>> + lv = DIV_ROUND_UP(parent_rate, rate);
>>>
>>> Would DIV_ROUND_CLOSEST() give a more accurate value?
>> I'll test it.
> Same result. So I'll keep it.
Is that true for all clock rates? Anyway, it's not
a huge deal, but especially when the number of rates
isn't very high this can make a difference.
-Alex
> - Troy
^ permalink raw reply
* Re: [PATCH v3 1/4] i2c: spacemit: configure ILCR for accurate SCL frequency
From: Troy Mitchell @ 2025-12-29 1:20 UTC (permalink / raw)
To: Alex Elder, Troy Mitchell, Lee Jones, Yixun Lan, Andi Shyti,
Alexandre Belloni, Liam Girdwood, Mark Brown
Cc: linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc
In-Reply-To: <4a76e9bf-926e-4b77-a2f8-ee4a72b2f1dd@riscstar.com>
On Sun, Dec 28, 2025 at 06:58:00PM -0600, Alex Elder wrote:
> On 12/26/25 1:52 AM, Troy Mitchell wrote:
> > > > > +static int spacemit_i2c_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > > > > + unsigned long parent_rate)
> > > > > +{
> > > > > + struct spacemit_i2c_dev *i2c = container_of(hw, struct spacemit_i2c_dev, scl_clk_hw);
> > > > > + u32 lv, lcr, mask, shift, max_lv;
> > > > > +
> > > > > + lv = DIV_ROUND_UP(parent_rate, rate);
> > > >
> > > > Would DIV_ROUND_CLOSEST() give a more accurate value?
> > > I'll test it.
> > Same result. So I'll keep it.
>
> Is that true for all clock rates?
I only test 400k.
> Anyway, it's not
> a huge deal, but especially when the number of rates
> isn't very high this can make a difference.
I'll test more. Thanks!
- Troy
^ permalink raw reply
* Re: [PATCH v4 3/3] rtc: spacemit: default module when MFD_SPACEMIT_P1 is enabled
From: Alex Elder @ 2025-12-29 18:02 UTC (permalink / raw)
To: Alexandre Belloni, Troy Mitchell
Cc: Lee Jones, Yixun Lan, Andi Shyti, Liam Girdwood, Mark Brown,
linux-kernel, linux-riscv, spacemit, linux-i2c, linux-rtc
In-Reply-To: <202512251653368b33c7e7@mail.local>
On 12/25/25 10:53 AM, Alexandre Belloni wrote:
> On 25/12/2025 15:46:33+0800, Troy Mitchell wrote:
>> The RTC driver defaulted to the same value as MFD_SPACEMIT_P1, which
>> caused it to be built-in automatically whenever the PMIC support was
>> set to y.
>>
>> This is not always desirable, as the RTC function is not required on
>> all platforms using the SpacemiT P1 PMIC.
>
> But then, can't people simply change the config? I don't feel like
> this is an improvement.
It's not an improvement for people who want to use the SpacemiT
P1 PMIC, but it's an improvement for all the other RISC-V builds
using "defconfig" that would rather have that support be modular
to avoid needlessly consuming resources.
I haven't done any testing on this but it looks fine to me.
Acked-by: Alex Elder <elder@riscstar.com>
I think it's a small change worth merging. I don't think
doing so does any harm. Your call or course, Alexandre.
-Alex
>> Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
>> ---
>> drivers/rtc/Kconfig | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
>> index 50dc779f7f983074df7882200c90f0df21d142f2..53866493e9bbaf35ff0de85cbfe43e8343eadc1e 100644
>> --- a/drivers/rtc/Kconfig
>> +++ b/drivers/rtc/Kconfig
>> @@ -410,7 +410,7 @@ config RTC_DRV_SPACEMIT_P1
>> tristate "SpacemiT P1 RTC"
>> depends on ARCH_SPACEMIT || COMPILE_TEST
>> depends on MFD_SPACEMIT_P1
>> - default MFD_SPACEMIT_P1
>> + default m if MFD_SPACEMIT_P1
>> help
>> Enable support for the RTC function in the SpacemiT P1 PMIC.
>> This driver can also be built as a module, which will be called
>>
>> --
>> 2.52.0
>>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox