Linux RTC
 help / color / mirror / Atom feed
* 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

* 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 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 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: 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 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 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

* [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

* [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 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 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

* 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

* 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 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,
> &regflag);
> +		if (ret)
> +			return ret;
> +
> +		if (regflag & RX8901_REG_INTF_VLF)
> +			tmp |= RTC_VL_DATA_INVALID;
> +
> +		ret = regmap_read(ds1307->regmap, RX8901_REG_BUF_INTF,
> &regflag);
> +		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 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,
> &regflag);
> +		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

* [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 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

* 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  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

* [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

* [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 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

* 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

* 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

* [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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox