* Re: [PATCH 03/27] rtc: ac100: convert from divider_round_rate() to divider_determine_rate()
From: Alexandre Belloni @ 2026-01-22 2:02 UTC (permalink / raw)
To: Brian Masney
Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
linux-rtc
In-Reply-To: <aXFz05Tnm8MmQbBD@redhat.com>
On 21/01/2026 19:48:19-0500, Brian Masney wrote:
> Hi Alexandre,
>
> On Thu, Jan 22, 2026 at 01:26:09AM +0100, Alexandre Belloni wrote:
> > On 08/01/2026 16:16:21-0500, Brian Masney wrote:
> > > The divider_round_rate() function is now deprecated, so let's migrate
> > > to divider_determine_rate() instead so that this deprecated API can be
> > > removed.
> > >
> > > Signed-off-by: Brian Masney <bmasney@redhat.com>
> > >
> > > ---
> > > To: Alexandre Belloni <alexandre.belloni@bootlin.com>
> > > Cc: linux-rtc@vger.kernel.org
> > > ---
> > > drivers/rtc/rtc-ac100.c | 75 +++++++++++++++++++++++++------------------------
> > > 1 file changed, 38 insertions(+), 37 deletions(-)
> > >
> > > diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
> > > index 33626311fa781b5ce90dcc472f948dc933bbc897..16aca4431da8c029e6195d8a3c9fe75fa95d0bc0 100644
> > > --- a/drivers/rtc/rtc-ac100.c
> > > +++ b/drivers/rtc/rtc-ac100.c
> > > @@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
> > > AC100_CLKOUT_DIV_WIDTH);
> > > }
> > >
> > > -static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
> > > - unsigned long prate)
> > > -{
> > > - unsigned long best_rate = 0, tmp_rate, tmp_prate;
> > > - int i;
> > > -
> > > - if (prate == AC100_RTC_32K_RATE)
> > > - return divider_round_rate(hw, rate, &prate, NULL,
> > > - AC100_CLKOUT_DIV_WIDTH,
> > > - CLK_DIVIDER_POWER_OF_TWO);
> > > -
> > > - for (i = 0; ac100_clkout_prediv[i].div; i++) {
> > > - tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
> > > - tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
> > > - AC100_CLKOUT_DIV_WIDTH,
> > > - CLK_DIVIDER_POWER_OF_TWO);
> > > -
> > > - if (tmp_rate > rate)
> > > - continue;
> > > - if (rate - tmp_rate < best_rate - tmp_rate)
> > > - best_rate = tmp_rate;
> > > - }
> > > -
> > > - return best_rate;
> > > -}
> > > -
> > > static int ac100_clkout_determine_rate(struct clk_hw *hw,
> > > struct clk_rate_request *req)
> > > {
> > > - struct clk_hw *best_parent;
> > > + int i, ret, num_parents = clk_hw_get_num_parents(hw);
> > > + struct clk_hw *best_parent = NULL;
> > > unsigned long best = 0;
> > > - int i, num_parents = clk_hw_get_num_parents(hw);
> > >
> > > for (i = 0; i < num_parents; i++) {
> > > struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
> > > - unsigned long tmp, prate;
> > > + unsigned long prate;
> > >
> > > /*
> > > * The clock has two parents, one is a fixed clock which is
> > > @@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
> > >
> > > prate = clk_hw_get_rate(parent);
> > >
> > > - tmp = ac100_clkout_round_rate(hw, req->rate, prate);
> > > -
> > > - if (tmp > req->rate)
> > > - continue;
> > > - if (req->rate - tmp < req->rate - best) {
> > > - best = tmp;
> > > - best_parent = parent;
> > > + if (prate == AC100_RTC_32K_RATE) {
> > > + struct clk_rate_request div_req = *req;
> > > +
> > > + div_req.best_parent_rate = prate;
> > > +
> > > + ret = divider_determine_rate(hw, &div_req, NULL,
> > > + AC100_CLKOUT_DIV_WIDTH,
> > > + CLK_DIVIDER_POWER_OF_TWO);
> > > + if (ret != 0 || div_req.rate > req->rate)
> > > + continue;
> >
> > This leaves a braces inbalance
>
> To be clear, you also want the braces around the if like this:
>
> if (ret != 0 || div_req.rate > req->rate) {
> continue;
> } else if (req->rate - div_req.rate < req->rate - best) {
> best = div_req.rate;
> best_parent = parent;
> }
>
Yes, you can change that and add my ack on v2, I'm fine with this going
through clk.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [GIT PULL] clk: remove deprecated API divider_round_rate() and friends for v6.20
From: Brian Masney @ 2026-01-22 0:52 UTC (permalink / raw)
To: Stephen Boyd; +Cc: linux-clk, linux-kernel, Alexandre Belloni, linux-rtc
In-Reply-To: <aXFYU324yQ6uBmk0@redhat.com>
Hi Stephen,
On Wed, Jan 21, 2026 at 05:50:59PM -0500, Brian Masney wrote:
> Here's a PULL for this large series that continues the work to remove
> some deprecated round_rate APIs. I used the following b4 command to
> collect up this series:
>
> b4 am --cherry-pick 1-13,17-23 \
> 20260108-clk-divider-round-rate-v1-0-535a3ed73bf3@redhat.com
>
> I skipped some of the patches that have already been picked up by
> others. The last two patches in that series that actually remove the
> deprecated functions will need to go in during the next dev cycle.
>
> One thing that I want to call out in this pull is the change to
> drivers/rtc/rtc-ac100.c, which is all clk related.
Alexandre requested a minor change with the rtc patch, so I'll send you
a v2 pull tomorrow without that.
Brian
^ permalink raw reply
* Re: [PATCH 03/27] rtc: ac100: convert from divider_round_rate() to divider_determine_rate()
From: Brian Masney @ 2026-01-22 0:48 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
linux-rtc
In-Reply-To: <202601220026092a75a45e@mail.local>
Hi Alexandre,
On Thu, Jan 22, 2026 at 01:26:09AM +0100, Alexandre Belloni wrote:
> On 08/01/2026 16:16:21-0500, Brian Masney wrote:
> > The divider_round_rate() function is now deprecated, so let's migrate
> > to divider_determine_rate() instead so that this deprecated API can be
> > removed.
> >
> > Signed-off-by: Brian Masney <bmasney@redhat.com>
> >
> > ---
> > To: Alexandre Belloni <alexandre.belloni@bootlin.com>
> > Cc: linux-rtc@vger.kernel.org
> > ---
> > drivers/rtc/rtc-ac100.c | 75 +++++++++++++++++++++++++------------------------
> > 1 file changed, 38 insertions(+), 37 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
> > index 33626311fa781b5ce90dcc472f948dc933bbc897..16aca4431da8c029e6195d8a3c9fe75fa95d0bc0 100644
> > --- a/drivers/rtc/rtc-ac100.c
> > +++ b/drivers/rtc/rtc-ac100.c
> > @@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
> > AC100_CLKOUT_DIV_WIDTH);
> > }
> >
> > -static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
> > - unsigned long prate)
> > -{
> > - unsigned long best_rate = 0, tmp_rate, tmp_prate;
> > - int i;
> > -
> > - if (prate == AC100_RTC_32K_RATE)
> > - return divider_round_rate(hw, rate, &prate, NULL,
> > - AC100_CLKOUT_DIV_WIDTH,
> > - CLK_DIVIDER_POWER_OF_TWO);
> > -
> > - for (i = 0; ac100_clkout_prediv[i].div; i++) {
> > - tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
> > - tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
> > - AC100_CLKOUT_DIV_WIDTH,
> > - CLK_DIVIDER_POWER_OF_TWO);
> > -
> > - if (tmp_rate > rate)
> > - continue;
> > - if (rate - tmp_rate < best_rate - tmp_rate)
> > - best_rate = tmp_rate;
> > - }
> > -
> > - return best_rate;
> > -}
> > -
> > static int ac100_clkout_determine_rate(struct clk_hw *hw,
> > struct clk_rate_request *req)
> > {
> > - struct clk_hw *best_parent;
> > + int i, ret, num_parents = clk_hw_get_num_parents(hw);
> > + struct clk_hw *best_parent = NULL;
> > unsigned long best = 0;
> > - int i, num_parents = clk_hw_get_num_parents(hw);
> >
> > for (i = 0; i < num_parents; i++) {
> > struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
> > - unsigned long tmp, prate;
> > + unsigned long prate;
> >
> > /*
> > * The clock has two parents, one is a fixed clock which is
> > @@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
> >
> > prate = clk_hw_get_rate(parent);
> >
> > - tmp = ac100_clkout_round_rate(hw, req->rate, prate);
> > -
> > - if (tmp > req->rate)
> > - continue;
> > - if (req->rate - tmp < req->rate - best) {
> > - best = tmp;
> > - best_parent = parent;
> > + if (prate == AC100_RTC_32K_RATE) {
> > + struct clk_rate_request div_req = *req;
> > +
> > + div_req.best_parent_rate = prate;
> > +
> > + ret = divider_determine_rate(hw, &div_req, NULL,
> > + AC100_CLKOUT_DIV_WIDTH,
> > + CLK_DIVIDER_POWER_OF_TWO);
> > + if (ret != 0 || div_req.rate > req->rate)
> > + continue;
>
> This leaves a braces inbalance
To be clear, you also want the braces around the if like this:
if (ret != 0 || div_req.rate > req->rate) {
continue;
} else if (req->rate - div_req.rate < req->rate - best) {
best = div_req.rate;
best_parent = parent;
}
Brian
^ permalink raw reply
* Re: [PATCH 03/27] rtc: ac100: convert from divider_round_rate() to divider_determine_rate()
From: Alexandre Belloni @ 2026-01-22 0:26 UTC (permalink / raw)
To: Brian Masney
Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
linux-rtc
In-Reply-To: <20260108-clk-divider-round-rate-v1-3-535a3ed73bf3@redhat.com>
Hello,
On 08/01/2026 16:16:21-0500, Brian Masney wrote:
> The divider_round_rate() function is now deprecated, so let's migrate
> to divider_determine_rate() instead so that this deprecated API can be
> removed.
>
> Signed-off-by: Brian Masney <bmasney@redhat.com>
>
> ---
> To: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: linux-rtc@vger.kernel.org
> ---
> drivers/rtc/rtc-ac100.c | 75 +++++++++++++++++++++++++------------------------
> 1 file changed, 38 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
> index 33626311fa781b5ce90dcc472f948dc933bbc897..16aca4431da8c029e6195d8a3c9fe75fa95d0bc0 100644
> --- a/drivers/rtc/rtc-ac100.c
> +++ b/drivers/rtc/rtc-ac100.c
> @@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
> AC100_CLKOUT_DIV_WIDTH);
> }
>
> -static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
> - unsigned long prate)
> -{
> - unsigned long best_rate = 0, tmp_rate, tmp_prate;
> - int i;
> -
> - if (prate == AC100_RTC_32K_RATE)
> - return divider_round_rate(hw, rate, &prate, NULL,
> - AC100_CLKOUT_DIV_WIDTH,
> - CLK_DIVIDER_POWER_OF_TWO);
> -
> - for (i = 0; ac100_clkout_prediv[i].div; i++) {
> - tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
> - tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
> - AC100_CLKOUT_DIV_WIDTH,
> - CLK_DIVIDER_POWER_OF_TWO);
> -
> - if (tmp_rate > rate)
> - continue;
> - if (rate - tmp_rate < best_rate - tmp_rate)
> - best_rate = tmp_rate;
> - }
> -
> - return best_rate;
> -}
> -
> static int ac100_clkout_determine_rate(struct clk_hw *hw,
> struct clk_rate_request *req)
> {
> - struct clk_hw *best_parent;
> + int i, ret, num_parents = clk_hw_get_num_parents(hw);
> + struct clk_hw *best_parent = NULL;
> unsigned long best = 0;
> - int i, num_parents = clk_hw_get_num_parents(hw);
>
> for (i = 0; i < num_parents; i++) {
> struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
> - unsigned long tmp, prate;
> + unsigned long prate;
>
> /*
> * The clock has two parents, one is a fixed clock which is
> @@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
>
> prate = clk_hw_get_rate(parent);
>
> - tmp = ac100_clkout_round_rate(hw, req->rate, prate);
> -
> - if (tmp > req->rate)
> - continue;
> - if (req->rate - tmp < req->rate - best) {
> - best = tmp;
> - best_parent = parent;
> + if (prate == AC100_RTC_32K_RATE) {
> + struct clk_rate_request div_req = *req;
> +
> + div_req.best_parent_rate = prate;
> +
> + ret = divider_determine_rate(hw, &div_req, NULL,
> + AC100_CLKOUT_DIV_WIDTH,
> + CLK_DIVIDER_POWER_OF_TWO);
> + if (ret != 0 || div_req.rate > req->rate)
> + continue;
This leaves a braces inbalance
> + else if (req->rate - div_req.rate < req->rate - best) {
> + best = div_req.rate;
> + best_parent = parent;
> + }
> + } else {
> + int j;
> +
> + for (j = 0; ac100_clkout_prediv[j].div; j++) {
> + struct clk_rate_request div_req = *req;
> + unsigned long tmp_prate;
> +
> + tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[j].div);
> + div_req.best_parent_rate = tmp_prate;
> +
> + ret = divider_determine_rate(hw, &div_req, NULL,
> + AC100_CLKOUT_DIV_WIDTH,
> + CLK_DIVIDER_POWER_OF_TWO);
> + if (ret != 0 || div_req.rate > req->rate)
> + continue;
Ditto.
> + else if (req->rate - div_req.rate < req->rate - best) {
> + best = div_req.rate;
> + best_parent = parent;
> + }
> + }
> }
> }
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 00/27] clk: remove deprecated API divider_round_rate() and friends
From: Brian Masney @ 2026-01-21 22:53 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: linux-clk, linux-kernel, Chen Wang, Inochi Amaoto, sophgo,
Chen-Yu Tsai, Maxime Ripard, Jernej Skrabec, Samuel Holland,
linux-arm-kernel, linux-sunxi, Alexandre Belloni, linux-rtc,
Andreas Färber, Manivannan Sadhasivam, linux-actions,
Keguang Zhang, linux-mips, Taichi Sugaya, Takao Orito,
Jacky Huang, Shan-Chun Hung, Vladimir Zapolskiy,
Piotr Wojtaszczyk, Bjorn Andersson, linux-arm-msm, Orson Zhai,
Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
linux-stm32, Michal Simek, Rob Clark, Dmitry Baryshkov,
David Airlie, Simona Vetter, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, dri-devel, freedreno, Vinod Koul,
Neil Armstrong, linux-phy
In-Reply-To: <20260108-clk-divider-round-rate-v1-0-535a3ed73bf3@redhat.com>
Hi Stephen,
On Thu, Jan 08, 2026 at 04:16:18PM -0500, Brian Masney wrote:
> Here's a series that gets rid of the deprecated APIs
> divider_round_rate(), divider_round_rate_parent(), and
> divider_ro_round_rate_parent() since these functions are just wrappers
> for the determine_rate variant.
I sent you a GIT PULL for what can go to Linus for the upcoming merge
window from this series:
https://lore.kernel.org/linux-clk/aXFYU324yQ6uBmk0@redhat.com/T/#u
Thanks,
Brian
^ permalink raw reply
* [GIT PULL] clk: remove deprecated API divider_round_rate() and friends for v6.20
From: Brian Masney @ 2026-01-21 22:50 UTC (permalink / raw)
To: Stephen Boyd; +Cc: linux-clk, linux-kernel, Alexandre Belloni, linux-rtc
Hi Stephen,
Here's a PULL for this large series that continues the work to remove
some deprecated round_rate APIs. I used the following b4 command to
collect up this series:
b4 am --cherry-pick 1-13,17-23 \
20260108-clk-divider-round-rate-v1-0-535a3ed73bf3@redhat.com
I skipped some of the patches that have already been picked up by
others. The last two patches in that series that actually remove the
deprecated functions will need to go in during the next dev cycle.
One thing that I want to call out in this pull is the change to
drivers/rtc/rtc-ac100.c, which is all clk related.
The following changes since commit 8f0b4cce4481fb22653697cced8d0d04027cb1e8:
Linux 6.19-rc1 (2025-12-14 16:05:07 +1200)
are available in the Git repository at:
https://github.com/masneyb/linux tags/clk-divider-round-rate-v6.20
for you to fetch changes up to 533162201ebcc478739235c6d002971f02f42f19:
clk: zynqmp: divider: convert from divider_round_rate() to divider_determine_rate() (2026-01-21 16:32:09 -0500)
----------------------------------------------------------------
Here's a series that lays the groundwork to rid of the deprecated APIs
divider_round_rate(), divider_round_rate_parent(), and
divider_ro_round_rate_parent() since these functions are just wrappers
for the determine_rate variant.
We need to wait for some other changes to land in Linus's tree via the
phy tree before we can actually remove these functions. We should be
able to do that during the next development cycle.
Note that when I converted some of these drivers from round_rate to
determine_rate, this was mistakenly converted to the following in some
cases:
req->rate = divider_round_rate(...)
This is invalid in the case when an error occurs since it can set the
rate to a negative value. So this series fixes those bugs and removes
the deprecated APIs all in one go.
----------------------------------------------------------------
Brian Masney (20):
clk: sophgo: cv18xx-ip: convert from divider_round_rate() to divider_determine_rate()
clk: sunxi-ng: convert from divider_round_rate_parent() to divider_determine_rate()
rtc: ac100: convert from divider_round_rate() to divider_determine_rate()
clk: actions: owl-composite: convert from owl_divider_helper_round_rate() to divider_determine_rate()
clk: actions: owl-divider: convert from divider_round_rate() to divider_determine_rate()
clk: bm1880: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: bm1880: convert from divider_round_rate() to divider_determine_rate()
clk: hisilicon: clkdivider-hi6220: convert from divider_round_rate() to divider_determine_rate()
clk: loongson1: convert from divider_round_rate() to divider_determine_rate()
clk: milbeaut: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: milbeaut: convert from divider_round_rate() to divider_determine_rate()
clk: nuvoton: ma35d1-divider: convert from divider_round_rate() to divider_determine_rate()
clk: nxp: lpc32xx: convert from divider_round_rate() to divider_determine_rate()
clk: sophgo: sg2042-clkgen: convert from divider_round_rate() to divider_determine_rate()
clk: sprd: div: convert from divider_round_rate() to divider_determine_rate()
clk: stm32: stm32-core: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: stm32: stm32-core: convert from divider_round_rate_parent() to divider_determine_rate()
clk: versaclock3: convert from divider_round_rate() to divider_determine_rate()
clk: x86: cgu: convert from divider_round_rate() to divider_determine_rate()
clk: zynqmp: divider: convert from divider_round_rate() to divider_determine_rate()
drivers/clk/actions/owl-composite.c | 11 +--
drivers/clk/actions/owl-divider.c | 17 +---
drivers/clk/actions/owl-divider.h | 5 -
drivers/clk/clk-bm1880.c | 13 +--
drivers/clk/clk-loongson1.c | 5 +-
drivers/clk/clk-milbeaut.c | 15 +--
drivers/clk/clk-versaclock3.c | 7 +-
drivers/clk/hisilicon/clkdivider-hi6220.c | 6 +-
drivers/clk/nuvoton/clk-ma35d1-divider.c | 7 +-
drivers/clk/nxp/clk-lpc32xx.c | 6 +-
drivers/clk/sophgo/clk-cv18xx-ip.c | 154 +++++++++++++++++-------------
drivers/clk/sophgo/clk-sg2042-clkgen.c | 15 +--
drivers/clk/sprd/div.c | 6 +-
drivers/clk/stm32/clk-stm32-core.c | 42 +++-----
drivers/clk/sunxi-ng/ccu_div.c | 25 +++--
drivers/clk/sunxi-ng/ccu_mp.c | 26 ++---
drivers/clk/sunxi-ng/ccu_mult.c | 16 ++--
drivers/clk/sunxi-ng/ccu_mux.c | 49 ++++++----
drivers/clk/sunxi-ng/ccu_mux.h | 8 +-
drivers/clk/sunxi-ng/ccu_nkm.c | 25 ++---
drivers/clk/x86/clk-cgu.c | 6 +-
drivers/clk/zynqmp/divider.c | 5 +-
drivers/rtc/rtc-ac100.c | 75 ++++++++-------
23 files changed, 245 insertions(+), 299 deletions(-)
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: rtc: loongson: Correct Loongson-1C interrupts property
From: Conor Dooley @ 2026-01-21 18:28 UTC (permalink / raw)
To: Binbin Zhou
Cc: Alexandre Belloni, Binbin Zhou, Huacai Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-rtc, Xiaochuang Mao,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-mips,
Keguang Zhang
In-Reply-To: <CAMpQs4Lm1Oq8L+dY8OnseV-NNUoD3+0QjnZATRkmR-sejCKAdA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4255 bytes --]
On Wed, Jan 21, 2026 at 02:52:06PM +0800, Binbin Zhou wrote:
> Hi Conor & Alexandre:
>
> Thanks for your reply.
>
> On Wed, Jan 21, 2026 at 7:39 AM Conor Dooley <conor@kernel.org> wrote:
> >
> > On Tue, Jan 20, 2026 at 11:49:20PM +0100, Alexandre Belloni wrote:
> > > On 20/01/2026 19:24:09+0000, Conor Dooley wrote:
> > > > On Tue, Jan 20, 2026 at 08:50:45AM +0100, Alexandre Belloni wrote:
> > > > > On 19/01/2026 18:24:36+0000, Conor Dooley wrote:
> > > > > > On Sat, Jan 17, 2026 at 10:26:48AM +0800, Binbin Zhou wrote:
> > > > > > > The `interrupts` property indicates an RTC alarm interrupt, which is
> > > > > > > required for RTCs that support the alarm feature, which is not supported
> > > > > > > by the Loongson-1C RTC. We exclude it for a more accurate description.
> > > > > > >
> > > > > > > Changing the `allowed` property is ABI-breaking behavior, but
> > > > > > > throughout the existing Loongson DTS{i}, the description of the RTC
> > > > > > > nodes conforms to the modified bingding rules.
> > > > > >
> > > > > > Right, changing properties is an ABI break, but when following the ABI
> > > > > > would've produced something non-functional, breaking it is not really
> > > > > > relevant.
> > > > >
> > > > >
> > > > > But the HW has the interrupt, the fact that is not functional doesn't
> > > > > mean it isn't there. I thought we should describe the hardware?
> > > >
> > > > Does the hardware have it? My interpretation of the commit message was
> > > > that it didn't have the alarm feature and thus no interrupt? Unless the
> > > > interrupt has some other purpose, in which case yeah we shouldn't accept
> > > > this change and only the new device should permit there being no
> > > > interrupt.
> > >
> > > The datasheet shows the interrupt coming out of the RTC and it has the
> > > proper registers. Why it is not functional is not clear to me.
> >
> > Right.. Perhaps Binbin can explain that then? If the interrupt is
> > actually there then the dts should get fixed instead IMO.
>
> I carefully reviewed the manual again and believe this patch is still necessary.
>
> First, the Loongson-1C RTC does not define the timing interrupt
> register (`TOY_MATCH0_REG`)[1], meaning it lacks hardware support for
I don't understand Chinese, so I'll take your word for it that this
particular model doesn't have this interrupt and that there's no other
interrupt used by the rtc via a different register :) My ack for the
patch remains valid.
Also, I looked at the existing binding again, and there's no ABI break
anyway cos the interrupts property wasn't required in the first place,
so any driver has to be written to permit the absence of an interrupts
property. I think you should remove mention of ABI break from the commit
message, since it's not actually one.
> alarms. Consequently, `interrupts` are also unnecessary.
> The Loongson-2K0300 is different. It defines `TOY_MATCH0_REG`, but due
> to a hardware design flaw, accessing this register causes system
> crashes. Therefore, I must also classify it as lacking alarm support.
This logic also seems fair to me, assuming that this is the only
interrupt that the device has.
> Additionally, in patch-3 [2], I rewrote the alarm logic to decouple
> the `interrupts` property from the alarm feature: I defined
> corresponding workaround bits in `loongson_rtc_config->flags`. This
> should be considered a SoC-specific attribute.
>
> Finally, two thoughts:
> 1. Retain this patch; it is correct for Loongson-1C.
> 2. For Patch-2, still add the `interrupts` property to the
> Loongson-2K0300 RTC node (as it exists in hardware), combined with the
> workaround bit setting in patch-3 to avoid the hardware flaw.
Personally, I think what you've done in patch 2 is okay, since that
interrupt is non-functional.
>
> Would this approach be acceptable?
>
> [1]: https://www.loongson.cn/uploads/images/2022051616223977135.%E9%BE%99%E8%8A%AF1C300%E5%A4%84%E7%90%86%E5%99%A8%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C.pdf
> (section 21.2.1)
> [2]: https://lore.kernel.org/linux-rtc/abff68dda2fe6a6601a9e58b31e278d941297fce.1768616276.git.zhoubinbin@loongson.cn/
>
> --
> Thanks.
> Binbin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 1/7] dt-bindings: rtc: sun6i: Add Allwinner A733 support
From: Rob Herring (Arm) @ 2026-01-21 16:56 UTC (permalink / raw)
To: Junhui Liu
Cc: Jernej Skrabec, Alexandre Belloni, linux-rtc, Maxime Ripard,
Chen-Yu Tsai, devicetree, Krzysztof Kozlowski, Conor Dooley,
linux-kernel, Samuel Holland, linux-arm-kernel, linux-clk,
Michael Turquette, Stephen Boyd, linux-sunxi
In-Reply-To: <20260121-a733-rtc-v1-1-d359437f23a7@pigmoral.tech>
On Wed, 21 Jan 2026 18:59:07 +0800, Junhui Liu wrote:
> The RTC module in the Allwinner A733 SoC is functionally compatible with
> the sun6i RTC, but its internal Clock Control Unit (CCU) has significant
> changes.
>
> The A733 supports selecting the oscillator between three frequencies:
> 19.2MHz, 24MHz, and 26MHz. The RTC CCU relies on hardware to detect
> which frequency is actually used on the board. By defining all three
> frequencies as fixed-clocks in the device tree, the driver can identify
> the hardware-detected frequency and expose it to the rest of the system.
>
> Additionally, the A733 RTC CCU provides several new DCXO gate clocks for
> specific modules, including SerDes, HDMI, and UFS.
>
> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
> ---
> .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 38 ++++++++++++++++++++--
> include/dt-bindings/clock/sun60i-a733-rtc.h | 16 +++++++++
> 2 files changed, 52 insertions(+), 2 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* [PATCH] rtc: fix spelling typos in comments
From: Nick Huang @ 2026-01-21 15:42 UTC (permalink / raw)
To: Alexandre Belloni
Cc: linux-rtc, linux-kernel, kusogame68, n1136402, Nick Huang
Fix spelling typos in rtc-fm3130.c and rtc-rs5c372.c.
- Change 'chek' to 'check' in rtc-fm3130.c.
- Change 'whic' to 'which' in rtc-rs5c372.c.
Signed-off-by: Nick Huang <sef1548@gmail.com>
---
drivers/rtc/rtc-fm3130.c | 2 +-
drivers/rtc/rtc-rs5c372.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index f82728eba..53271f638 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -465,7 +465,7 @@ static int fm3130_probe(struct i2c_client *client)
bad_alarm:
- /* clock registers sanity chek */
+ /* clock registers sanity check */
tmp = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f);
if (tmp > 59)
goto bad_clock;
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index f8fab0205..92bea6e98 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -639,7 +639,7 @@ static int rs5c372_set_offset(struct device *dev, long offset)
if (!steps || !(val & 0x3E)) {
/*
* if offset is too small, set oscillation adjustment register
- * or time trimming register with its default value whic means
+ * or time trimming register with its default value which means
* no increment or decrement. But for rs5c372[a|b], the XSL bit
* should be kept unchanged.
*/
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v3 1/6] rtc: zynqmp: declare dependency on arch
From: Michal Simek @ 2026-01-21 12:16 UTC (permalink / raw)
To: Tomas Melin, Alexandre Belloni
Cc: linux-rtc, linux-arm-kernel, linux-kernel, kernel test robot
In-Reply-To: <20260119-zynqmp-rtc-updates-v3-1-acd902fdeab1@vaisala.com>
On 1/19/26 10:51, Tomas Melin wrote:
> Driver is compatible with RTC controller found on zynqmp.
> Configure dependency to enable building only when zynqmp architecture
> is enabled.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
> ---
> drivers/rtc/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 2933c41c77c88e60df721fe65b9c8afb995ae51e..46b497524cbfb5d0c1662dcaddbb6d28b4ae2abe 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1376,7 +1376,7 @@ config RTC_DRV_OPTEE
>
> config RTC_DRV_ZYNQMP
> tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
> - depends on OF && HAS_IOMEM
> + depends on OF && HAS_IOMEM && ARCH_ZYNQMP
arm-linux-gnueabi-ld: drivers/rtc/rtc-zynqmp.o: in function
`xlnx_rtc_read_offset':
>> rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0xd0): undefined reference to
`__aeabi_ldivmod'
You should use macros like div_u64() to fix it instead of have driver enabled
only for ZynqMP.
M
^ permalink raw reply
* Re: [PATCH v3 1/6] rtc: zynqmp: declare dependency on arch
From: Michal Simek @ 2026-01-21 12:11 UTC (permalink / raw)
To: Tomas Melin, Alexandre Belloni
Cc: linux-rtc, linux-arm-kernel, linux-kernel, kernel test robot
In-Reply-To: <20260119-zynqmp-rtc-updates-v3-1-acd902fdeab1@vaisala.com>
On 1/19/26 10:51, Tomas Melin wrote:
> Driver is compatible with RTC controller found on zynqmp.
> Configure dependency to enable building only when zynqmp architecture
> is enabled.
>
> Reported-by: kernel test robot <lkp@intel.com>
do you have any link what exactly has been reported?
M
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
> ---
> drivers/rtc/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 2933c41c77c88e60df721fe65b9c8afb995ae51e..46b497524cbfb5d0c1662dcaddbb6d28b4ae2abe 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1376,7 +1376,7 @@ config RTC_DRV_OPTEE
>
> config RTC_DRV_ZYNQMP
> tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
> - depends on OF && HAS_IOMEM
> + depends on OF && HAS_IOMEM && ARCH_ZYNQMP
> help
> If you say yes here you get support for the RTC controller found on
> Xilinx Zynq Ultrascale+ MPSoC.
>
^ permalink raw reply
* [PATCH 7/7] clk: sunxi-ng: Add Allwinner A733 RTC CCU support
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
Add support for the internal CCU found in the RTC module of the Allwinner
A733 SoC. While the basic 16MHz (IOSC) and 32kHz logic remains compatible
with older SoCs like the sun6i, the A733 introduces several new features.
The A733 RTC CCU supports choosing one of three external crystal
frequencies: 19.2MHz, 24MHz, and 26MHz. It features hardware detection
logic to automatically identify the frequency used on the board and
exports this DCXO signal as the "hosc" clock.
Furthermore, the driver implements logic to derive a 32kHz reference
from the HOSC. This is achieved through a muxed clock path using fixed
pre-dividers to normalize the different crystal frequencies to ~32kHz.
This path reuses the same hardware mux registers as the HOSC clock.
Additionally, this CCU provides several gate clocks for specific
peripherals, including SerDes, HDMI, and UFS. The driver is implemented
as an auxiliary driver to be bound to the sun6i-rtc driver.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/clk/sunxi-ng/Kconfig | 5 +
drivers/clk/sunxi-ng/Makefile | 2 +
drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.c | 204 +++++++++++++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.h | 18 +++
drivers/clk/sunxi-ng/ccu_rtc.h | 7 +
5 files changed, 236 insertions(+)
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 6af2d020e03e..16afbf249f26 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -67,6 +67,11 @@ config SUN55I_A523_R_CCU
default ARCH_SUNXI
depends on ARM64 || COMPILE_TEST
+config SUN60I_A733_RTC_CCU
+ tristate "Support for the Allwinner A733 RTC CCU"
+ default ARCH_SUNXI
+ depends on ARM64 || COMPILE_TEST
+
config SUN4I_A10_CCU
tristate "Support for the Allwinner A10/A20 CCU"
default ARCH_SUNXI
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index c3f810a025a8..b0d823440c33 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o
obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o
obj-$(CONFIG_SUN55I_A523_MCU_CCU) += sun55i-a523-mcu-ccu.o
obj-$(CONFIG_SUN55I_A523_R_CCU) += sun55i-a523-r-ccu.o
+obj-$(CONFIG_SUN60I_A733_RTC_CCU) += sun60i-a733-rtc-ccu.o
obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o
obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o
obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o
@@ -67,6 +68,7 @@ sun50i-h616-ccu-y += ccu-sun50i-h616.o
sun55i-a523-ccu-y += ccu-sun55i-a523.o
sun55i-a523-mcu-ccu-y += ccu-sun55i-a523-mcu.o
sun55i-a523-r-ccu-y += ccu-sun55i-a523-r.o
+sun60i-a733-rtc-ccu-y += ccu-sun60i-a733-rtc.o
sun4i-a10-ccu-y += ccu-sun4i-a10.o
sun5i-ccu-y += ccu-sun5i.o
sun6i-a31-ccu-y += ccu-sun6i-a31.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.c
new file mode 100644
index 000000000000..d17aceffa16e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
+ */
+
+#include <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include "ccu_common.h"
+
+#include "ccu_gate.h"
+#include "ccu_mux.h"
+#include "ccu_rtc.h"
+
+#include "ccu-sun60i-a733-rtc.h"
+
+static struct ccu_common iosc_clk = {
+ .reg = DCXO_CTRL_REG,
+ .features = CCU_FEATURE_IOSC_CALIBRATION,
+ .hw.init = CLK_HW_INIT_NO_PARENT("iosc", &ccu_iosc_ops,
+ CLK_GET_RATE_NOCACHE),
+};
+
+static struct ccu_common iosc_32k_clk = {
+ .features = CCU_FEATURE_IOSC_CALIBRATION,
+ .hw.init = CLK_HW_INIT_HW("iosc-32k", &iosc_clk.hw,
+ &ccu_iosc_32k_ops,
+ CLK_GET_RATE_NOCACHE),
+};
+
+static SUNXI_CCU_GATE_FW(ext_osc32k_gate_clk, "ext-osc32k-gate",
+ "ext-osc32k", 0x0, BIT(4), 0);
+
+static const struct clk_hw *osc32k_parents[] = {
+ &iosc_32k_clk.hw,
+ &ext_osc32k_gate_clk.common.hw,
+};
+
+static struct ccu_mux osc32k_clk = {
+ .mux = _SUNXI_CCU_MUX(0, 1),
+ .common = {
+ .reg = LOSC_CTRL_REG,
+ .features = CCU_FEATURE_KEY_FIELD,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("osc32k",
+ osc32k_parents,
+ &ccu_mux_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data hosc_parents[] = {
+ { .fw_name = "osc24M" },
+ { .fw_name = "osc19M" },
+ { .fw_name = "osc26M" },
+ { .fw_name = "osc24M" },
+};
+
+struct ccu_mux hosc_clk = {
+ .enable = DCXO_CTRL_DCXO_EN,
+ .mux = _SUNXI_CCU_MUX(14, 2),
+ .common = {
+ .reg = DCXO_CTRL_REG,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("hosc",
+ hosc_parents,
+ &ccu_mux_ro_ops,
+ 0),
+ },
+};
+
+static const struct ccu_mux_fixed_prediv hosc_32k_predivs[] = {
+ { .index = 0, .div = 732 },
+ { .index = 1, .div = 586 },
+ { .index = 2, .div = 793 },
+ { .index = 3, .div = 732 },
+};
+
+static struct ccu_mux hosc_32k_mux_clk = {
+ .enable = DCXO_CTRL_DCXO_EN,
+ .mux = {
+ .shift = 14,
+ .width = 2,
+ .fixed_predivs = hosc_32k_predivs,
+ .n_predivs = ARRAY_SIZE(hosc_32k_predivs),
+ },
+ .common = {
+ .reg = DCXO_CTRL_REG,
+ .features = CCU_FEATURE_FIXED_PREDIV,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("hosc-32k-mux",
+ hosc_parents,
+ &ccu_mux_ro_ops,
+ 0),
+ },
+};
+
+static SUNXI_CCU_GATE_HW(hosc_32k_clk, "hosc-32k", &hosc_32k_mux_clk.common.hw,
+ LOSC_OUT_GATING_REG, BIT(16), 0);
+
+static const struct clk_hw *rtc_32k_parents[] = {
+ &osc32k_clk.common.hw,
+ &hosc_32k_clk.common.hw,
+};
+
+static struct ccu_mux rtc_32k_clk = {
+ .mux = _SUNXI_CCU_MUX(1, 1),
+ .common = {
+ .reg = LOSC_CTRL_REG,
+ .features = CCU_FEATURE_KEY_FIELD,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("rtc-32k",
+ rtc_32k_parents,
+ &ccu_mux_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data osc32k_fanout_parents[] = {
+ { .hw = &osc32k_clk.common.hw },
+ { .hw = &ext_osc32k_gate_clk.common.hw },
+ { .hw = &hosc_32k_clk.common.hw },
+};
+
+static SUNXI_CCU_MUX_DATA_WITH_GATE(osc32k_fanout_clk, "osc32k-fanout", osc32k_fanout_parents,
+ LOSC_OUT_GATING_REG,
+ 1, 2, /* mux */
+ BIT(0), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE_HW(hosc_serdes1_clk, "hosc-serdes1", &hosc_clk.common.hw,
+ DCXO_GATING_REG, DCXO_SERDES1_GATING, 0);
+static SUNXI_CCU_GATE_HW(hosc_serdes0_clk, "hosc-serdes0", &hosc_clk.common.hw,
+ DCXO_GATING_REG, DCXO_SERDES0_GATING, 0);
+static SUNXI_CCU_GATE_HW(hosc_hdmi_clk, "hosc-hdmi", &hosc_clk.common.hw,
+ DCXO_GATING_REG, DCXO_HDMI_GATING, 0);
+static SUNXI_CCU_GATE_HW(hosc_ufs_clk, "hosc-ufs", &hosc_clk.common.hw,
+ DCXO_GATING_REG, DCXO_UFS_GATING, 0);
+
+static struct ccu_common *sun60i_rtc_ccu_clks[] = {
+ &iosc_clk,
+ &iosc_32k_clk,
+ &ext_osc32k_gate_clk.common,
+ &osc32k_clk.common,
+ &hosc_clk.common,
+ &hosc_32k_mux_clk.common,
+ &hosc_32k_clk.common,
+ &rtc_32k_clk.common,
+ &osc32k_fanout_clk.common,
+ &hosc_serdes1_clk.common,
+ &hosc_serdes0_clk.common,
+ &hosc_hdmi_clk.common,
+ &hosc_ufs_clk.common,
+};
+
+static struct clk_hw_onecell_data sun60i_rtc_ccu_hw_clks = {
+ .num = CLK_NUMBER,
+ .hws = {
+ [CLK_IOSC] = &iosc_clk.hw,
+ [CLK_OSC32K] = &osc32k_clk.common.hw,
+ [CLK_HOSC] = &hosc_clk.common.hw,
+ [CLK_RTC_32K] = &rtc_32k_clk.common.hw,
+ [CLK_OSC32K_FANOUT] = &osc32k_fanout_clk.common.hw,
+ [CLK_HOSC_SERDES1] = &hosc_serdes1_clk.common.hw,
+ [CLK_HOSC_SERDES0] = &hosc_serdes0_clk.common.hw,
+ [CLK_HOSC_HDMI] = &hosc_hdmi_clk.common.hw,
+ [CLK_HOSC_UFS] = &hosc_ufs_clk.common.hw,
+ [CLK_IOSC_32K] = &iosc_32k_clk.hw,
+ [CLK_EXT_OSC32K_GATE] = &ext_osc32k_gate_clk.common.hw,
+ [CLK_HOSC_32K_MUX] = &hosc_32k_mux_clk.common.hw,
+ [CLK_HOSC_32K] = &hosc_32k_clk.common.hw,
+ },
+};
+
+static const struct sunxi_ccu_desc sun60i_rtc_ccu_desc = {
+ .ccu_clks = sun60i_rtc_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun60i_rtc_ccu_clks),
+
+ .hw_clks = &sun60i_rtc_ccu_hw_clks,
+};
+
+static int sun60i_rtc_ccu_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &adev->dev;
+ void __iomem *reg = dev->platform_data;
+
+ return devm_sunxi_ccu_probe(dev, reg, &sun60i_rtc_ccu_desc);
+}
+
+static const struct auxiliary_device_id sun60i_ccu_rtc_ids[] = {
+ { .name = SUN6I_RTC_AUX_ID(sun60i) },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, sun60i_ccu_rtc_ids);
+
+static struct auxiliary_driver sun60i_ccu_rtc_driver = {
+ .probe = sun60i_rtc_ccu_probe,
+ .id_table = sun60i_ccu_rtc_ids,
+};
+module_auxiliary_driver(sun60i_ccu_rtc_driver);
+
+MODULE_IMPORT_NS("SUNXI_CCU");
+MODULE_DESCRIPTION("Support for the Allwinner A733 RTC CCU");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.h b/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.h
new file mode 100644
index 000000000000..41ec6195b5e7
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
+ */
+
+#ifndef _CCU_SUN60I_A733_RTC_H_
+#define _CCU_SUN60I_A733_RTC_H_
+
+#include <dt-bindings/clock/sun60i-a733-rtc.h>
+
+#define CLK_IOSC_32K 9
+#define CLK_EXT_OSC32K_GATE 10
+#define CLK_HOSC_32K_MUX 11
+#define CLK_HOSC_32K 12
+
+#define CLK_NUMBER (CLK_HOSC_32K + 1)
+
+#endif /* _CCU_SUN60I_A733_RTC_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_rtc.h b/drivers/clk/sunxi-ng/ccu_rtc.h
index 1c44c2206a25..665162723796 100644
--- a/drivers/clk/sunxi-ng/ccu_rtc.h
+++ b/drivers/clk/sunxi-ng/ccu_rtc.h
@@ -27,8 +27,15 @@
#define LOSC_OUT_GATING_REG 0x60
#define DCXO_CTRL_REG 0x160
+#define DCXO_CTRL_DCXO_EN BIT(1)
#define DCXO_CTRL_CLK16M_RC_EN BIT(0)
+#define DCXO_GATING_REG 0x16c
+#define DCXO_SERDES1_GATING BIT(5)
+#define DCXO_SERDES0_GATING BIT(4)
+#define DCXO_HDMI_GATING BIT(1)
+#define DCXO_UFS_GATING BIT(0)
+
#define SUN6I_RTC_AUX_ID(_name) "rtc_sun6i." #_name
extern const struct clk_ops ccu_iosc_ops;
--
2.52.0
^ permalink raw reply related
* [PATCH 6/7] rtc: sun6i: Add support for A733 RTC
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
The RTC in the Allwinner A733 SoC is compatible with the H616 in terms
of its time storage and alarm functionality. However, its internal CCU
is different, with additional DCXO handling logic.
Add new match data to register a new auxiliary device for its CCU part.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/rtc/rtc-sun6i.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index b4489e0a09ce..a58d9c6b917c 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -865,6 +865,11 @@ static const struct sun6i_rtc_match_data sun6i_rtc_match_data = {
.flags = RTC_LINEAR_DAY,
};
+static const struct sun6i_rtc_match_data sun60i_rtc_match_data = {
+ .adev_name = "sun60i",
+ .flags = RTC_LINEAR_DAY,
+};
+
/*
* As far as RTC functionality goes, all models are the same. The
* datasheets claim that different models have different number of
@@ -883,6 +888,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
.data = &sun6i_rtc_match_data },
{ .compatible = "allwinner,sun50i-r329-rtc",
.data = &sun6i_rtc_match_data },
+ { .compatible = "allwinner,sun60i-a733-rtc",
+ .data = &sun60i_rtc_match_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
--
2.52.0
^ permalink raw reply related
* [PATCH 5/7] clk: sunxi-ng: mux: Add mux read-only clock operations
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
The Allwinner A733 SoC introduces some mux clocks (such as the one
indicating the DCXO frequency) that use read-only registers to report
their current hardware configuration. Writing to these registers is not
supported by hardware and should be avoided.
Add ccu_mux_ro_ops to support these clocks, which omit .set_parent()
and .determine_rate() to prevent changing the mux state.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/clk/sunxi-ng/ccu_mux.c | 11 +++++++++++
drivers/clk/sunxi-ng/ccu_mux.h | 1 +
2 files changed, 12 insertions(+)
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index 74f9e98a5d35..d48e7c3e065d 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -277,6 +277,17 @@ const struct clk_ops ccu_mux_ops = {
};
EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, "SUNXI_CCU");
+const struct clk_ops ccu_mux_ro_ops = {
+ .disable = ccu_mux_disable,
+ .enable = ccu_mux_enable,
+ .is_enabled = ccu_mux_is_enabled,
+
+ .get_parent = ccu_mux_get_parent,
+
+ .recalc_rate = ccu_mux_recalc_rate,
+};
+EXPORT_SYMBOL_NS_GPL(ccu_mux_ro_ops, "SUNXI_CCU");
+
/*
* This clock notifier is called when the frequency of the of the parent
* PLL clock is to be changed. The idea is to switch the parent to a
diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h
index eb1172ebbd94..887c164d00f4 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.h
+++ b/drivers/clk/sunxi-ng/ccu_mux.h
@@ -129,6 +129,7 @@ static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
}
extern const struct clk_ops ccu_mux_ops;
+extern const struct clk_ops ccu_mux_ro_ops;
unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
struct ccu_mux_internal *cm,
--
2.52.0
^ permalink raw reply related
* [PATCH 4/7] clk: sunxi-ng: Extract common RTC CCU clock logic
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
Extract the IOSC and 32k clock logic from ccu-sun6i-rtc into a shared
module to simplify adding RTC CCU support for new SoCs. This is needed
because newer Allwinner SoCs introduce additional DCXO/HOSC logic that
prevents direct reuse of the existing driver.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/clk/sunxi-ng/Makefile | 3 +
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 152 +----------------------------------
drivers/clk/sunxi-ng/ccu_rtc.c | 136 +++++++++++++++++++++++++++++++
drivers/clk/sunxi-ng/ccu_rtc.h | 37 +++++++++
4 files changed, 177 insertions(+), 151 deletions(-)
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index a1c4087d7241..c3f810a025a8 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -23,6 +23,9 @@ sunxi-ccu-y += ccu_nkmp.o
sunxi-ccu-y += ccu_nm.o
sunxi-ccu-y += ccu_mp.o
+# RTC clocks
+sunxi-ccu-y += ccu_rtc.o
+
# SoC support
obj-$(CONFIG_SUNIV_F1C100S_CCU) += suniv-f1c100s-ccu.o
obj-$(CONFIG_SUN20I_D1_CCU) += sun20i-d1-ccu.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index 6f888169412c..562ba752bcec 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -14,37 +14,12 @@
#include "ccu_common.h"
-#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_mux.h"
+#include "ccu_rtc.h"
#include "ccu-sun6i-rtc.h"
-#define IOSC_ACCURACY 300000000 /* 30% */
-#define IOSC_RATE 16000000
-
-#define LOSC_RATE 32768
-#define LOSC_RATE_SHIFT 15
-
-#define LOSC_CTRL_REG 0x0
-#define LOSC_CTRL_KEY 0x16aa0000
-
-#define IOSC_32K_CLK_DIV_REG 0x8
-#define IOSC_32K_CLK_DIV GENMASK(4, 0)
-#define IOSC_32K_PRE_DIV 32
-
-#define IOSC_CLK_CALI_REG 0xc
-#define IOSC_CLK_CALI_DIV_ONES 22
-#define IOSC_CLK_CALI_EN BIT(1)
-#define IOSC_CLK_CALI_SRC_SEL BIT(0)
-
-#define LOSC_OUT_GATING_REG 0x60
-
-#define DCXO_CTRL_REG 0x160
-#define DCXO_CTRL_CLK16M_RC_EN BIT(0)
-
-#define SUN6I_RTC_AUX_ID(_name) "rtc_sun6i." #_name
-
struct sun6i_rtc_match_data {
bool have_ext_osc32k : 1;
bool have_iosc_calibration : 1;
@@ -53,137 +28,12 @@ struct sun6i_rtc_match_data {
u8 osc32k_fanout_nparents;
};
-static int ccu_iosc_enable(struct clk_hw *hw)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
-
- return ccu_gate_helper_enable(cm, DCXO_CTRL_CLK16M_RC_EN);
-}
-
-static void ccu_iosc_disable(struct clk_hw *hw)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
-
- return ccu_gate_helper_disable(cm, DCXO_CTRL_CLK16M_RC_EN);
-}
-
-static int ccu_iosc_is_enabled(struct clk_hw *hw)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
-
- return ccu_gate_helper_is_enabled(cm, DCXO_CTRL_CLK16M_RC_EN);
-}
-
-static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
-
- if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
- u32 reg = readl(cm->base + IOSC_CLK_CALI_REG);
-
- /*
- * Recover the IOSC frequency by shifting the ones place of
- * (fixed-point divider * 32768) into bit zero.
- */
- if (reg & IOSC_CLK_CALI_EN)
- return reg >> (IOSC_CLK_CALI_DIV_ONES - LOSC_RATE_SHIFT);
- }
-
- return IOSC_RATE;
-}
-
-static unsigned long ccu_iosc_recalc_accuracy(struct clk_hw *hw,
- unsigned long parent_accuracy)
-{
- return IOSC_ACCURACY;
-}
-
-static const struct clk_ops ccu_iosc_ops = {
- .enable = ccu_iosc_enable,
- .disable = ccu_iosc_disable,
- .is_enabled = ccu_iosc_is_enabled,
- .recalc_rate = ccu_iosc_recalc_rate,
- .recalc_accuracy = ccu_iosc_recalc_accuracy,
-};
-
static struct ccu_common iosc_clk = {
.reg = DCXO_CTRL_REG,
.hw.init = CLK_HW_INIT_NO_PARENT("iosc", &ccu_iosc_ops,
CLK_GET_RATE_NOCACHE),
};
-static int ccu_iosc_32k_prepare(struct clk_hw *hw)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
- u32 val;
-
- if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
- return 0;
-
- val = readl(cm->base + IOSC_CLK_CALI_REG);
- writel(val | IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL,
- cm->base + IOSC_CLK_CALI_REG);
-
- return 0;
-}
-
-static void ccu_iosc_32k_unprepare(struct clk_hw *hw)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
- u32 val;
-
- if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
- return;
-
- val = readl(cm->base + IOSC_CLK_CALI_REG);
- writel(val & ~(IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL),
- cm->base + IOSC_CLK_CALI_REG);
-}
-
-static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
- u32 val;
-
- if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
- val = readl(cm->base + IOSC_CLK_CALI_REG);
-
- /* Assume the calibrated 32k clock is accurate. */
- if (val & IOSC_CLK_CALI_SRC_SEL)
- return LOSC_RATE;
- }
-
- val = readl(cm->base + IOSC_32K_CLK_DIV_REG) & IOSC_32K_CLK_DIV;
-
- return parent_rate / IOSC_32K_PRE_DIV / (val + 1);
-}
-
-static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw,
- unsigned long parent_accuracy)
-{
- struct ccu_common *cm = hw_to_ccu_common(hw);
- u32 val;
-
- if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
- val = readl(cm->base + IOSC_CLK_CALI_REG);
-
- /* Assume the calibrated 32k clock is accurate. */
- if (val & IOSC_CLK_CALI_SRC_SEL)
- return 0;
- }
-
- return parent_accuracy;
-}
-
-static const struct clk_ops ccu_iosc_32k_ops = {
- .prepare = ccu_iosc_32k_prepare,
- .unprepare = ccu_iosc_32k_unprepare,
- .recalc_rate = ccu_iosc_32k_recalc_rate,
- .recalc_accuracy = ccu_iosc_32k_recalc_accuracy,
-};
-
static struct ccu_common iosc_32k_clk = {
.hw.init = CLK_HW_INIT_HW("iosc-32k", &iosc_clk.hw,
&ccu_iosc_32k_ops,
diff --git a/drivers/clk/sunxi-ng/ccu_rtc.c b/drivers/clk/sunxi-ng/ccu_rtc.c
new file mode 100644
index 000000000000..cfc10218517c
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_rtc.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+
+#include "ccu_common.h"
+
+#include "ccu_gate.h"
+#include "ccu_rtc.h"
+
+static int ccu_iosc_enable(struct clk_hw *hw)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+
+ return ccu_gate_helper_enable(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static void ccu_iosc_disable(struct clk_hw *hw)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+
+ return ccu_gate_helper_disable(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static int ccu_iosc_is_enabled(struct clk_hw *hw)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+
+ return ccu_gate_helper_is_enabled(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
+ u32 reg = readl(cm->base + IOSC_CLK_CALI_REG);
+ /*
+ * Recover the IOSC frequency by shifting the ones place of
+ * (fixed-point divider * 32768) into bit zero.
+ */
+ if (reg & IOSC_CLK_CALI_EN)
+ return reg >> (IOSC_CLK_CALI_DIV_ONES - LOSC_RATE_SHIFT);
+ }
+
+ return IOSC_RATE;
+}
+
+static unsigned long ccu_iosc_recalc_accuracy(struct clk_hw *hw,
+ unsigned long parent_accuracy)
+{
+ return IOSC_ACCURACY;
+}
+
+const struct clk_ops ccu_iosc_ops = {
+ .enable = ccu_iosc_enable,
+ .disable = ccu_iosc_disable,
+ .is_enabled = ccu_iosc_is_enabled,
+ .recalc_rate = ccu_iosc_recalc_rate,
+ .recalc_accuracy = ccu_iosc_recalc_accuracy,
+};
+
+static int ccu_iosc_32k_prepare(struct clk_hw *hw)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+ u32 val;
+
+ if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
+ return 0;
+
+ val = readl(cm->base + IOSC_CLK_CALI_REG);
+ writel(val | IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL,
+ cm->base + IOSC_CLK_CALI_REG);
+
+ return 0;
+}
+
+static void ccu_iosc_32k_unprepare(struct clk_hw *hw)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+ u32 val;
+
+ if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
+ return;
+
+ val = readl(cm->base + IOSC_CLK_CALI_REG);
+ writel(val & ~(IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL),
+ cm->base + IOSC_CLK_CALI_REG);
+}
+
+static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+ u32 val;
+
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
+ val = readl(cm->base + IOSC_CLK_CALI_REG);
+
+ /* Assume the calibrated 32k clock is accurate. */
+ if (val & IOSC_CLK_CALI_SRC_SEL)
+ return LOSC_RATE;
+ }
+
+ val = readl(cm->base + IOSC_32K_CLK_DIV_REG) & IOSC_32K_CLK_DIV;
+
+ return parent_rate / IOSC_32K_PRE_DIV / (val + 1);
+}
+
+static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw,
+ unsigned long parent_accuracy)
+{
+ struct ccu_common *cm = hw_to_ccu_common(hw);
+ u32 val;
+
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
+ val = readl(cm->base + IOSC_CLK_CALI_REG);
+
+ /* Assume the calibrated 32k clock is accurate. */
+ if (val & IOSC_CLK_CALI_SRC_SEL)
+ return 0;
+ }
+
+ return parent_accuracy;
+}
+
+const struct clk_ops ccu_iosc_32k_ops = {
+ .prepare = ccu_iosc_32k_prepare,
+ .unprepare = ccu_iosc_32k_unprepare,
+ .recalc_rate = ccu_iosc_32k_recalc_rate,
+ .recalc_accuracy = ccu_iosc_32k_recalc_accuracy,
+};
diff --git a/drivers/clk/sunxi-ng/ccu_rtc.h b/drivers/clk/sunxi-ng/ccu_rtc.h
new file mode 100644
index 000000000000..1c44c2206a25
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_rtc.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _CCU_RTC_H_
+#define _CCU_RTC_H_
+
+#define IOSC_ACCURACY 300000000 /* 30% */
+#define IOSC_RATE 16000000
+
+#define LOSC_RATE 32768
+#define LOSC_RATE_SHIFT 15
+
+#define LOSC_CTRL_REG 0x0
+#define LOSC_CTRL_KEY 0x16aa0000
+
+#define IOSC_32K_CLK_DIV_REG 0x8
+#define IOSC_32K_CLK_DIV GENMASK(4, 0)
+#define IOSC_32K_PRE_DIV 32
+
+#define IOSC_CLK_CALI_REG 0xc
+#define IOSC_CLK_CALI_DIV_ONES 22
+#define IOSC_CLK_CALI_EN BIT(1)
+#define IOSC_CLK_CALI_SRC_SEL BIT(0)
+
+#define LOSC_OUT_GATING_REG 0x60
+
+#define DCXO_CTRL_REG 0x160
+#define DCXO_CTRL_CLK16M_RC_EN BIT(0)
+
+#define SUN6I_RTC_AUX_ID(_name) "rtc_sun6i." #_name
+
+extern const struct clk_ops ccu_iosc_ops;
+extern const struct clk_ops ccu_iosc_32k_ops;
+
+#endif /* _CCU_RTC_H_ */
--
2.52.0
^ permalink raw reply related
* [PATCH 3/7] clk: sunxi-ng: sun6i-rtc: Add feature bit for IOSC calibration
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
The sun6i-rtc CCU driver currently uses a global static variable to
denote whether calibration is supported, which makes IOSC operations
tightly coupled to this file.
Convert this into a feature bit to decouple the logic. This allows the
IOSC clock code to be moved into a shared module for reuse by other SoCs.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 17 +++++++++--------
drivers/clk/sunxi-ng/ccu_common.h | 1 +
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index 3088f247d927..6f888169412c 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -53,8 +53,6 @@ struct sun6i_rtc_match_data {
u8 osc32k_fanout_nparents;
};
-static bool have_iosc_calibration;
-
static int ccu_iosc_enable(struct clk_hw *hw)
{
struct ccu_common *cm = hw_to_ccu_common(hw);
@@ -81,7 +79,7 @@ static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw,
{
struct ccu_common *cm = hw_to_ccu_common(hw);
- if (have_iosc_calibration) {
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
u32 reg = readl(cm->base + IOSC_CLK_CALI_REG);
/*
@@ -120,7 +118,7 @@ static int ccu_iosc_32k_prepare(struct clk_hw *hw)
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
- if (!have_iosc_calibration)
+ if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
return 0;
val = readl(cm->base + IOSC_CLK_CALI_REG);
@@ -135,7 +133,7 @@ static void ccu_iosc_32k_unprepare(struct clk_hw *hw)
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
- if (!have_iosc_calibration)
+ if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
return;
val = readl(cm->base + IOSC_CLK_CALI_REG);
@@ -149,7 +147,7 @@ static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw,
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
- if (have_iosc_calibration) {
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
val = readl(cm->base + IOSC_CLK_CALI_REG);
/* Assume the calibrated 32k clock is accurate. */
@@ -168,7 +166,7 @@ static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw,
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
- if (have_iosc_calibration) {
+ if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
val = readl(cm->base + IOSC_CLK_CALI_REG);
/* Assume the calibrated 32k clock is accurate. */
@@ -366,7 +364,10 @@ static int sun6i_rtc_ccu_probe(struct auxiliary_device *adev,
return 0;
data = match->data;
- have_iosc_calibration = data->have_iosc_calibration;
+ if (data->have_iosc_calibration) {
+ iosc_clk.features |= CCU_FEATURE_IOSC_CALIBRATION;
+ iosc_32k_clk.features |= CCU_FEATURE_IOSC_CALIBRATION;
+ }
if (data->have_ext_osc32k) {
const char *fw_name;
diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h
index bbec283b9d99..d9dc24ad5503 100644
--- a/drivers/clk/sunxi-ng/ccu_common.h
+++ b/drivers/clk/sunxi-ng/ccu_common.h
@@ -21,6 +21,7 @@
#define CCU_FEATURE_CLOSEST_RATE BIT(9)
#define CCU_FEATURE_DUAL_DIV BIT(10)
#define CCU_FEATURE_UPDATE_BIT BIT(11)
+#define CCU_FEATURE_IOSC_CALIBRATION BIT(12)
/* MMC timing mode switch bit */
#define CCU_MMC_NEW_TIMING_MODE BIT(30)
--
2.52.0
^ permalink raw reply related
* [PATCH 2/7] rtc: sun6i: Bind internal CCU via auxiliary bus
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
The sun6i RTC block contains an internal clock control unit (CCU).
Currently, the RTC driver binds this CCU part by directly calling a
probe function exported by the clock framework. This creates a tight
coupling between the RTC and clock drivers and makes it difficult to
add internal CCU support for new SoCs.
Switch to use the auxiliary bus for binding the internal CCU to
decouple the drivers.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 29 +++++++++++++++++++++++------
drivers/rtc/rtc-sun6i.c | 31 +++++++++++++++++++++++--------
include/linux/clk/sunxi-ng.h | 2 --
3 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index f6bfeba009e8..3088f247d927 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -3,6 +3,7 @@
// Copyright (c) 2021 Samuel Holland <samuel@sholland.org>
//
+#include <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
@@ -11,8 +12,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/clk/sunxi-ng.h>
-
#include "ccu_common.h"
#include "ccu_div.h"
@@ -44,6 +43,8 @@
#define DCXO_CTRL_REG 0x160
#define DCXO_CTRL_CLK16M_RC_EN BIT(0)
+#define SUN6I_RTC_AUX_ID(_name) "rtc_sun6i." #_name
+
struct sun6i_rtc_match_data {
bool have_ext_osc32k : 1;
bool have_iosc_calibration : 1;
@@ -349,14 +350,18 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = {
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match);
-int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
+static int sun6i_rtc_ccu_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
{
const struct sun6i_rtc_match_data *data;
struct clk *ext_osc32k_clk = NULL;
const struct of_device_id *match;
+ struct device *dev = &adev->dev;
+ void __iomem *reg = dev->platform_data;
+ struct device *parent = dev->parent;
/* This driver is only used for newer variants of the hardware. */
- match = of_match_device(sun6i_rtc_ccu_match, dev);
+ match = of_match_device(sun6i_rtc_ccu_match, parent);
if (!match)
return 0;
@@ -367,9 +372,9 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
const char *fw_name;
/* ext-osc32k was the only input clock in the old binding. */
- fw_name = of_property_present(dev->of_node, "clock-names")
+ fw_name = of_property_present(parent->of_node, "clock-names")
? "ext-osc32k" : NULL;
- ext_osc32k_clk = devm_clk_get_optional(dev, fw_name);
+ ext_osc32k_clk = devm_clk_get_optional(parent, fw_name);
if (IS_ERR(ext_osc32k_clk))
return PTR_ERR(ext_osc32k_clk);
}
@@ -392,6 +397,18 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc);
}
+static const struct auxiliary_device_id sun6i_ccu_rtc_ids[] = {
+ { .name = SUN6I_RTC_AUX_ID(sun6i) },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, sun6i_ccu_rtc_ids);
+
+static struct auxiliary_driver sun6i_ccu_rtc_driver = {
+ .probe = sun6i_rtc_ccu_probe,
+ .id_table = sun6i_ccu_rtc_ids,
+};
+module_auxiliary_driver(sun6i_ccu_rtc_driver);
+
MODULE_IMPORT_NS("SUNXI_CCU");
MODULE_DESCRIPTION("Support for the Allwinner H616/R329 RTC CCU");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index e5e6013d080e..b4489e0a09ce 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -11,9 +11,9 @@
* Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
*/
+#include <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
-#include <linux/clk/sunxi-ng.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/fs.h>
@@ -141,6 +141,11 @@ struct sun6i_rtc_clk_data {
#define RTC_LINEAR_DAY BIT(0)
+struct sun6i_rtc_match_data {
+ const char *adev_name;
+ unsigned long flags;
+};
+
struct sun6i_rtc_dev {
struct rtc_device *rtc;
const struct sun6i_rtc_clk_data *data;
@@ -745,8 +750,10 @@ static void sun6i_rtc_bus_clk_cleanup(void *data)
static int sun6i_rtc_probe(struct platform_device *pdev)
{
+ const struct sun6i_rtc_match_data *data;
struct sun6i_rtc_dev *chip = sun6i_rtc;
struct device *dev = &pdev->dev;
+ struct auxiliary_device *adev;
struct clk *bus_clk;
int ret;
@@ -765,6 +772,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
return ret;
}
+ data = of_device_get_match_data(&pdev->dev);
+
if (!chip) {
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -776,16 +785,17 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
- if (IS_REACHABLE(CONFIG_SUN6I_RTC_CCU)) {
- ret = sun6i_rtc_ccu_probe(dev, chip->base);
- if (ret)
- return ret;
+ if (data && data->adev_name) {
+ adev = devm_auxiliary_device_create(dev, data->adev_name, chip->base);
+ if (!adev)
+ return -ENODEV;
}
}
platform_set_drvdata(pdev, chip);
- chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev);
+ if (data)
+ chip->flags = data->flags;
chip->irq = platform_get_irq(pdev, 0);
if (chip->irq < 0)
@@ -850,6 +860,11 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
return 0;
}
+static const struct sun6i_rtc_match_data sun6i_rtc_match_data = {
+ .adev_name = "sun6i",
+ .flags = RTC_LINEAR_DAY,
+};
+
/*
* As far as RTC functionality goes, all models are the same. The
* datasheets claim that different models have different number of
@@ -865,9 +880,9 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun50i-h5-rtc" },
{ .compatible = "allwinner,sun50i-h6-rtc" },
{ .compatible = "allwinner,sun50i-h616-rtc",
- .data = (void *)RTC_LINEAR_DAY },
+ .data = &sun6i_rtc_match_data },
{ .compatible = "allwinner,sun50i-r329-rtc",
- .data = (void *)RTC_LINEAR_DAY },
+ .data = &sun6i_rtc_match_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
diff --git a/include/linux/clk/sunxi-ng.h b/include/linux/clk/sunxi-ng.h
index 57c8ec44ab4e..cf32123b39f5 100644
--- a/include/linux/clk/sunxi-ng.h
+++ b/include/linux/clk/sunxi-ng.h
@@ -9,6 +9,4 @@
int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode);
int sunxi_ccu_get_mmc_timing_mode(struct clk *clk);
-int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg);
-
#endif
--
2.52.0
^ permalink raw reply related
* [PATCH 1/7] dt-bindings: rtc: sun6i: Add Allwinner A733 support
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
In-Reply-To: <20260121-a733-rtc-v1-0-d359437f23a7@pigmoral.tech>
The RTC module in the Allwinner A733 SoC is functionally compatible with
the sun6i RTC, but its internal Clock Control Unit (CCU) has significant
changes.
The A733 supports selecting the oscillator between three frequencies:
19.2MHz, 24MHz, and 26MHz. The RTC CCU relies on hardware to detect
which frequency is actually used on the board. By defining all three
frequencies as fixed-clocks in the device tree, the driver can identify
the hardware-detected frequency and expose it to the rest of the system.
Additionally, the A733 RTC CCU provides several new DCXO gate clocks for
specific modules, including SerDes, HDMI, and UFS.
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
.../bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 38 ++++++++++++++++++++--
include/dt-bindings/clock/sun60i-a733-rtc.h | 16 +++++++++
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index 9df5cdb6f63f..b18431955783 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -26,6 +26,7 @@ properties:
- allwinner,sun50i-h6-rtc
- allwinner,sun50i-h616-rtc
- allwinner,sun50i-r329-rtc
+ - allwinner,sun60i-a733-rtc
- items:
- const: allwinner,sun50i-a64-rtc
- const: allwinner,sun8i-h3-rtc
@@ -46,11 +47,11 @@ properties:
clocks:
minItems: 1
- maxItems: 4
+ maxItems: 6
clock-names:
minItems: 1
- maxItems: 4
+ maxItems: 6
clock-output-names:
minItems: 1
@@ -156,6 +157,38 @@ allOf:
- clocks
- clock-names
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: allwinner,sun60i-a733-rtc
+
+ then:
+ properties:
+ clocks:
+ minItems: 5
+ items:
+ - description: Bus clock for register access
+ - description: 19.2 MHz oscillator
+ - description: 24 MHz oscillator
+ - description: 26 MHz oscillator
+ - description: AHB parent for internal SPI clock
+ - description: External 32768 Hz oscillator
+
+ clock-names:
+ minItems: 5
+ items:
+ - const: bus
+ - const: osc19M
+ - const: osc24M
+ - const: osc26M
+ - const: ahb
+ - const: ext-osc32k
+
+ required:
+ - clocks
+ - clock-names
+
- if:
properties:
compatible:
@@ -164,6 +197,7 @@ allOf:
- allwinner,sun8i-r40-rtc
- allwinner,sun50i-h616-rtc
- allwinner,sun50i-r329-rtc
+ - allwinner,sun60i-a733-rtc
then:
properties:
diff --git a/include/dt-bindings/clock/sun60i-a733-rtc.h b/include/dt-bindings/clock/sun60i-a733-rtc.h
new file mode 100644
index 000000000000..8a2b5facad73
--- /dev/null
+++ b/include/dt-bindings/clock/sun60i-a733-rtc.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+
+#ifndef _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_
+#define _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_
+
+#define CLK_IOSC 0
+#define CLK_OSC32K 1
+#define CLK_HOSC 2
+#define CLK_RTC_32K 3
+#define CLK_OSC32K_FANOUT 4
+#define CLK_HOSC_SERDES1 5
+#define CLK_HOSC_SERDES0 6
+#define CLK_HOSC_HDMI 7
+#define CLK_HOSC_UFS 8
+
+#endif /* _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_ */
--
2.52.0
^ permalink raw reply related
* [PATCH 0/7] rtc: sun6i: Add support for Allwinner A733 SoC
From: Junhui Liu @ 2026-01-21 10:59 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Ripard
Cc: linux-clk, linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
devicetree, Junhui Liu
Add support for the Allwinner A733 RTC and its internal Clock Control
Unit (CCU). Reuse the rtc-sun6i rtc driver while introducing a new
SoC-specific RTC CCU driver to handle the hardware's evolved clock
structure.
To facilitate this addition and improve driver modularity, transition
the binding between the RTC and its internal CCU from direct
cross-subsystem function calls to the auxiliary bus. Also extract shared
IOSC and 32kHz clock logic into a standalone ccu_rtc module for reuse
across newer SoC generations.
The A733 implementation supports hardware detection of three external
crystal frequencies (19.2MHz, 24MHz and 26MHz), which is represented in
the driver via read-only mux operations. Implement logic to derive a
normalized 32kHz reference from these DCXO sources using fixed
pre-dividers. Additionally, provide several new DCXO gate clocks for
peripherals, including SerDes, HDMI, and UFS.
---
Junhui Liu (7):
dt-bindings: rtc: sun6i: Add Allwinner A733 support
rtc: sun6i: Bind internal CCU via auxiliary bus
clk: sunxi-ng: sun6i-rtc: Add feature bit for IOSC calibration
clk: sunxi-ng: Extract common RTC CCU clock logic
clk: sunxi-ng: mux: Add mux read-only clock operations
rtc: sun6i: Add support for A733 RTC
clk: sunxi-ng: Add Allwinner A733 RTC CCU support
.../bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 38 +++-
drivers/clk/sunxi-ng/Kconfig | 5 +
drivers/clk/sunxi-ng/Makefile | 5 +
drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.c | 204 +++++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun60i-a733-rtc.h | 18 ++
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 184 +++----------------
drivers/clk/sunxi-ng/ccu_common.h | 1 +
drivers/clk/sunxi-ng/ccu_mux.c | 11 ++
drivers/clk/sunxi-ng/ccu_mux.h | 1 +
drivers/clk/sunxi-ng/ccu_rtc.c | 136 ++++++++++++++
drivers/clk/sunxi-ng/ccu_rtc.h | 44 +++++
drivers/rtc/rtc-sun6i.c | 38 +++-
include/dt-bindings/clock/sun60i-a733-rtc.h | 16 ++
include/linux/clk/sunxi-ng.h | 2 -
14 files changed, 533 insertions(+), 170 deletions(-)
---
base-commit: 24d479d26b25bce5faea3ddd9fa8f3a6c3129ea7
change-id: 20251226-a733-rtc-c5167df14e6e
Best regards,
--
Junhui Liu <junhui.liu@pigmoral.tech>
^ permalink raw reply
* Re: [PATCH v2 0/3] Samsung mfd/rtc driver alarm IRQ simplification
From: Lee Jones @ 2026-01-21 8:48 UTC (permalink / raw)
To: Mark Brown
Cc: Krzysztof Kozlowski, Alexandre Belloni, André Draszik, tools,
users, Peter Griffin, Tudor Ambarus, Will McVicker, Juan Yescas,
Douglas Anderson, kernel-team, Kaustabh Chakraborty, linux-kernel,
linux-samsung-soc, linux-rtc
In-Reply-To: <916995f4-60e0-47dc-abdb-8819089d103c@sirena.org.uk>
On Tue, 20 Jan 2026, Mark Brown wrote:
> On Tue, Jan 20, 2026 at 05:24:05PM +0000, Lee Jones wrote:
> > On Tue, 20 Jan 2026, Mark Brown wrote:
>
> > > If you fetch a series but don't delete it from the database then (with
> > > b4 ty -d) then b4 will remember it and if any commits in what gets
> > > applied match it'll generate a mail for b4 ty -a. Usually that's when
> > > some commits didn't get changed.
>
> > The last attempt to apply this failed with conflicts.
>
> > I wonder why b4 stored that as a success?
>
> Are you using b4 shazam? I wonder if under the hood it's a mailbox
> fetch then an apply. I download a mailbox then script my own
> application after the fact so it's not so surprising that it happens for
> me, b4 knows nothing about the patches actually being applied until I
> tell it to go look to send thanks.
Not using shazam. This is my abbreviated workflow:
b4.sh am -3 -slt ${PATCHES} -o - ${id} > ${MBOX}
cat ${MBOX} | formail -ds ./scripts/checkpatch.pl || true
cat ${MBOX} | git am -3 --reject
kitty -o font_size=12 git rebase -i HEAD~${NOPATCHES}
b4.sh ty -aS --me-too --since=1.day
--
Lee Jones [李琼斯]
^ permalink raw reply
* Re: [PATCH v2 0/3] Samsung mfd/rtc driver alarm IRQ simplification
From: Lee Jones @ 2026-01-21 8:44 UTC (permalink / raw)
To: Konstantin Ryabitsev
Cc: Mark Brown, Krzysztof Kozlowski, Alexandre Belloni,
André Draszik, tools, users, Peter Griffin, Tudor Ambarus,
Will McVicker, Juan Yescas, Douglas Anderson, kernel-team,
Kaustabh Chakraborty, linux-kernel, linux-samsung-soc, linux-rtc
In-Reply-To: <20260120-incredible-ladybug-of-psychology-605faf@lemur>
On Tue, 20 Jan 2026, Konstantin Ryabitsev wrote:
> On Tue, Jan 20, 2026 at 05:24:05PM +0000, Lee Jones wrote:
> > > If you fetch a series but don't delete it from the database then (with
> > > b4 ty -d) then b4 will remember it and if any commits in what gets
> > > applied match it'll generate a mail for b4 ty -a. Usually that's when
> > > some commits didn't get changed.
> >
> > The last attempt to apply this failed with conflicts.
> >
> > I wonder why b4 stored that as a success?
>
> It doesn't actually know -- it just stores the retrieved series and then
> checks if it can find any of them in the tree in a commit with your
> authorship. Sometimes it breaks.
>
> My plan is to put in interactive mode where you can do a quick sanity check --
> currently it's all of nothing with "b4 ty -a".
Got it. Thanks for the explanation.
--
Lee Jones [李琼斯]
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: rtc: loongson: Correct Loongson-1C interrupts property
From: Binbin Zhou @ 2026-01-21 6:52 UTC (permalink / raw)
To: Conor Dooley
Cc: Alexandre Belloni, Binbin Zhou, Huacai Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-rtc, Xiaochuang Mao,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-mips,
Keguang Zhang
In-Reply-To: <20260120-proposal-retry-d0a1f3de10ea@spud>
Hi Conor & Alexandre:
Thanks for your reply.
On Wed, Jan 21, 2026 at 7:39 AM Conor Dooley <conor@kernel.org> wrote:
>
> On Tue, Jan 20, 2026 at 11:49:20PM +0100, Alexandre Belloni wrote:
> > On 20/01/2026 19:24:09+0000, Conor Dooley wrote:
> > > On Tue, Jan 20, 2026 at 08:50:45AM +0100, Alexandre Belloni wrote:
> > > > On 19/01/2026 18:24:36+0000, Conor Dooley wrote:
> > > > > On Sat, Jan 17, 2026 at 10:26:48AM +0800, Binbin Zhou wrote:
> > > > > > The `interrupts` property indicates an RTC alarm interrupt, which is
> > > > > > required for RTCs that support the alarm feature, which is not supported
> > > > > > by the Loongson-1C RTC. We exclude it for a more accurate description.
> > > > > >
> > > > > > Changing the `allowed` property is ABI-breaking behavior, but
> > > > > > throughout the existing Loongson DTS{i}, the description of the RTC
> > > > > > nodes conforms to the modified bingding rules.
> > > > >
> > > > > Right, changing properties is an ABI break, but when following the ABI
> > > > > would've produced something non-functional, breaking it is not really
> > > > > relevant.
> > > >
> > > >
> > > > But the HW has the interrupt, the fact that is not functional doesn't
> > > > mean it isn't there. I thought we should describe the hardware?
> > >
> > > Does the hardware have it? My interpretation of the commit message was
> > > that it didn't have the alarm feature and thus no interrupt? Unless the
> > > interrupt has some other purpose, in which case yeah we shouldn't accept
> > > this change and only the new device should permit there being no
> > > interrupt.
> >
> > The datasheet shows the interrupt coming out of the RTC and it has the
> > proper registers. Why it is not functional is not clear to me.
>
> Right.. Perhaps Binbin can explain that then? If the interrupt is
> actually there then the dts should get fixed instead IMO.
I carefully reviewed the manual again and believe this patch is still necessary.
First, the Loongson-1C RTC does not define the timing interrupt
register (`TOY_MATCH0_REG`)[1], meaning it lacks hardware support for
alarms. Consequently, `interrupts` are also unnecessary.
The Loongson-2K0300 is different. It defines `TOY_MATCH0_REG`, but due
to a hardware design flaw, accessing this register causes system
crashes. Therefore, I must also classify it as lacking alarm support.
Additionally, in patch-3 [2], I rewrote the alarm logic to decouple
the `interrupts` property from the alarm feature: I defined
corresponding workaround bits in `loongson_rtc_config->flags`. This
should be considered a SoC-specific attribute.
Finally, two thoughts:
1. Retain this patch; it is correct for Loongson-1C.
2. For Patch-2, still add the `interrupts` property to the
Loongson-2K0300 RTC node (as it exists in hardware), combined with the
workaround bit setting in patch-3 to avoid the hardware flaw.
Would this approach be acceptable?
[1]: https://www.loongson.cn/uploads/images/2022051616223977135.%E9%BE%99%E8%8A%AF1C300%E5%A4%84%E7%90%86%E5%99%A8%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C.pdf
(section 21.2.1)
[2]: https://lore.kernel.org/linux-rtc/abff68dda2fe6a6601a9e58b31e278d941297fce.1768616276.git.zhoubinbin@loongson.cn/
--
Thanks.
Binbin
^ permalink raw reply
* Re: [PATCH v2 0/3] Samsung mfd/rtc driver alarm IRQ simplification
From: Konstantin Ryabitsev @ 2026-01-21 3:23 UTC (permalink / raw)
To: Lee Jones
Cc: Mark Brown, Krzysztof Kozlowski, Alexandre Belloni,
André Draszik, tools, users, Peter Griffin, Tudor Ambarus,
Will McVicker, Juan Yescas, Douglas Anderson, kernel-team,
Kaustabh Chakraborty, linux-kernel, linux-samsung-soc, linux-rtc
In-Reply-To: <20260120172405.GI1354723@google.com>
On Tue, Jan 20, 2026 at 05:24:05PM +0000, Lee Jones wrote:
> > If you fetch a series but don't delete it from the database then (with
> > b4 ty -d) then b4 will remember it and if any commits in what gets
> > applied match it'll generate a mail for b4 ty -a. Usually that's when
> > some commits didn't get changed.
>
> The last attempt to apply this failed with conflicts.
>
> I wonder why b4 stored that as a success?
It doesn't actually know -- it just stores the retrieved series and then
checks if it can find any of them in the tree in a commit with your
authorship. Sometimes it breaks.
My plan is to put in interactive mode where you can do a quick sanity check --
currently it's all of nothing with "b4 ty -a".
-K
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: rtc: loongson: Correct Loongson-1C interrupts property
From: Conor Dooley @ 2026-01-20 23:39 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Binbin Zhou, Binbin Zhou, Huacai Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-rtc, Xiaochuang Mao,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-mips,
Keguang Zhang
In-Reply-To: <20260120224920df0cf2ac@mail.local>
[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]
On Tue, Jan 20, 2026 at 11:49:20PM +0100, Alexandre Belloni wrote:
> On 20/01/2026 19:24:09+0000, Conor Dooley wrote:
> > On Tue, Jan 20, 2026 at 08:50:45AM +0100, Alexandre Belloni wrote:
> > > On 19/01/2026 18:24:36+0000, Conor Dooley wrote:
> > > > On Sat, Jan 17, 2026 at 10:26:48AM +0800, Binbin Zhou wrote:
> > > > > The `interrupts` property indicates an RTC alarm interrupt, which is
> > > > > required for RTCs that support the alarm feature, which is not supported
> > > > > by the Loongson-1C RTC. We exclude it for a more accurate description.
> > > > >
> > > > > Changing the `allowed` property is ABI-breaking behavior, but
> > > > > throughout the existing Loongson DTS{i}, the description of the RTC
> > > > > nodes conforms to the modified bingding rules.
> > > >
> > > > Right, changing properties is an ABI break, but when following the ABI
> > > > would've produced something non-functional, breaking it is not really
> > > > relevant.
> > >
> > >
> > > But the HW has the interrupt, the fact that is not functional doesn't
> > > mean it isn't there. I thought we should describe the hardware?
> >
> > Does the hardware have it? My interpretation of the commit message was
> > that it didn't have the alarm feature and thus no interrupt? Unless the
> > interrupt has some other purpose, in which case yeah we shouldn't accept
> > this change and only the new device should permit there being no
> > interrupt.
>
> The datasheet shows the interrupt coming out of the RTC and it has the
> proper registers. Why it is not functional is not clear to me.
Right.. Perhaps Binbin can explain that then? If the interrupt is
actually there then the dts should get fixed instead IMO.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: rtc: loongson: Correct Loongson-1C interrupts property
From: Alexandre Belloni @ 2026-01-20 22:49 UTC (permalink / raw)
To: Conor Dooley
Cc: Binbin Zhou, Binbin Zhou, Huacai Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-rtc, Xiaochuang Mao,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-mips,
Keguang Zhang
In-Reply-To: <20260120-cubical-harmonica-a7b7bbb26b08@spud>
On 20/01/2026 19:24:09+0000, Conor Dooley wrote:
> On Tue, Jan 20, 2026 at 08:50:45AM +0100, Alexandre Belloni wrote:
> > On 19/01/2026 18:24:36+0000, Conor Dooley wrote:
> > > On Sat, Jan 17, 2026 at 10:26:48AM +0800, Binbin Zhou wrote:
> > > > The `interrupts` property indicates an RTC alarm interrupt, which is
> > > > required for RTCs that support the alarm feature, which is not supported
> > > > by the Loongson-1C RTC. We exclude it for a more accurate description.
> > > >
> > > > Changing the `allowed` property is ABI-breaking behavior, but
> > > > throughout the existing Loongson DTS{i}, the description of the RTC
> > > > nodes conforms to the modified bingding rules.
> > >
> > > Right, changing properties is an ABI break, but when following the ABI
> > > would've produced something non-functional, breaking it is not really
> > > relevant.
> >
> >
> > But the HW has the interrupt, the fact that is not functional doesn't
> > mean it isn't there. I thought we should describe the hardware?
>
> Does the hardware have it? My interpretation of the commit message was
> that it didn't have the alarm feature and thus no interrupt? Unless the
> interrupt has some other purpose, in which case yeah we shouldn't accept
> this change and only the new device should permit there being no
> interrupt.
The datasheet shows the interrupt coming out of the RTC and it has the
proper registers. Why it is not functional is not clear to me.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ 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