* [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel
@ 2025-07-05 16:01 Daniel Lezcano
2025-07-05 16:01 ` [PATCH 02/20] clocksource/drivers/vf_pit: Add COMPILE_TEST option Daniel Lezcano
` (19 more replies)
0 siblings, 20 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: ghennadi.procopciuc, S32, linux-kernel, Arnd Bergmann
The driver uses the raw_readl() and raw_writel() functions. Those are
not for MMIO devices. Replace them with readl() and writel()
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
drivers/clocksource/timer-vf-pit.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 911c92146eca..8041a8f62d1f 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -35,30 +35,30 @@ static unsigned long cycle_per_jiffy;
static inline void pit_timer_enable(void)
{
- __raw_writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL);
+ writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL);
}
static inline void pit_timer_disable(void)
{
- __raw_writel(0, clkevt_base + PITTCTRL);
+ writel(0, clkevt_base + PITTCTRL);
}
static inline void pit_irq_acknowledge(void)
{
- __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+ writel(PITTFLG_TIF, clkevt_base + PITTFLG);
}
static u64 notrace pit_read_sched_clock(void)
{
- return ~__raw_readl(clksrc_base + PITCVAL);
+ return ~readl(clksrc_base + PITCVAL);
}
static int __init pit_clocksource_init(unsigned long rate)
{
/* set the max load value and start the clock source counter */
- __raw_writel(0, clksrc_base + PITTCTRL);
- __raw_writel(~0UL, clksrc_base + PITLDVAL);
- __raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
+ writel(0, clksrc_base + PITTCTRL);
+ writel(~0UL, clksrc_base + PITLDVAL);
+ writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
sched_clock_register(pit_read_sched_clock, 32, rate);
return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
@@ -76,7 +76,7 @@ static int pit_set_next_event(unsigned long delta,
* hardware requirement.
*/
pit_timer_disable();
- __raw_writel(delta - 1, clkevt_base + PITLDVAL);
+ writel(delta - 1, clkevt_base + PITLDVAL);
pit_timer_enable();
return 0;
@@ -125,8 +125,8 @@ static struct clock_event_device clockevent_pit = {
static int __init pit_clockevent_init(unsigned long rate, int irq)
{
- __raw_writel(0, clkevt_base + PITTCTRL);
- __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+ writel(0, clkevt_base + PITTCTRL);
+ writel(PITTFLG_TIF, clkevt_base + PITTFLG);
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
"VF pit timer", &clockevent_pit));
@@ -183,7 +183,7 @@ static int __init pit_timer_init(struct device_node *np)
cycle_per_jiffy = clk_rate / (HZ);
/* enable the pit module */
- __raw_writel(~PITMCR_MDIS, timer_base + PITMCR);
+ writel(~PITMCR_MDIS, timer_base + PITMCR);
ret = pit_clocksource_init(clk_rate);
if (ret)
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 02/20] clocksource/drivers/vf_pit: Add COMPILE_TEST option
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers Daniel Lezcano
` (18 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The VF PIT driver is a silent koption. In order to allow a better
compilation test coverage, let's add the COMPILE_TEST option so it can
be selected on other platforms than the Vybrid Family.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 645f517a1ac2..6f7d371904df 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -475,7 +475,7 @@ config FSL_FTM_TIMER
Support for Freescale FlexTimer Module (FTM) timer.
config VF_PIT_TIMER
- bool
+ bool "Vybrid Family Programmable timer" if COMPILE_TEST
select CLKSRC_MMIO
help
Support for Periodic Interrupt Timer on Freescale Vybrid Family SoCs.
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
2025-07-05 16:01 ` [PATCH 02/20] clocksource/drivers/vf_pit: Add COMPILE_TEST option Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 12:04 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage Daniel Lezcano
` (17 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The driver is implemented as using a single timer and a single
clocksource. In order to take advantage of the multiple timers
supported in the PIT hardware and introduce different setup for a new
platform, let's encapsulate the data into a structure and pass this
structure around in the function parameter. The structure will be a
per timer instanciation in the next changes.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 119 +++++++++++++++++------------
1 file changed, 70 insertions(+), 49 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 8041a8f62d1f..581b46e7b111 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -15,7 +15,7 @@
*/
#define PITMCR 0x00
#define PIT0_OFFSET 0x100
-#define PITn_OFFSET(n) (PIT0_OFFSET + 0x10 * (n))
+#define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
#define PITLDVAL 0x00
#define PITCVAL 0x04
#define PITTCTRL 0x08
@@ -29,23 +29,36 @@
#define PITTFLG_TIF 0x1
+struct pit_timer {
+ void __iomem *clksrc_base;
+ void __iomem *clkevt_base;
+ unsigned long cycle_per_jiffy;
+ struct clock_event_device ced;
+ struct clocksource cs;
+};
+
+static struct pit_timer pit_timer;
+
static void __iomem *clksrc_base;
-static void __iomem *clkevt_base;
-static unsigned long cycle_per_jiffy;
-static inline void pit_timer_enable(void)
+static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced)
+{
+ return container_of(ced, struct pit_timer, ced);
+}
+
+static inline void pit_timer_enable(struct pit_timer *pit)
{
- writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL);
+ writel(PITTCTRL_TEN | PITTCTRL_TIE, pit->clkevt_base + PITTCTRL);
}
-static inline void pit_timer_disable(void)
+static inline void pit_timer_disable(struct pit_timer *pit)
{
- writel(0, clkevt_base + PITTCTRL);
+ writel(0, pit->clkevt_base + PITTCTRL);
}
-static inline void pit_irq_acknowledge(void)
+static inline void pit_irq_acknowledge(struct pit_timer *pit)
{
- writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+ writel(PITTFLG_TIF, pit->clkevt_base + PITTFLG);
}
static u64 notrace pit_read_sched_clock(void)
@@ -53,21 +66,22 @@ static u64 notrace pit_read_sched_clock(void)
return ~readl(clksrc_base + PITCVAL);
}
-static int __init pit_clocksource_init(unsigned long rate)
+static int __init pit_clocksource_init(struct pit_timer *pit, unsigned long rate)
{
/* set the max load value and start the clock source counter */
- writel(0, clksrc_base + PITTCTRL);
- writel(~0UL, clksrc_base + PITLDVAL);
- writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
+ writel(0, pit->clksrc_base + PITTCTRL);
+ writel(~0, pit->clksrc_base + PITLDVAL);
+ writel(PITTCTRL_TEN, pit->clksrc_base + PITTCTRL);
sched_clock_register(pit_read_sched_clock, 32, rate);
- return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
+ return clocksource_mmio_init(pit->clksrc_base + PITCVAL, "vf-pit", rate,
300, 32, clocksource_mmio_readl_down);
}
-static int pit_set_next_event(unsigned long delta,
- struct clock_event_device *unused)
+static int pit_set_next_event(unsigned long delta, struct clock_event_device *ced)
{
+ struct pit_timer *pit = ced_to_pit(ced);
+
/*
* set a new value to PITLDVAL register will not restart the timer,
* to abort the current cycle and start a timer period with the new
@@ -75,30 +89,37 @@ static int pit_set_next_event(unsigned long delta,
* and the PITLAVAL should be set to delta minus one according to pit
* hardware requirement.
*/
- pit_timer_disable();
- writel(delta - 1, clkevt_base + PITLDVAL);
- pit_timer_enable();
+ pit_timer_disable(pit);
+ writel(delta - 1, pit->clkevt_base + PITLDVAL);
+ pit_timer_enable(pit);
return 0;
}
-static int pit_shutdown(struct clock_event_device *evt)
+static int pit_shutdown(struct clock_event_device *ced)
{
- pit_timer_disable();
+ struct pit_timer *pit = ced_to_pit(ced);
+
+ pit_timer_disable(pit);
+
return 0;
}
-static int pit_set_periodic(struct clock_event_device *evt)
+static int pit_set_periodic(struct clock_event_device *ced)
{
- pit_set_next_event(cycle_per_jiffy, evt);
+ struct pit_timer *pit = ced_to_pit(ced);
+
+ pit_set_next_event(pit->cycle_per_jiffy, ced);
+
return 0;
}
static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = dev_id;
+ struct clock_event_device *ced = dev_id;
+ struct pit_timer *pit = ced_to_pit(ced);
- pit_irq_acknowledge();
+ pit_irq_acknowledge(pit);
/*
* pit hardware doesn't support oneshot, it will generate an interrupt
@@ -106,33 +127,33 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
* and start the counter again. So software need to disable the timer
* to stop the counter loop in ONESHOT mode.
*/
- if (likely(clockevent_state_oneshot(evt)))
- pit_timer_disable();
+ if (likely(clockevent_state_oneshot(ced)))
+ pit_timer_disable(pit);
- evt->event_handler(evt);
+ ced->event_handler(ced);
return IRQ_HANDLED;
}
-static struct clock_event_device clockevent_pit = {
- .name = "VF pit timer",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_state_shutdown = pit_shutdown,
- .set_state_periodic = pit_set_periodic,
- .set_next_event = pit_set_next_event,
- .rating = 300,
-};
-
-static int __init pit_clockevent_init(unsigned long rate, int irq)
+static int __init pit_clockevent_init(struct pit_timer *pit, unsigned long rate, int irq)
{
- writel(0, clkevt_base + PITTCTRL);
- writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+ writel(0, pit->clkevt_base + PITTCTRL);
+
+ writel(PITTFLG_TIF, pit->clkevt_base + PITTFLG);
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
- "VF pit timer", &clockevent_pit));
+ "VF pit timer", &pit->ced));
+
+ pit->ced.cpumask = cpumask_of(0);
+ pit->ced.irq = irq;
+
+ pit->ced.name = "VF pit timer";
+ pit->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ pit->ced.set_state_shutdown = pit_shutdown;
+ pit->ced.set_state_periodic = pit_set_periodic;
+ pit->ced.set_next_event = pit_set_next_event;
+ pit->ced.rating = 300;
- clockevent_pit.cpumask = cpumask_of(0);
- clockevent_pit.irq = irq;
/*
* The value for the LDVAL register trigger is calculated as:
* LDVAL trigger = (period / clock period) - 1
@@ -141,7 +162,7 @@ static int __init pit_clockevent_init(unsigned long rate, int irq)
* LDVAL trigger value is 1. And then the min_delta is
* minimal LDVAL trigger value + 1, and the max_delta is full 32-bit.
*/
- clockevents_config_and_register(&clockevent_pit, rate, 2, 0xffffffff);
+ clockevents_config_and_register(&pit->ced, rate, 2, 0xffffffff);
return 0;
}
@@ -164,8 +185,8 @@ static int __init pit_timer_init(struct device_node *np)
* so choose PIT2 as clocksource, PIT3 as clockevent device,
* and leave PIT0 and PIT1 unused for anyone else who needs them.
*/
- clksrc_base = timer_base + PITn_OFFSET(2);
- clkevt_base = timer_base + PITn_OFFSET(3);
+ pit_timer.clksrc_base = timer_base + PIT_CH(2);
+ pit_timer.clkevt_base = timer_base + PIT_CH(3);
irq = irq_of_parse_and_map(np, 0);
if (irq <= 0)
@@ -180,15 +201,15 @@ static int __init pit_timer_init(struct device_node *np)
return ret;
clk_rate = clk_get_rate(pit_clk);
- cycle_per_jiffy = clk_rate / (HZ);
+ pit_timer.cycle_per_jiffy = clk_rate / (HZ);
/* enable the pit module */
writel(~PITMCR_MDIS, timer_base + PITMCR);
- ret = pit_clocksource_init(clk_rate);
+ ret = pit_clocksource_init(&pit_timer, clk_rate);
if (ret)
return ret;
- return pit_clockevent_init(clk_rate, irq);
+ return pit_clockevent_init(&pit_timer, clk_rate, irq);
}
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
2025-07-05 16:01 ` [PATCH 02/20] clocksource/drivers/vf_pit: Add COMPILE_TEST option Daniel Lezcano
2025-07-05 16:01 ` [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter Daniel Lezcano
` (16 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
This change passes the base address to the clockevent and clocksource
initialization functions in order to use different base address in the
next changes.
No functional changes intended.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 37 +++++++++++++++++++-----------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 581b46e7b111..34edb23194c5 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -66,16 +66,27 @@ static u64 notrace pit_read_sched_clock(void)
return ~readl(clksrc_base + PITCVAL);
}
-static int __init pit_clocksource_init(struct pit_timer *pit, unsigned long rate)
+static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base,
+ unsigned long rate)
{
+ /*
+ * PIT0 and PIT1 can be chained to build a 64-bit timer, so
+ * choose PIT2 as clocksource and leave PIT0 and PIT1 unused
+ * for anyone else who needs them.
+ */
+ pit->clksrc_base = base + PIT_CH(2);
+
/* set the max load value and start the clock source counter */
writel(0, pit->clksrc_base + PITTCTRL);
writel(~0, pit->clksrc_base + PITLDVAL);
writel(PITTCTRL_TEN, pit->clksrc_base + PITTCTRL);
+ clksrc_base = pit->clksrc_base;
+
sched_clock_register(pit_read_sched_clock, 32, rate);
+
return clocksource_mmio_init(pit->clksrc_base + PITCVAL, "vf-pit", rate,
- 300, 32, clocksource_mmio_readl_down);
+ 300, 32, clocksource_mmio_readl_down);
}
static int pit_set_next_event(unsigned long delta, struct clock_event_device *ced)
@@ -135,8 +146,16 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init pit_clockevent_init(struct pit_timer *pit, unsigned long rate, int irq)
+static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
+ unsigned long rate, int irq)
{
+ /*
+ * PIT0 and PIT1 can be chained to build a 64-bit timer, so
+ * choose PIT3 as clockevent and leave PIT0 and PIT1 unused
+ * for anyone else who needs them.
+ */
+ pit->clkevt_base = base + PIT_CH(3);
+
writel(0, pit->clkevt_base + PITTCTRL);
writel(PITTFLG_TIF, pit->clkevt_base + PITTFLG);
@@ -180,14 +199,6 @@ static int __init pit_timer_init(struct device_node *np)
return -ENXIO;
}
- /*
- * PIT0 and PIT1 can be chained to build a 64-bit timer,
- * so choose PIT2 as clocksource, PIT3 as clockevent device,
- * and leave PIT0 and PIT1 unused for anyone else who needs them.
- */
- pit_timer.clksrc_base = timer_base + PIT_CH(2);
- pit_timer.clkevt_base = timer_base + PIT_CH(3);
-
irq = irq_of_parse_and_map(np, 0);
if (irq <= 0)
return -EINVAL;
@@ -206,10 +217,10 @@ static int __init pit_timer_init(struct device_node *np)
/* enable the pit module */
writel(~PITMCR_MDIS, timer_base + PITMCR);
- ret = pit_clocksource_init(&pit_timer, clk_rate);
+ ret = pit_clocksource_init(&pit_timer, timer_base, clk_rate);
if (ret)
return ret;
- return pit_clockevent_init(&pit_timer, clk_rate, irq);
+ return pit_clockevent_init(&pit_timer, timer_base, clk_rate, irq);
}
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (2 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 9:33 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 06/20] clocksource/drivers/vf_pit: Encapsulate the initialization of the cycles_per_jiffy Daniel Lezcano
` (15 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
In order to initialize the timer with a cpumask tied to a cpu, let's
pass it as a parameter instead of hardwiring it in the init function.
No functional changes intended.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 34edb23194c5..20f637c8e856 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -147,7 +147,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
}
static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
- unsigned long rate, int irq)
+ unsigned long rate, int irq, int cpu)
{
/*
* PIT0 and PIT1 can be chained to build a 64-bit timer, so
@@ -163,7 +163,7 @@ static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
"VF pit timer", &pit->ced));
- pit->ced.cpumask = cpumask_of(0);
+ pit->ced.cpumask = cpumask_of(cpu);
pit->ced.irq = irq;
pit->ced.name = "VF pit timer";
@@ -221,6 +221,6 @@ static int __init pit_timer_init(struct device_node *np)
if (ret)
return ret;
- return pit_clockevent_init(&pit_timer, timer_base, clk_rate, irq);
+ return pit_clockevent_init(&pit_timer, timer_base, clk_rate, irq, 0);
}
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 06/20] clocksource/drivers/vf_pit: Encapsulate the initialization of the cycles_per_jiffy
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (3 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 07/20] clocksource/drivers/vf-pit: Allocate the struct timer at init time Daniel Lezcano
` (14 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Move the cycles_per_jiffy initialization to the same place where the
other pit timer fields are initialized.
No functional changes intended.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 20f637c8e856..3c1ac05626de 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -155,6 +155,7 @@ static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
* for anyone else who needs them.
*/
pit->clkevt_base = base + PIT_CH(3);
+ pit->cycle_per_jiffy = rate / (HZ);
writel(0, pit->clkevt_base + PITTCTRL);
@@ -212,7 +213,6 @@ static int __init pit_timer_init(struct device_node *np)
return ret;
clk_rate = clk_get_rate(pit_clk);
- pit_timer.cycle_per_jiffy = clk_rate / (HZ);
/* enable the pit module */
writel(~PITMCR_MDIS, timer_base + PITMCR);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 07/20] clocksource/drivers/vf-pit: Allocate the struct timer at init time
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (4 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 06/20] clocksource/drivers/vf_pit: Encapsulate the initialization of the cycles_per_jiffy Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 08/20] clocksource/drivers/vf-pit: Convert raw values to BIT macros Daniel Lezcano
` (13 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Instead of having a static global structure for a timer, let's
allocate it dynamically so we can create multiple instances in the
future to support multiple timers. At the same time, add the
rollbacking code in case of error.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 48 +++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 3c1ac05626de..e1f1e66a2664 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -37,8 +37,6 @@ struct pit_timer {
struct clocksource cs;
};
-static struct pit_timer pit_timer;
-
static void __iomem *clksrc_base;
static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced)
@@ -189,38 +187,66 @@ static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
static int __init pit_timer_init(struct device_node *np)
{
+ struct pit_timer *pit;
struct clk *pit_clk;
void __iomem *timer_base;
unsigned long clk_rate;
int irq, ret;
+ pit = kzalloc(sizeof(*pit), GFP_KERNEL);
+ if (!pit)
+ return -ENOMEM;
+
+ ret = -ENXIO;
timer_base = of_iomap(np, 0);
if (!timer_base) {
pr_err("Failed to iomap\n");
- return -ENXIO;
+ goto out_kfree;
}
+ ret = -EINVAL;
irq = irq_of_parse_and_map(np, 0);
- if (irq <= 0)
- return -EINVAL;
+ if (irq <= 0) {
+ pr_err("Failed to irq_of_parse_and_map\n");
+ goto out_iounmap;
+ }
pit_clk = of_clk_get(np, 0);
- if (IS_ERR(pit_clk))
- return PTR_ERR(pit_clk);
+ if (IS_ERR(pit_clk)) {
+ ret = PTR_ERR(pit_clk);
+ goto out_iounmap;
+ }
ret = clk_prepare_enable(pit_clk);
if (ret)
- return ret;
+ goto out_clk_put;
clk_rate = clk_get_rate(pit_clk);
/* enable the pit module */
writel(~PITMCR_MDIS, timer_base + PITMCR);
- ret = pit_clocksource_init(&pit_timer, timer_base, clk_rate);
+ ret = pit_clocksource_init(pit, timer_base, clk_rate);
if (ret)
- return ret;
+ goto out_disable_unprepare;
+
+ ret = pit_clockevent_init(pit, timer_base, clk_rate, irq, 0);
+ if (ret)
+ goto out_pit_clocksource_unregister;
+
+ return 0;
- return pit_clockevent_init(&pit_timer, timer_base, clk_rate, irq, 0);
+out_pit_clocksource_unregister:
+ clocksource_unregister(&pit->cs);
+out_disable_unprepare:
+ clk_disable_unprepare(pit_clk);
+out_clk_put:
+ clk_put(pit_clk);
+out_iounmap:
+ iounmap(timer_base);
+out_kfree:
+ kfree(pit);
+
+ return ret;
}
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 08/20] clocksource/drivers/vf-pit: Convert raw values to BIT macros
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (5 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 07/20] clocksource/drivers/vf-pit: Allocate the struct timer at init time Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver Daniel Lezcano
` (12 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Use the BIT macros instead of the shifting syntax.
No functional change intended.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index e1f1e66a2664..be71c215d641 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -21,11 +21,11 @@
#define PITTCTRL 0x08
#define PITTFLG 0x0c
-#define PITMCR_MDIS (0x1 << 1)
+#define PITMCR_MDIS BIT(1)
-#define PITTCTRL_TEN (0x1 << 0)
-#define PITTCTRL_TIE (0x1 << 1)
-#define PITCTRL_CHN (0x1 << 2)
+#define PITTCTRL_TEN BIT(0)
+#define PITTCTRL_TIE BIT(1)
+#define PITCTRL_CHN BIT(2)
#define PITTFLG_TIF 0x1
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (6 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 08/20] clocksource/drivers/vf-pit: Convert raw values to BIT macros Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros Daniel Lezcano
` (11 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The function clocksource_mmio_init() uses its own global static
clocksource variable making no possible to have several instances of a
clocksource using this function. In order to support that, let's add
the clocksource structure to the pit structure and use the
clocksource_register_hz() function instead.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index be71c215d641..066d0d2600f4 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -44,6 +44,11 @@ static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced)
return container_of(ced, struct pit_timer, ced);
}
+static inline struct pit_timer *cs_to_pit(struct clocksource *cs)
+{
+ return container_of(cs, struct pit_timer, cs);
+}
+
static inline void pit_timer_enable(struct pit_timer *pit)
{
writel(PITTCTRL_TEN | PITTCTRL_TIE, pit->clkevt_base + PITTCTRL);
@@ -64,6 +69,13 @@ static u64 notrace pit_read_sched_clock(void)
return ~readl(clksrc_base + PITCVAL);
}
+static u64 pit_timer_clocksource_read(struct clocksource *cs)
+{
+ struct pit_timer *pit = cs_to_pit(cs);
+
+ return ~(u64)readl(pit->clksrc_base + PITCVAL);
+}
+
static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base,
unsigned long rate)
{
@@ -73,6 +85,11 @@ static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base
* for anyone else who needs them.
*/
pit->clksrc_base = base + PIT_CH(2);
+ pit->cs.name = "vf-pit";
+ pit->cs.rating = 300;
+ pit->cs.read = pit_timer_clocksource_read;
+ pit->cs.mask = CLOCKSOURCE_MASK(32);
+ pit->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
/* set the max load value and start the clock source counter */
writel(0, pit->clksrc_base + PITTCTRL);
@@ -83,8 +100,7 @@ static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base
sched_clock_register(pit_read_sched_clock, 32, rate);
- return clocksource_mmio_init(pit->clksrc_base + PITCVAL, "vf-pit", rate,
- 300, 32, clocksource_mmio_readl_down);
+ return clocksource_register_hz(&pit->cs, rate);
}
static int pit_set_next_event(unsigned long delta, struct clock_event_device *ced)
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (7 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 11/20] clocksource/drivers/vf-pit: Encapsulate the PTLCVAL macro Daniel Lezcano
` (10 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Pass the base address to the macro, so we can use the macro with
multiple instances of the timer because we deal with different base
address. At the same time, change writes to the register to the
existing corresponding functions.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 35 ++++++++++++++++--------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 066d0d2600f4..9c5e06506c26 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -16,18 +16,21 @@
#define PITMCR 0x00
#define PIT0_OFFSET 0x100
#define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
-#define PITLDVAL 0x00
+
#define PITCVAL 0x04
-#define PITTCTRL 0x08
-#define PITTFLG 0x0c
#define PITMCR_MDIS BIT(1)
-#define PITTCTRL_TEN BIT(0)
-#define PITTCTRL_TIE BIT(1)
-#define PITCTRL_CHN BIT(2)
+#define PITLDVAL(__base) (__base)
+#define PITTCTRL(__base) ((__base) + 0x08)
+
+
+#define PITTCTRL_TEN BIT(0)
+#define PITTCTRL_TIE BIT(1)
+
+#define PITTFLG(__base) ((__base) + 0x0c)
-#define PITTFLG_TIF 0x1
+#define PITTFLG_TIF BIT(0)
struct pit_timer {
void __iomem *clksrc_base;
@@ -51,17 +54,17 @@ static inline struct pit_timer *cs_to_pit(struct clocksource *cs)
static inline void pit_timer_enable(struct pit_timer *pit)
{
- writel(PITTCTRL_TEN | PITTCTRL_TIE, pit->clkevt_base + PITTCTRL);
+ writel(PITTCTRL_TEN | PITTCTRL_TIE, PITTCTRL(pit->clkevt_base));
}
static inline void pit_timer_disable(struct pit_timer *pit)
{
- writel(0, pit->clkevt_base + PITTCTRL);
+ writel(0, PITTCTRL(pit->clkevt_base));
}
static inline void pit_irq_acknowledge(struct pit_timer *pit)
{
- writel(PITTFLG_TIF, pit->clkevt_base + PITTFLG);
+ writel(PITTFLG_TIF, PITTFLG(pit->clkevt_base));
}
static u64 notrace pit_read_sched_clock(void)
@@ -92,9 +95,9 @@ static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base
pit->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
/* set the max load value and start the clock source counter */
- writel(0, pit->clksrc_base + PITTCTRL);
- writel(~0, pit->clksrc_base + PITLDVAL);
- writel(PITTCTRL_TEN, pit->clksrc_base + PITTCTRL);
+ pit_timer_disable(pit);
+ writel(~0, PITLDVAL(pit->clksrc_base));
+ writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
clksrc_base = pit->clksrc_base;
@@ -115,7 +118,7 @@ static int pit_set_next_event(unsigned long delta, struct clock_event_device *ce
* hardware requirement.
*/
pit_timer_disable(pit);
- writel(delta - 1, pit->clkevt_base + PITLDVAL);
+ writel(delta - 1, PITLDVAL(pit->clkevt_base));
pit_timer_enable(pit);
return 0;
@@ -171,9 +174,9 @@ static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
pit->clkevt_base = base + PIT_CH(3);
pit->cycle_per_jiffy = rate / (HZ);
- writel(0, pit->clkevt_base + PITTCTRL);
+ pit_timer_disable(pit);
- writel(PITTFLG_TIF, pit->clkevt_base + PITTFLG);
+ pit_irq_acknowledge(pit);
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
"VF pit timer", &pit->ced));
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 11/20] clocksource/drivers/vf-pit: Encapsulate the PTLCVAL macro
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (8 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names Daniel Lezcano
` (9 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Pass the channel and the base address to the PITLCVAL macro so it is
possible to use multiple instances of the timer with the macro.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 9c5e06506c26..bd90c607c45e 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -17,13 +17,13 @@
#define PIT0_OFFSET 0x100
#define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
-#define PITCVAL 0x04
-
#define PITMCR_MDIS BIT(1)
#define PITLDVAL(__base) (__base)
#define PITTCTRL(__base) ((__base) + 0x08)
+#define PITCVAL_OFFSET 0x04
+#define PITCVAL(__base) ((__base) + 0x04)
#define PITTCTRL_TEN BIT(0)
#define PITTCTRL_TIE BIT(1)
@@ -40,7 +40,7 @@ struct pit_timer {
struct clocksource cs;
};
-static void __iomem *clksrc_base;
+static void __iomem *sched_clock_base;
static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced)
{
@@ -69,14 +69,14 @@ static inline void pit_irq_acknowledge(struct pit_timer *pit)
static u64 notrace pit_read_sched_clock(void)
{
- return ~readl(clksrc_base + PITCVAL);
+ return ~readl(sched_clock_base);
}
static u64 pit_timer_clocksource_read(struct clocksource *cs)
{
struct pit_timer *pit = cs_to_pit(cs);
- return ~(u64)readl(pit->clksrc_base + PITCVAL);
+ return ~(u64)readl(PITCVAL(pit->clksrc_base));
}
static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base,
@@ -99,8 +99,7 @@ static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base
writel(~0, PITLDVAL(pit->clksrc_base));
writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
- clksrc_base = pit->clksrc_base;
-
+ sched_clock_base = pit->clksrc_base + PITCVAL_OFFSET;
sched_clock_register(pit_read_sched_clock, 32, rate);
return clocksource_register_hz(&pit->cs, rate);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (9 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 11/20] clocksource/drivers/vf-pit: Encapsulate the PTLCVAL macro Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-25 5:12 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 13/20] clocksource/drivers/vf-pit: Encapsulate clocksource enable / disable Daniel Lezcano
` (8 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
In ordero to differentiate from userspace the pit timer given the
device tree, let's use the node name for the interrupt and the timer
names.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index bd90c607c45e..71a17b6aab06 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -79,8 +79,8 @@ static u64 pit_timer_clocksource_read(struct clocksource *cs)
return ~(u64)readl(PITCVAL(pit->clksrc_base));
}
-static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base,
- unsigned long rate)
+static int __init pit_clocksource_init(struct pit_timer *pit, const char *name,
+ void __iomem *base, unsigned long rate)
{
/*
* PIT0 and PIT1 can be chained to build a 64-bit timer, so
@@ -88,7 +88,7 @@ static int __init pit_clocksource_init(struct pit_timer *pit, void __iomem *base
* for anyone else who needs them.
*/
pit->clksrc_base = base + PIT_CH(2);
- pit->cs.name = "vf-pit";
+ pit->cs.name = name;
pit->cs.rating = 300;
pit->cs.read = pit_timer_clocksource_read;
pit->cs.mask = CLOCKSOURCE_MASK(32);
@@ -162,8 +162,8 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
- unsigned long rate, int irq, int cpu)
+static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
+ void __iomem *base, unsigned long rate, int irq, int cpu)
{
/*
* PIT0 and PIT1 can be chained to build a 64-bit timer, so
@@ -178,12 +178,12 @@ static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
pit_irq_acknowledge(pit);
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
- "VF pit timer", &pit->ced));
+ name, &pit->ced));
pit->ced.cpumask = cpumask_of(cpu);
pit->ced.irq = irq;
- pit->ced.name = "VF pit timer";
+ pit->ced.name = name;
pit->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
pit->ced.set_state_shutdown = pit_shutdown;
pit->ced.set_state_periodic = pit_set_periodic;
@@ -208,6 +208,7 @@ static int __init pit_timer_init(struct device_node *np)
struct pit_timer *pit;
struct clk *pit_clk;
void __iomem *timer_base;
+ const char *name = of_node_full_name(np);
unsigned long clk_rate;
int irq, ret;
@@ -244,11 +245,11 @@ static int __init pit_timer_init(struct device_node *np)
/* enable the pit module */
writel(~PITMCR_MDIS, timer_base + PITMCR);
- ret = pit_clocksource_init(pit, timer_base, clk_rate);
+ ret = pit_clocksource_init(pit, name, timer_base, clk_rate);
if (ret)
goto out_disable_unprepare;
- ret = pit_clockevent_init(pit, timer_base, clk_rate, irq, 0);
+ ret = pit_clockevent_init(pit, name, timer_base, clk_rate, irq, 0);
if (ret)
goto out_pit_clocksource_unregister;
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 13/20] clocksource/drivers/vf-pit: Encapsulate clocksource enable / disable
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (10 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 14/20] clocksource/drivers/vf-pit: Enable and disable module on error Daniel Lezcano
` (7 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
For the sake of lisibility, let's encapsulate the writel calls to
enable and disable the timer into a function with a self-explainatory
name.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 71a17b6aab06..2799cff2a296 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -62,6 +62,16 @@ static inline void pit_timer_disable(struct pit_timer *pit)
writel(0, PITTCTRL(pit->clkevt_base));
}
+static inline void pit_clocksource_enable(struct pit_timer *pit)
+{
+ writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
+}
+
+static inline void pit_clocksource_disable(struct pit_timer *pit)
+{
+ pit_timer_disable(pit);
+}
+
static inline void pit_irq_acknowledge(struct pit_timer *pit)
{
writel(PITTFLG_TIF, PITTFLG(pit->clkevt_base));
@@ -95,9 +105,9 @@ static int __init pit_clocksource_init(struct pit_timer *pit, const char *name,
pit->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
/* set the max load value and start the clock source counter */
- pit_timer_disable(pit);
+ pit_clocksource_disable(pit);
writel(~0, PITLDVAL(pit->clksrc_base));
- writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
+ pit_clocksource_enable(pit);
sched_clock_base = pit->clksrc_base + PITCVAL_OFFSET;
sched_clock_register(pit_read_sched_clock, 32, rate);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 14/20] clocksource/drivers/vf-pit: Enable and disable module on error
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (11 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 13/20] clocksource/drivers/vf-pit: Encapsulate clocksource enable / disable Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 15/20] clocksource/drivers/vf-pit: Encapsulate set counter function Daniel Lezcano
` (6 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Encapsulate the calls to writel to enable and disable the PIT module
and make use of them. Add the missing module disablement in case of
error.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 2799cff2a296..043e36b2165d 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -13,10 +13,12 @@
/*
* Each pit takes 0x10 Bytes register space
*/
-#define PITMCR 0x00
#define PIT0_OFFSET 0x100
#define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
+#define PITMCR(__base) (__base)
+
+#define PITMCR_FRZ BIT(0)
#define PITMCR_MDIS BIT(1)
#define PITLDVAL(__base) (__base)
@@ -52,6 +54,16 @@ static inline struct pit_timer *cs_to_pit(struct clocksource *cs)
return container_of(cs, struct pit_timer, cs);
}
+static inline void pit_module_enable(void __iomem *base)
+{
+ writel(0, PITMCR(base));
+}
+
+static inline void pit_module_disable(void __iomem *base)
+{
+ writel(PITMCR_MDIS, PITMCR(base));
+}
+
static inline void pit_timer_enable(struct pit_timer *pit)
{
writel(PITTCTRL_TEN | PITTCTRL_TIE, PITTCTRL(pit->clkevt_base));
@@ -253,11 +265,11 @@ static int __init pit_timer_init(struct device_node *np)
clk_rate = clk_get_rate(pit_clk);
/* enable the pit module */
- writel(~PITMCR_MDIS, timer_base + PITMCR);
+ pit_module_enable(timer_base);
ret = pit_clocksource_init(pit, name, timer_base, clk_rate);
if (ret)
- goto out_disable_unprepare;
+ goto out_pit_module_disable;
ret = pit_clockevent_init(pit, name, timer_base, clk_rate, irq, 0);
if (ret)
@@ -267,7 +279,8 @@ static int __init pit_timer_init(struct device_node *np)
out_pit_clocksource_unregister:
clocksource_unregister(&pit->cs);
-out_disable_unprepare:
+out_pit_module_disable:
+ pit_module_disable(timer_base);
clk_disable_unprepare(pit_clk);
out_clk_put:
clk_put(pit_clk);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 15/20] clocksource/drivers/vf-pit: Encapsulate set counter function
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (12 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 14/20] clocksource/drivers/vf-pit: Enable and disable module on error Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable Daniel Lezcano
` (5 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Encapsulate the writel() calls to set the counter into a
self-explainatory function.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index 043e36b2165d..cd104129e900 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -74,6 +74,11 @@ static inline void pit_timer_disable(struct pit_timer *pit)
writel(0, PITTCTRL(pit->clkevt_base));
}
+static inline void pit_timer_set_counter(void __iomem *base, unsigned int cnt)
+{
+ writel(cnt, PITLDVAL(base));
+}
+
static inline void pit_clocksource_enable(struct pit_timer *pit)
{
writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
@@ -118,7 +123,7 @@ static int __init pit_clocksource_init(struct pit_timer *pit, const char *name,
/* set the max load value and start the clock source counter */
pit_clocksource_disable(pit);
- writel(~0, PITLDVAL(pit->clksrc_base));
+ pit_timer_set_counter(pit->clksrc_base, ~0);
pit_clocksource_enable(pit);
sched_clock_base = pit->clksrc_base + PITCVAL_OFFSET;
@@ -139,7 +144,7 @@ static int pit_set_next_event(unsigned long delta, struct clock_event_device *ce
* hardware requirement.
*/
pit_timer_disable(pit);
- writel(delta - 1, PITLDVAL(pit->clkevt_base));
+ pit_timer_set_counter(pit->clkevt_base, delta - 1);
pit_timer_enable(pit);
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (13 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 15/20] clocksource/drivers/vf-pit: Encapsulate set counter function Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-07 10:28 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 17/20] clocksource/drivers/vf-pit: Unify the function name for irq ack Daniel Lezcano
` (4 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The difference between the pit_clocksource_enable() and
pit_clocksource_disable() is only setting the TIF flag for the
clockevent. Let's group them and pass the TIF flag parameter to the
function so we save some lines of code. But as the base address is
different regarding if it is a clocksource or a clockevent, we pass
the base address in parameter instead of the struct pit_timer.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 34 ++++++++++++------------------
1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index cd104129e900..f4b25d5a5685 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -64,14 +64,16 @@ static inline void pit_module_disable(void __iomem *base)
writel(PITMCR_MDIS, PITMCR(base));
}
-static inline void pit_timer_enable(struct pit_timer *pit)
+static inline void pit_timer_enable(void __iomem *base, bool tie)
{
- writel(PITTCTRL_TEN | PITTCTRL_TIE, PITTCTRL(pit->clkevt_base));
+ int val = PITTCTRL_TEN | (tie ? PITTCTRL_TIE : 0);
+
+ writel(val, PITTCTRL(base));
}
-static inline void pit_timer_disable(struct pit_timer *pit)
+static inline void pit_timer_disable(void __iomem *base)
{
- writel(0, PITTCTRL(pit->clkevt_base));
+ writel(0, PITTCTRL(base));
}
static inline void pit_timer_set_counter(void __iomem *base, unsigned int cnt)
@@ -79,16 +81,6 @@ static inline void pit_timer_set_counter(void __iomem *base, unsigned int cnt)
writel(cnt, PITLDVAL(base));
}
-static inline void pit_clocksource_enable(struct pit_timer *pit)
-{
- writel(PITTCTRL_TEN, PITTCTRL(pit->clksrc_base));
-}
-
-static inline void pit_clocksource_disable(struct pit_timer *pit)
-{
- pit_timer_disable(pit);
-}
-
static inline void pit_irq_acknowledge(struct pit_timer *pit)
{
writel(PITTFLG_TIF, PITTFLG(pit->clkevt_base));
@@ -122,9 +114,9 @@ static int __init pit_clocksource_init(struct pit_timer *pit, const char *name,
pit->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
/* set the max load value and start the clock source counter */
- pit_clocksource_disable(pit);
+ pit_timer_disable(pit->clksrc_base);
pit_timer_set_counter(pit->clksrc_base, ~0);
- pit_clocksource_enable(pit);
+ pit_timer_enable(pit->clksrc_base, 0);
sched_clock_base = pit->clksrc_base + PITCVAL_OFFSET;
sched_clock_register(pit_read_sched_clock, 32, rate);
@@ -143,9 +135,9 @@ static int pit_set_next_event(unsigned long delta, struct clock_event_device *ce
* and the PITLAVAL should be set to delta minus one according to pit
* hardware requirement.
*/
- pit_timer_disable(pit);
+ pit_timer_disable(pit->clkevt_base);
pit_timer_set_counter(pit->clkevt_base, delta - 1);
- pit_timer_enable(pit);
+ pit_timer_enable(pit->clkevt_base, true);
return 0;
}
@@ -154,7 +146,7 @@ static int pit_shutdown(struct clock_event_device *ced)
{
struct pit_timer *pit = ced_to_pit(ced);
- pit_timer_disable(pit);
+ pit_timer_disable(pit->clkevt_base);
return 0;
}
@@ -182,7 +174,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
* to stop the counter loop in ONESHOT mode.
*/
if (likely(clockevent_state_oneshot(ced)))
- pit_timer_disable(pit);
+ pit_timer_disable(pit->clkevt_base);
ced->event_handler(ced);
@@ -200,7 +192,7 @@ static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
pit->clkevt_base = base + PIT_CH(3);
pit->cycle_per_jiffy = rate / (HZ);
- pit_timer_disable(pit);
+ pit_timer_disable(pit->clkevt_base);
pit_irq_acknowledge(pit);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 17/20] clocksource/drivers/vf-pit: Unify the function name for irq ack
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (14 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 18/20] clocksource/drivers/pit: Rename the VF PIT to NXP PIT Daniel Lezcano
` (3 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
Most the function are under the form pit_timer_*, let's change the
interrupt acknowledgement function name to have the same format.
No functional changes intended.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-vf-pit.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
index f4b25d5a5685..ff9d721f5e31 100644
--- a/drivers/clocksource/timer-vf-pit.c
+++ b/drivers/clocksource/timer-vf-pit.c
@@ -81,7 +81,7 @@ static inline void pit_timer_set_counter(void __iomem *base, unsigned int cnt)
writel(cnt, PITLDVAL(base));
}
-static inline void pit_irq_acknowledge(struct pit_timer *pit)
+static inline void pit_timer_irqack(struct pit_timer *pit)
{
writel(PITTFLG_TIF, PITTFLG(pit->clkevt_base));
}
@@ -165,7 +165,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
struct clock_event_device *ced = dev_id;
struct pit_timer *pit = ced_to_pit(ced);
- pit_irq_acknowledge(pit);
+ pit_timer_irqack(pit);
/*
* pit hardware doesn't support oneshot, it will generate an interrupt
@@ -194,7 +194,7 @@ static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
pit_timer_disable(pit->clkevt_base);
- pit_irq_acknowledge(pit);
+ pit_timer_irqack(pit);
BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
name, &pit->ced));
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 18/20] clocksource/drivers/pit: Rename the VF PIT to NXP PIT
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (15 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 17/20] clocksource/drivers/vf-pit: Unify the function name for irq ack Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support Daniel Lezcano
` (2 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The PIT acronym stands for Periodic Interrupt Timer which is found on
different NXP platforms not only on the Vybrid Family. Change the name
to be more generic for the NXP platforms in general. That will be
consistent with the NXP STM driver naming convention.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/Kconfig | 9 ++++++---
drivers/clocksource/Makefile | 2 +-
drivers/clocksource/{timer-vf-pit.c => timer-nxp-pit.c} | 0
3 files changed, 7 insertions(+), 4 deletions(-)
rename drivers/clocksource/{timer-vf-pit.c => timer-nxp-pit.c} (100%)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6f7d371904df..0fd662f67d29 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -474,11 +474,14 @@ config FSL_FTM_TIMER
help
Support for Freescale FlexTimer Module (FTM) timer.
-config VF_PIT_TIMER
- bool "Vybrid Family Programmable timer" if COMPILE_TEST
+config NXP_PIT_TIMER
+ bool "NXP Periodic Interrupt Timer" if COMPILE_TEST
select CLKSRC_MMIO
help
- Support for Periodic Interrupt Timer on Freescale Vybrid Family SoCs.
+ Support for Periodic Interrupt Timer on Freescale / NXP
+ SoCs. This periodic timer is found on the Vybrid Family and
+ the Automotive S32G2/3 platforms. It contains 4 channels
+ where two can be coupled to form a 64 bits channel.
config SYS_SUPPORTS_SH_CMT
bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 205bf3b0a8f3..77a0f08eb43b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -49,7 +49,7 @@ obj-$(CONFIG_CLKSRC_LPC32XX) += timer-lpc32xx.o
obj-$(CONFIG_CLKSRC_MPS2) += mps2-timer.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_FSL_FTM_TIMER) += timer-fsl-ftm.o
-obj-$(CONFIG_VF_PIT_TIMER) += timer-vf-pit.o
+obj-$(CONFIG_NXP_PIT_TIMER) += timer-nxp-pit.o
obj-$(CONFIG_CLKSRC_QCOM) += timer-qcom.o
obj-$(CONFIG_MTK_TIMER) += timer-mediatek.o
obj-$(CONFIG_MTK_CPUX_TIMER) += timer-mediatek-cpux.o
diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-nxp-pit.c
similarity index 100%
rename from drivers/clocksource/timer-vf-pit.c
rename to drivers/clocksource/timer-nxp-pit.c
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (16 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 18/20] clocksource/drivers/pit: Rename the VF PIT to NXP PIT Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-06 22:13 ` kernel test robot
2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3 Daniel Lezcano
2025-07-07 9:11 ` [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Ghennadi Procopciuc
19 siblings, 2 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx; +Cc: ghennadi.procopciuc, S32, linux-kernel
The S32G platform has two Periodic Interrupt Timer (PIT). The IP is
exactly the same as the VF platform.
The setup found for this platform is each timer instance is bound to
CPU0 and CPU1.
The changes bring the support for multiple timer instances. When we
reach the maximum PIT instances for this platform, which is described
in the match table data, the hotplug callbacks are called where they
finish the per CPU setup.
Tested on a s32g274a-rdb2.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-nxp-pit.c | 113 +++++++++++++++++++++++-----
1 file changed, 96 insertions(+), 17 deletions(-)
diff --git a/drivers/clocksource/timer-nxp-pit.c b/drivers/clocksource/timer-nxp-pit.c
index ff9d721f5e31..3e4caa106ee8 100644
--- a/drivers/clocksource/timer-nxp-pit.c
+++ b/drivers/clocksource/timer-nxp-pit.c
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2012-2013 Freescale Semiconductor, Inc.
+ * Copyright 2018,2021-2025 NXP
*/
-
#include <linux/interrupt.h>
#include <linux/clockchips.h>
+#include <linux/cpuhotplug.h>
#include <linux/clk.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
+#include <linux/platform_device.h>
/*
* Each pit takes 0x10 Bytes register space
@@ -37,11 +39,23 @@
struct pit_timer {
void __iomem *clksrc_base;
void __iomem *clkevt_base;
- unsigned long cycle_per_jiffy;
struct clock_event_device ced;
struct clocksource cs;
+ int rate;
+};
+
+struct pit_timer_data {
+ int max_pit_instances;
};
+static DEFINE_PER_CPU(struct pit_timer *, pit_timers);
+
+/*
+ * Global structure for multiple PITs initialization
+ */
+static int pit_instances;
+static int max_pit_instances = 1;
+
static void __iomem *sched_clock_base;
static inline struct pit_timer *ced_to_pit(struct clock_event_device *ced)
@@ -98,8 +112,8 @@ static u64 pit_timer_clocksource_read(struct clocksource *cs)
return ~(u64)readl(PITCVAL(pit->clksrc_base));
}
-static int __init pit_clocksource_init(struct pit_timer *pit, const char *name,
- void __iomem *base, unsigned long rate)
+static int pit_clocksource_init(struct pit_timer *pit, const char *name,
+ void __iomem *base, unsigned long rate)
{
/*
* PIT0 and PIT1 can be chained to build a 64-bit timer, so
@@ -155,7 +169,7 @@ static int pit_set_periodic(struct clock_event_device *ced)
{
struct pit_timer *pit = ced_to_pit(ced);
- pit_set_next_event(pit->cycle_per_jiffy, ced);
+ pit_set_next_event(pit->rate / HZ, ced);
return 0;
}
@@ -181,23 +195,27 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
- void __iomem *base, unsigned long rate, int irq, int cpu)
+static int pit_clockevent_per_cpu_init(struct pit_timer *pit, const char *name,
+ void __iomem *base, unsigned long rate, int irq, int cpu)
{
+ int ret;
+
/*
* PIT0 and PIT1 can be chained to build a 64-bit timer, so
* choose PIT3 as clockevent and leave PIT0 and PIT1 unused
* for anyone else who needs them.
*/
pit->clkevt_base = base + PIT_CH(3);
- pit->cycle_per_jiffy = rate / (HZ);
+ pit->rate = rate;
pit_timer_disable(pit->clkevt_base);
pit_timer_irqack(pit);
- BUG_ON(request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
- name, &pit->ced));
+ ret = request_irq(irq, pit_timer_interrupt, IRQF_TIMER | IRQF_NOBALANCING,
+ name, &pit->ced);
+ if (ret)
+ return ret;
pit->ced.cpumask = cpumask_of(cpu);
pit->ced.irq = irq;
@@ -209,6 +227,23 @@ static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
pit->ced.set_next_event = pit_set_next_event;
pit->ced.rating = 300;
+ per_cpu(pit_timers, cpu) = pit;
+
+ return 0;
+}
+
+static int pit_clockevent_starting_cpu(unsigned int cpu)
+{
+ struct pit_timer *pit = per_cpu(pit_timers, cpu);
+ int ret;
+
+ if (!pit)
+ return 0;
+
+ ret = irq_force_affinity(pit->ced.irq, cpumask_of(cpu));
+ if (ret)
+ return ret;
+
/*
* The value for the LDVAL register trigger is calculated as:
* LDVAL trigger = (period / clock period) - 1
@@ -217,12 +252,12 @@ static int __init pit_clockevent_init(struct pit_timer *pit, const char *name,
* LDVAL trigger value is 1. And then the min_delta is
* minimal LDVAL trigger value + 1, and the max_delta is full 32-bit.
*/
- clockevents_config_and_register(&pit->ced, rate, 2, 0xffffffff);
+ clockevents_config_and_register(&pit->ced, pit->rate, 2, 0xffffffff);
return 0;
}
-static int __init pit_timer_init(struct device_node *np)
+static int pit_timer_init(struct device_node *np)
{
struct pit_timer *pit;
struct clk *pit_clk;
@@ -261,16 +296,31 @@ static int __init pit_timer_init(struct device_node *np)
clk_rate = clk_get_rate(pit_clk);
- /* enable the pit module */
- pit_module_enable(timer_base);
+ pit_module_disable(timer_base);
ret = pit_clocksource_init(pit, name, timer_base, clk_rate);
- if (ret)
+ if (ret) {
+ pr_err("Failed to initialize clocksource '%pOF'\n", np);
goto out_pit_module_disable;
+ }
- ret = pit_clockevent_init(pit, name, timer_base, clk_rate, irq, 0);
- if (ret)
+ ret = pit_clockevent_per_cpu_init(pit, name, timer_base, clk_rate, irq, pit_instances);
+ if (ret) {
+ pr_err("Failed to initialize clockevent '%pOF'\n", np);
goto out_pit_clocksource_unregister;
+ }
+
+ /* enable the pit module */
+ pit_module_enable(timer_base);
+
+ pit_instances++;
+
+ if (pit_instances == max_pit_instances) {
+ ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "PIT timer:starting",
+ pit_clockevent_starting_cpu, NULL);
+ if (ret < 0)
+ goto out_pit_clocksource_unregister;
+ }
return 0;
@@ -288,4 +338,33 @@ static int __init pit_timer_init(struct device_node *np)
return ret;
}
+
+static int pit_timer_probe(struct platform_device *pdev)
+{
+ const struct pit_timer_data *pit_timer_data;
+
+ pit_timer_data = of_device_get_match_data(&pdev->dev);
+ if (pit_timer_data)
+ max_pit_instances = pit_timer_data->max_pit_instances;
+
+ return pit_timer_init(pdev->dev.of_node);
+}
+
+static struct pit_timer_data s32g2_data = { .max_pit_instances = 2 };
+
+static const struct of_device_id pit_timer_of_match[] = {
+ { .compatible = "nxp,s32g2-pit", .data = &s32g2_data },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pit_timer_of_match);
+
+static struct platform_driver nxp_pit_driver = {
+ .driver = {
+ .name = "nxp-pit",
+ .of_match_table = pit_timer_of_match,
+ },
+ .probe = pit_timer_probe,
+};
+module_platform_driver(nxp_pit_driver);
+
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (17 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support Daniel Lezcano
@ 2025-07-05 16:01 ` Daniel Lezcano
2025-07-08 17:27 ` Rob Herring
2025-07-07 9:11 ` [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Ghennadi Procopciuc
19 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-05 16:01 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: ghennadi.procopciuc, S32, linux-kernel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
.../devicetree/bindings/timer/fsl,vf610-pit.yaml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml b/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
index bee2c35bd0e2..2aac63a58bfd 100644
--- a/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
+++ b/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
@@ -15,8 +15,12 @@ description:
properties:
compatible:
- enum:
- - fsl,vf610-pit
+ oneOf:
+ - const: fsl,vf610-pit
+ - const: nxp,s32g2-pit
+ - items:
+ - const: nxp,s32g3-pit
+ - const: nxp,s32g2-pit
reg:
maxItems: 1
--
2.43.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support
2025-07-05 16:01 ` [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support Daniel Lezcano
@ 2025-07-06 22:13 ` kernel test robot
2025-07-07 12:02 ` Ghennadi Procopciuc
1 sibling, 0 replies; 37+ messages in thread
From: kernel test robot @ 2025-07-06 22:13 UTC (permalink / raw)
To: Daniel Lezcano, tglx
Cc: llvm, oe-kbuild-all, ghennadi.procopciuc, S32, linux-kernel
Hi Daniel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on tip/timers/core]
[also build test WARNING on soc/for-next linus/master v6.16-rc4 next-20250704]
[cannot apply to daniel-lezcano/clockevents/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Lezcano/clocksource-drivers-vf_pit-Add-COMPILE_TEST-option/20250706-000719
base: tip/timers/core
patch link: https://lore.kernel.org/r/20250705160129.3688026-19-daniel.lezcano%40linaro.org
patch subject: [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20250707/202507070449.1xGzeBPS-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250707/202507070449.1xGzeBPS-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507070449.1xGzeBPS-lkp@intel.com/
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> WARNING: modpost: vmlinux: section mismatch in reference: pit_timer_init+0x2d4 (section: .text) -> sched_clock_register (section: .init.text)
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
` (18 preceding siblings ...)
2025-07-05 16:01 ` [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3 Daniel Lezcano
@ 2025-07-07 9:11 ` Ghennadi Procopciuc
19 siblings, 0 replies; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 9:11 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel, Arnd Bergmann
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> The driver uses the raw_readl() and raw_writel() functions. Those are
> not for MMIO devices. Replace them with readl() and writel()
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> ---
Please attach a cover letter.
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter
2025-07-05 16:01 ` [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter Daniel Lezcano
@ 2025-07-07 9:33 ` Ghennadi Procopciuc
2025-07-24 17:30 ` Daniel Lezcano
0 siblings, 1 reply; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 9:33 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> In order to initialize the timer with a cpumask tied to a cpu, let's
> pass it as a parameter instead of hardwiring it in the init function.
>
> No functional changes intended.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/clocksource/timer-vf-pit.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
> index 34edb23194c5..20f637c8e856 100644
> --- a/drivers/clocksource/timer-vf-pit.c
> +++ b/drivers/clocksource/timer-vf-pit.c
> @@ -147,7 +147,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
> }
>
> static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
> - unsigned long rate, int irq)
> + unsigned long rate, int irq, int cpu)
I noticed that cpumask_of() and get_cpu_mask() expect an 'unsigned int cpu' rather than an 'int cpu'. Would you consider updating the type of the cpu parameter accordingly?
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable
2025-07-05 16:01 ` [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable Daniel Lezcano
@ 2025-07-07 10:28 ` Ghennadi Procopciuc
0 siblings, 0 replies; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 10:28 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
[...]
> -static inline void pit_timer_enable(struct pit_timer *pit)
> +static inline void pit_timer_enable(void __iomem *base, bool tie)
> {
> - writel(PITTCTRL_TEN | PITTCTRL_TIE, PITTCTRL(pit->clkevt_base));
> + int val = PITTCTRL_TEN | (tie ? PITTCTRL_TIE : 0);
> +
> + writel(val, PITTCTRL(base));
> }
>
Would it make sense to use 'u32 val' instead of 'int val', given that writel() expects a 32-bit unsigned value?
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support
2025-07-05 16:01 ` [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support Daniel Lezcano
2025-07-06 22:13 ` kernel test robot
@ 2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-28 8:31 ` Daniel Lezcano
1 sibling, 1 reply; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 12:02 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> The S32G platform has two Periodic Interrupt Timer (PIT). The IP is
> exactly the same as the VF platform.
>
> The setup found for this platform is each timer instance is bound to
> CPU0 and CPU1.
>
> The changes bring the support for multiple timer instances. When we
> reach the maximum PIT instances for this platform, which is described
> in the match table data, the hotplug callbacks are called where they
> finish the per CPU setup.
>
> Tested on a s32g274a-rdb2.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
The current description does not clearly explain how the resources are used within the driver. It would be helpful to mention that channel 2 is used as the clocksource, while channel 3 is designated for clockevents.
Additionally, the S32G2 platform supports suspend and resume functionality. However, this capability is not yet implemented in the driver. Do you plan to include support for it in a future patch?
[...]
> -static int __init pit_timer_init(struct device_node *np)
> +static int pit_timer_init(struct device_node *np)
> {
> struct pit_timer *pit;
> struct clk *pit_clk;
> @@ -261,16 +296,31 @@ static int __init pit_timer_init(struct device_node *np)
>
> clk_rate = clk_get_rate(pit_clk);
>
> - /* enable the pit module */
> - pit_module_enable(timer_base);
> + pit_module_disable(timer_base);
>
> ret = pit_clocksource_init(pit, name, timer_base, clk_rate);
> - if (ret)
> + if (ret) {
> + pr_err("Failed to initialize clocksource '%pOF'\n", np);
> goto out_pit_module_disable;
> + }
>
> - ret = pit_clockevent_init(pit, name, timer_base, clk_rate, irq, 0);
> - if (ret)
> + ret = pit_clockevent_per_cpu_init(pit, name, timer_base, clk_rate, irq, pit_instances);
> + if (ret) {
> + pr_err("Failed to initialize clockevent '%pOF'\n", np);
> goto out_pit_clocksource_unregister;
> + }
This mechanism is very restrictive and will allow to assign the PIT0 and PIT1 to CPU0 and CPU1 only. Have you considered alternatives where the mapping is given as mask through early_param?
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver
2025-07-05 16:01 ` [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver Daniel Lezcano
@ 2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-26 19:37 ` Daniel Lezcano
0 siblings, 1 reply; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 12:02 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
[...]
> +static u64 pit_timer_clocksource_read(struct clocksource *cs)
> +{
> + struct pit_timer *pit = cs_to_pit(cs);
> +
> + return ~(u64)readl(pit->clksrc_base + PITCVAL);
> +}
The CVAL register is a 32-bit countdown timer. Casting its value to 64 bits before applying bitwise negation results in a 64-bit value where the upper 32 bits are always set. To avoid this, shouldn't the operations be reordered so that the bitwise negation is applied first to the 32-bit value, followed by casting the result to 64 bits?
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros
2025-07-05 16:01 ` [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros Daniel Lezcano
@ 2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-28 8:35 ` Daniel Lezcano
0 siblings, 1 reply; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 12:03 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> Pass the base address to the macro, so we can use the macro with
> multiple instances of the timer because we deal with different base
> address. At the same time, change writes to the register to the
> existing corresponding functions.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/clocksource/timer-vf-pit.c | 35 ++++++++++++++++--------------
> 1 file changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
> index 066d0d2600f4..9c5e06506c26 100644
> --- a/drivers/clocksource/timer-vf-pit.c
> +++ b/drivers/clocksource/timer-vf-pit.c
> @@ -16,18 +16,21 @@
> #define PITMCR 0x00
> #define PIT0_OFFSET 0x100
> #define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
> -#define PITLDVAL 0x00
> +
> #define PITCVAL 0x04
> -#define PITTCTRL 0x08
> -#define PITTFLG 0x0c
The registers PITLDVAL, PITCVAL, PITTCTRL, and PITTFLG refer to individual PIT channels rather than global PIT registers. Shouldn't this distinction be reflected in their naming? I would suggest prefixing them with PIT_CH_ to improve clarity and indicate their per-channel scope.
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage
2025-07-05 16:01 ` [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage Daniel Lezcano
@ 2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-24 17:29 ` Daniel Lezcano
0 siblings, 1 reply; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 12:03 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
[...]
> -static int __init pit_clockevent_init(struct pit_timer *pit, unsigned long rate, int irq)
> +static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
> + unsigned long rate, int irq)
> {
> + /*
> + * PIT0 and PIT1 can be chained to build a 64-bit timer, so
> + * choose PIT3 as clockevent and leave PIT0 and PIT1 unused
> + * for anyone else who needs them.
> + */
> + pit->clkevt_base = base + PIT_CH(3);
> +
This description is somewhat misleading, as it refers to PIT instances, whereas the code actually operates on PIT channels 0 and 1.
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers
2025-07-05 16:01 ` [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers Daniel Lezcano
@ 2025-07-07 12:04 ` Ghennadi Procopciuc
0 siblings, 0 replies; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-07 12:04 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> The driver is implemented as using a single timer and a single
> clocksource. In order to take advantage of the multiple timers
> supported in the PIT hardware and introduce different setup for a new
> platform, let's encapsulate the data into a structure and pass this
> structure around in the function parameter. The structure will be a
> per timer instanciation in the next changes.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/clocksource/timer-vf-pit.c | 119 +++++++++++++++++------------
> 1 file changed, 70 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
> index 8041a8f62d1f..581b46e7b111 100644
> --- a/drivers/clocksource/timer-vf-pit.c
> +++ b/drivers/clocksource/timer-vf-pit.c
> @@ -15,7 +15,7 @@
> */
> #define PITMCR 0x00
> #define PIT0_OFFSET 0x100
> -#define PITn_OFFSET(n) (PIT0_OFFSET + 0x10 * (n))
> +#define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
> #define PITLDVAL 0x00
> #define PITCVAL 0x04
> #define PITTCTRL 0x08
While not directly part of this change, the description above this patch states: 'Each PIT takes 0x10 bytes of register space.' In my view, this is somewhat misleading, as the reference manual refers to them as channels rather than separate PIT instances.
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3
2025-07-05 16:01 ` [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3 Daniel Lezcano
@ 2025-07-08 17:27 ` Rob Herring
0 siblings, 0 replies; 37+ messages in thread
From: Rob Herring @ 2025-07-08 17:27 UTC (permalink / raw)
To: Daniel Lezcano
Cc: tglx, ghennadi.procopciuc, S32, linux-kernel, Krzysztof Kozlowski,
Conor Dooley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
On Sat, Jul 05, 2025 at 06:01:26PM +0200, Daniel Lezcano wrote:
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Missing commit message. Why are we adding these? They are in use, but
undocumented?
> ---
> .../devicetree/bindings/timer/fsl,vf610-pit.yaml | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml b/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
> index bee2c35bd0e2..2aac63a58bfd 100644
> --- a/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
> +++ b/Documentation/devicetree/bindings/timer/fsl,vf610-pit.yaml
> @@ -15,8 +15,12 @@ description:
>
> properties:
> compatible:
> - enum:
> - - fsl,vf610-pit
> + oneOf:
> + - const: fsl,vf610-pit
> + - const: nxp,s32g2-pit
> + - items:
> + - const: nxp,s32g3-pit
> + - const: nxp,s32g2-pit
>
> reg:
> maxItems: 1
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage
2025-07-07 12:03 ` Ghennadi Procopciuc
@ 2025-07-24 17:29 ` Daniel Lezcano
2025-07-25 5:10 ` Ghennadi Procopciuc
0 siblings, 1 reply; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-24 17:29 UTC (permalink / raw)
To: Ghennadi Procopciuc, tglx; +Cc: S32, linux-kernel
On 07/07/2025 14:03, Ghennadi Procopciuc wrote:
> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> [...]
>
>> -static int __init pit_clockevent_init(struct pit_timer *pit, unsigned long rate, int irq)
>> +static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
>> + unsigned long rate, int irq)
>> {
>> + /*
>> + * PIT0 and PIT1 can be chained to build a 64-bit timer, so
>> + * choose PIT3 as clockevent and leave PIT0 and PIT1 unused
>> + * for anyone else who needs them.
>> + */
>> + pit->clkevt_base = base + PIT_CH(3);
>> +
>
> This description is somewhat misleading, as it refers to PIT instances, whereas the code actually operates on PIT channels 0 and 1.
>
Actually it is what we have already in the driver, it is just moved
around. I'll take the opportunity to change the content if it matters.
What about:
"The channels 0 and 1 can be chained to build a 64-bit timer. Let's use
the channel 3 as a clockevent and leave the channels 0 and 1 unused for
anyone else who needs them."
?
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter
2025-07-07 9:33 ` Ghennadi Procopciuc
@ 2025-07-24 17:30 ` Daniel Lezcano
0 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-24 17:30 UTC (permalink / raw)
To: Ghennadi Procopciuc, tglx; +Cc: S32, linux-kernel
On 07/07/2025 11:33, Ghennadi Procopciuc wrote:
> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
>> In order to initialize the timer with a cpumask tied to a cpu, let's
>> pass it as a parameter instead of hardwiring it in the init function.
>>
>> No functional changes intended.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>> ---
>> drivers/clocksource/timer-vf-pit.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
>> index 34edb23194c5..20f637c8e856 100644
>> --- a/drivers/clocksource/timer-vf-pit.c
>> +++ b/drivers/clocksource/timer-vf-pit.c
>> @@ -147,7 +147,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
>> }
>>
>> static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
>> - unsigned long rate, int irq)
>> + unsigned long rate, int irq, int cpu)
>
> I noticed that cpumask_of() and get_cpu_mask() expect an 'unsigned int cpu' rather than an 'int cpu'. Would you consider updating the type of the cpu parameter accordingly?
Yes, sure
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage
2025-07-24 17:29 ` Daniel Lezcano
@ 2025-07-25 5:10 ` Ghennadi Procopciuc
0 siblings, 0 replies; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-25 5:10 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/24/2025 8:29 PM, Daniel Lezcano wrote:
> On 07/07/2025 14:03, Ghennadi Procopciuc wrote:
>> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
>> [...]
>>
>>> -static int __init pit_clockevent_init(struct pit_timer *pit, unsigned long rate, int irq)
>>> +static int __init pit_clockevent_init(struct pit_timer *pit, void __iomem *base,
>>> + unsigned long rate, int irq)
>>> {
>>> + /*
>>> + * PIT0 and PIT1 can be chained to build a 64-bit timer, so
>>> + * choose PIT3 as clockevent and leave PIT0 and PIT1 unused
>>> + * for anyone else who needs them.
>>> + */
>>> + pit->clkevt_base = base + PIT_CH(3);
>>> +
>>
>> This description is somewhat misleading, as it refers to PIT instances, whereas the code actually operates on PIT channels 0 and 1.
>>
> Actually it is what we have already in the driver, it is just moved around. I'll take the opportunity to change the content if it matters. What about:
>
> "The channels 0 and 1 can be chained to build a 64-bit timer. Let's use the channel 3 as a clockevent and leave the channels 0 and 1 unused for anyone else who needs them."
>
> ?
Sounds more accurate. Thx.
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names
2025-07-05 16:01 ` [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names Daniel Lezcano
@ 2025-07-25 5:12 ` Ghennadi Procopciuc
0 siblings, 0 replies; 37+ messages in thread
From: Ghennadi Procopciuc @ 2025-07-25 5:12 UTC (permalink / raw)
To: Daniel Lezcano, tglx; +Cc: S32, linux-kernel
On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> In ordero to differentiate from userspace the pit timer given the
> device tree, let's use the node name for the interrupt and the timer
> names.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
Typo in 'In ordero'
--
Regards,
Ghennadi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver
2025-07-07 12:02 ` Ghennadi Procopciuc
@ 2025-07-26 19:37 ` Daniel Lezcano
0 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-26 19:37 UTC (permalink / raw)
To: Ghennadi Procopciuc, tglx; +Cc: S32, linux-kernel
On 07/07/2025 14:02, Ghennadi Procopciuc wrote:
> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
> [...]
>
>> +static u64 pit_timer_clocksource_read(struct clocksource *cs)
>> +{
>> + struct pit_timer *pit = cs_to_pit(cs);
>> +
>> + return ~(u64)readl(pit->clksrc_base + PITCVAL);
>> +}
>
> The CVAL register is a 32-bit countdown timer. Casting its value to 64 bits before applying bitwise negation results in a 64-bit value where the upper 32 bits are always set. To avoid this, shouldn't the operations be reordered so that the bitwise negation is applied first to the 32-bit value, followed by casting the result to 64 bits?
>
Yes, that's right
Good catch !
Thanks
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support
2025-07-07 12:02 ` Ghennadi Procopciuc
@ 2025-07-28 8:31 ` Daniel Lezcano
0 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-28 8:31 UTC (permalink / raw)
To: Ghennadi Procopciuc, tglx; +Cc: S32, linux-kernel
On 07/07/2025 14:02, Ghennadi Procopciuc wrote:
> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
>> The S32G platform has two Periodic Interrupt Timer (PIT). The IP is
>> exactly the same as the VF platform.
>>
>> The setup found for this platform is each timer instance is bound to
>> CPU0 and CPU1.
>>
>> The changes bring the support for multiple timer instances. When we
>> reach the maximum PIT instances for this platform, which is described
>> in the match table data, the hotplug callbacks are called where they
>> finish the per CPU setup.
>>
>> Tested on a s32g274a-rdb2.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>> ---
>
> The current description does not clearly explain how the resources are used within the driver. It would be helpful to mention that channel 2 is used as the clocksource, while channel 3 is designated for clockevents.
The changes are to allow to support multiple instances of the PIT timer.
The way the channels are used is unchanged. I can put a sentence to
remind how they are used.
> Additionally, the S32G2 platform supports suspend and resume functionality. However, this capability is not yet implemented in the driver. Do you plan to include support for it in a future patch?
Yes, usually PM is added after.
> [...]
>
>> -static int __init pit_timer_init(struct device_node *np)
>> +static int pit_timer_init(struct device_node *np)
>> {
>> struct pit_timer *pit;
>> struct clk *pit_clk;
>> @@ -261,16 +296,31 @@ static int __init pit_timer_init(struct device_node *np)
>>
>> clk_rate = clk_get_rate(pit_clk);
>>
>> - /* enable the pit module */
>> - pit_module_enable(timer_base);
>> + pit_module_disable(timer_base);
>>
>> ret = pit_clocksource_init(pit, name, timer_base, clk_rate);
>> - if (ret)
>> + if (ret) {
>> + pr_err("Failed to initialize clocksource '%pOF'\n", np);
>> goto out_pit_module_disable;
>> + }
>>
>> - ret = pit_clockevent_init(pit, name, timer_base, clk_rate, irq, 0);
>> - if (ret)
>> + ret = pit_clockevent_per_cpu_init(pit, name, timer_base, clk_rate, irq, pit_instances);
>> + if (ret) {
>> + pr_err("Failed to initialize clockevent '%pOF'\n", np);
>> goto out_pit_clocksource_unregister;
>> + }
>
> This mechanism is very restrictive and will allow to assign the PIT0 and PIT1 to CPU0 and CPU1 only. Have you considered alternatives where the mapping is given as mask through early_param?
Yes, we can consider putting in place a mechanism to configure how the
PIT are mapped to a CPU but that would be a separate feature to be added
later.
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros
2025-07-07 12:03 ` Ghennadi Procopciuc
@ 2025-07-28 8:35 ` Daniel Lezcano
0 siblings, 0 replies; 37+ messages in thread
From: Daniel Lezcano @ 2025-07-28 8:35 UTC (permalink / raw)
To: Ghennadi Procopciuc, tglx; +Cc: S32, linux-kernel
On 07/07/2025 14:03, Ghennadi Procopciuc wrote:
> On 7/5/2025 7:01 PM, Daniel Lezcano wrote:
>> Pass the base address to the macro, so we can use the macro with
>> multiple instances of the timer because we deal with different base
>> address. At the same time, change writes to the register to the
>> existing corresponding functions.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>> ---
>> drivers/clocksource/timer-vf-pit.c | 35 ++++++++++++++++--------------
>> 1 file changed, 19 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c
>> index 066d0d2600f4..9c5e06506c26 100644
>> --- a/drivers/clocksource/timer-vf-pit.c
>> +++ b/drivers/clocksource/timer-vf-pit.c
>> @@ -16,18 +16,21 @@
>> #define PITMCR 0x00
>> #define PIT0_OFFSET 0x100
>> #define PIT_CH(n) (PIT0_OFFSET + 0x10 * (n))
>> -#define PITLDVAL 0x00
>> +
>> #define PITCVAL 0x04
>> -#define PITTCTRL 0x08
>> -#define PITTFLG 0x0c
>
> The registers PITLDVAL, PITCVAL, PITTCTRL, and PITTFLG refer to individual PIT channels rather than global PIT registers. Shouldn't this distinction be reflected in their naming? I would suggest prefixing them with PIT_CH_ to improve clarity and indicate their per-channel scope.
Reasonably, I would like to keep them as is otherwise it would be out of
the scope of these changes which are aiming to set the scene for
multiple PITs support. If the naming convention has to be changed, that
could be addressed later in a separate series.
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2025-07-28 8:35 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-05 16:01 [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Daniel Lezcano
2025-07-05 16:01 ` [PATCH 02/20] clocksource/drivers/vf_pit: Add COMPILE_TEST option Daniel Lezcano
2025-07-05 16:01 ` [PATCH 03/20] clocksource/drivers/vf_pit: Set the scene for multiple timers Daniel Lezcano
2025-07-07 12:04 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 04/20] clocksource/drivers/vf_pit: Rework the base address usage Daniel Lezcano
2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-24 17:29 ` Daniel Lezcano
2025-07-25 5:10 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 05/20] clocksource/drivers/vf_pit: Pass the cpu number as parameter Daniel Lezcano
2025-07-07 9:33 ` Ghennadi Procopciuc
2025-07-24 17:30 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 06/20] clocksource/drivers/vf_pit: Encapsulate the initialization of the cycles_per_jiffy Daniel Lezcano
2025-07-05 16:01 ` [PATCH 07/20] clocksource/drivers/vf-pit: Allocate the struct timer at init time Daniel Lezcano
2025-07-05 16:01 ` [PATCH 08/20] clocksource/drivers/vf-pit: Convert raw values to BIT macros Daniel Lezcano
2025-07-05 16:01 ` [PATCH 09/20] clocksource/drivers/vf-pit: Register the clocksource from the driver Daniel Lezcano
2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-26 19:37 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 10/20] clocksource/drivers/vf-pit: Encapsulate the macros Daniel Lezcano
2025-07-07 12:03 ` Ghennadi Procopciuc
2025-07-28 8:35 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 11/20] clocksource/drivers/vf-pit: Encapsulate the PTLCVAL macro Daniel Lezcano
2025-07-05 16:01 ` [PATCH 12/20] clocksource/drivers/vf-pit: Use the node name for the interrupt and timer names Daniel Lezcano
2025-07-25 5:12 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 13/20] clocksource/drivers/vf-pit: Encapsulate clocksource enable / disable Daniel Lezcano
2025-07-05 16:01 ` [PATCH 14/20] clocksource/drivers/vf-pit: Enable and disable module on error Daniel Lezcano
2025-07-05 16:01 ` [PATCH 15/20] clocksource/drivers/vf-pit: Encapsulate set counter function Daniel Lezcano
2025-07-05 16:01 ` [PATCH 16/20] clocksource/drivers/vf-pit: Consolidate calls to pit_*_disable/enable Daniel Lezcano
2025-07-07 10:28 ` Ghennadi Procopciuc
2025-07-05 16:01 ` [PATCH 17/20] clocksource/drivers/vf-pit: Unify the function name for irq ack Daniel Lezcano
2025-07-05 16:01 ` [PATCH 18/20] clocksource/drivers/pit: Rename the VF PIT to NXP PIT Daniel Lezcano
2025-07-05 16:01 ` [PATCH 19/20] clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support Daniel Lezcano
2025-07-06 22:13 ` kernel test robot
2025-07-07 12:02 ` Ghennadi Procopciuc
2025-07-28 8:31 ` Daniel Lezcano
2025-07-05 16:01 ` [PATCH 20/20] dt: bindings: fsl,vf610-pit: Add compatible for s32g2 and s32g3 Daniel Lezcano
2025-07-08 17:27 ` Rob Herring
2025-07-07 9:11 ` [PATCH 01/20] clocksource/drivers/vf-pit: Replace raw_readl/writel to reald/writel Ghennadi Procopciuc
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).