linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver
@ 2025-10-23 20:50 Will McVicker
  0 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:50 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Peter Griffin,
	Ingo Molnar, Youngmin Nam, Will McVicker, Hosung Kim
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

This series adds support to build the Arm64 Exynos MCT driver as a module.
This is only possible on Arm64 SoCs since they can use the Arm architected
timer as the clocksource. Once the Exynos MCT module is loaded and the
device probes, the MCT is used as the wakeup source for the arch_timer to
ensure the device can wakeup from the "c2" idle state.

These patches are originally from the downstream Pixel 6 (gs101) kernel
found at [1] and have been adapted for upstream. Not only has the Exynos MCT
driver been shipping as a module in the field with Android, but I've also
tested this series with the upstream kernel on my Pixel 6 Pro.

To verify the module on Pixel 6 Pro is used and the arch_timer is used as the
main clocksource, I ran these tests:
---
# lsmod | grep exynos_mct
exynos_mct             20480  9 [permanent]

# cat /proc/interrupts | grep -E "mct|arch_timer"
 23:        759       1009        741        477        601        405       1350        789    GICv3  30 Level     arch_timer
117:          1          0          0          0          0          0          0          0    GICv3 785 Level     mct_comp_irq
118:       2126          0          0          0          0          0          0          0    GICv3 789 Level     mct_tick0
119:          0       1442          0          0          0          0          0          0    GICv3 790 Level     mct_tick1
120:          0          0       4617          0          0          0          0          0    GICv3 791 Level     mct_tick2
121:          0          0          0       2617          0          0          0          0    GICv3 792 Level     mct_tick3
122:          0          0          0          0       4173          0          0          0    GICv3 793 Level     mct_tick4
123:          0          0          0          0          0       2217          0          0    GICv3 794 Level     mct_tick5
124:          0          0          0          0          0          0       1618          0    GICv3 795 Level     mct_tick6
125:          0          0          0          0          0          0          0        894    GICv3 796 Level     mct_tick7

# cat /sys/devices/system/clocksource/clocksource0/current_clocksource
arch_sys_counter
---

I also compile tested for ARCH=ARM DEFCONFIG=multi_v7_defconfig with the
following debug configs to ensure the section mismatches are fixed:
  CONFIG_DEBUG_SECTION_MISMATCH=y
  # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set

Any additional testing is much appreciated!

Thanks,
Will

Note1, instructions to build and flash a Pixel 6 device with the upstream
kernel can be found at [2].

Note2, this series is based off of krzk/for-next commit 73f7017e6636 ("Merge
branch 'fixes' into for-next").

[1] https://android.googlesource.com/kernel/gs/+log/refs/heads/android-gs-raviole-5.10-android12-d1
[2] https://git.codelinaro.org/linaro/googlelt/pixelscripts/-/blob/clo/main/README.md?ref_type=heads

Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Donghoon Yu <hoony.yu@samsung.com>
Cc: Hosung Kim <hosung0.kim@samsung.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Saravana Kannan <saravanak@google.com>
Cc: John Stultz <jstultz@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Youngmin Nam <youngmin.nam@samsung.com>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: André Draszik <andre.draszik@linaro.org>
Cc: Will Deacon <will@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: linux-samsung-soc@vger.kernel.org
Cc: kernel-team@android.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org

---
Changes in v5:
- Fixed section mismatch issues.
- Addressed Arnd's concerns regarding potential issues with unloading and/or
  unbinding the driver.
- Fixed SoB concerns to clarify the development chain from AOSP to Linux.
- Pulled in https://lore.kernel.org/all/20250827102645.1964659-1-m.szyprowski@samsung.com/
  to limit percpu interrupts only for ARM64.

Changes in v4:
- Missed the "v3" string in the previous series for the actual patches
- Re-generated patches with --base a15edf91668beefdb5171c53fa698c9b43dd1e0d
  for kernel test robot.

Changes in v3:
- Rebased on top of Daniel's timer modularization prep series [3] and
  krzk/for-next commit a15edf91668b ("Merge branch 'next/dt64' into
  for-next")
- Added owner references to Exynos MCT clocksource and clockevent objects.
- Dropped #ifdef MODULE conditional section in favor of just using
  module_platform_driver() which will properly handle setting up the
  of_device_id table based on if the driver is built-in or a module.
- Update commit message for patch 2 based on John's feedback.
- Dropped DT change from v2 as it was picked up by Krzysztof for CPU Idle.

Changes in v2:
- Re-worked patch v1 5 based on Rob Herring's review to use the compatible
  data for retrieving the mct_init function pointer.
- Updated the Kconfig logic to disallow building the Exynos MCT driver as
  a module for ARM32 configurations based on Krzysztof Kozlowski's findings.
- Added comments and clarified commit messages in patches 1 and 2 based on
  reviews from John Stultz and Youngmin Nam.
- Fixed an issue found during testing that resulted in the device getting
  stuck on boot. This is included in v2 as patch 5.
- Collected *-by tags
- Rebased to the latest linux-next/master.
---

Donghoon Yu (2):
  clocksource/drivers/exynos_mct: Don't register as a sched_clock on
    arm64
  clocksource/drivers/exynos_mct: Add module support

Hosung Kim (1):
  clocksource/drivers/exynos_mct: Set local timer interrupts as percpu

Marek Szyprowski (1):
  clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64

Will McVicker (3):
  ARM: make register_current_timer_delay() accessible after init
  clocksource/drivers/exynos_mct: Fix uninitialized irq name warning
  arm64: exynos: Drop select CLKSRC_EXYNOS_MCT

 arch/arm/lib/delay.c             |  2 +-
 arch/arm64/Kconfig.platforms     |  1 -
 drivers/clocksource/Kconfig      |  3 +-
 drivers/clocksource/exynos_mct.c | 81 ++++++++++++++++++++++++++------
 4 files changed, 70 insertions(+), 17 deletions(-)


base-commit: 73f7017e663620a616171cc80d62504a624dc4de
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver
@ 2025-10-23 20:52 Will McVicker
  2025-10-23 20:52 ` [PATCH v5 1/7] ARM: make register_current_timer_delay() accessible after init Will McVicker
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

This series adds support to build the Arm64 Exynos MCT driver as a module.
This is only possible on Arm64 SoCs since they can use the Arm architected
timer as the clocksource. Once the Exynos MCT module is loaded and the
device probes, the MCT is used as the wakeup source for the arch_timer to
ensure the device can wakeup from the "c2" idle state.

These patches are originally from the downstream Pixel 6 (gs101) kernel
found at [1] and have been adapted for upstream. Not only has the Exynos MCT
driver been shipping as a module in the field with Android, but I've also
tested this series with the upstream kernel on my Pixel 6 Pro.

To verify the module on Pixel 6 Pro is used and the arch_timer is used as the
main clocksource, I ran these tests:
---
# lsmod | grep exynos_mct
exynos_mct             20480  9 [permanent]

# cat /proc/interrupts | grep -E "mct|arch_timer"
 23:        759       1009        741        477        601        405       1350        789    GICv3  30 Level     arch_timer
117:          1          0          0          0          0          0          0          0    GICv3 785 Level     mct_comp_irq
118:       2126          0          0          0          0          0          0          0    GICv3 789 Level     mct_tick0
119:          0       1442          0          0          0          0          0          0    GICv3 790 Level     mct_tick1
120:          0          0       4617          0          0          0          0          0    GICv3 791 Level     mct_tick2
121:          0          0          0       2617          0          0          0          0    GICv3 792 Level     mct_tick3
122:          0          0          0          0       4173          0          0          0    GICv3 793 Level     mct_tick4
123:          0          0          0          0          0       2217          0          0    GICv3 794 Level     mct_tick5
124:          0          0          0          0          0          0       1618          0    GICv3 795 Level     mct_tick6
125:          0          0          0          0          0          0          0        894    GICv3 796 Level     mct_tick7

# cat /sys/devices/system/clocksource/clocksource0/current_clocksource
arch_sys_counter
---

I also compile tested for ARCH=ARM DEFCONFIG=multi_v7_defconfig with the
following debug configs to ensure the section mismatches are fixed:
  CONFIG_DEBUG_SECTION_MISMATCH=y
  # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set

Any additional testing is much appreciated!

Thanks,
Will

Note1, instructions to build and flash a Pixel 6 device with the upstream
kernel can be found at [2].

Note2, this series is based off of krzk/for-next commit 73f7017e6636 ("Merge
branch 'fixes' into for-next").

[1] https://android.googlesource.com/kernel/gs/+log/refs/heads/android-gs-raviole-5.10-android12-d1
[2] https://git.codelinaro.org/linaro/googlelt/pixelscripts/-/blob/clo/main/README.md?ref_type=heads

Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Donghoon Yu <hoony.yu@samsung.com>
Cc: Hosung Kim <hosung0.kim@samsung.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Saravana Kannan <saravanak@google.com>
Cc: John Stultz <jstultz@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Youngmin Nam <youngmin.nam@samsung.com>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: André Draszik <andre.draszik@linaro.org>
Cc: Will Deacon <will@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: linux-samsung-soc@vger.kernel.org
Cc: kernel-team@android.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org

---
Changes in v5:
- Fixed section mismatch issues.
- Addressed Arnd's concerns regarding potential issues with unloading and/or
  unbinding the driver.
- Fixed SoB concerns to clarify the development chain from AOSP to Linux.
- Pulled in https://lore.kernel.org/all/20250827102645.1964659-1-m.szyprowski@samsung.com/
  to limit percpu interrupts only for ARM64.

Changes in v4:
- Missed the "v3" string in the previous series for the actual patches
- Re-generated patches with --base a15edf91668beefdb5171c53fa698c9b43dd1e0d
  for kernel test robot.

Changes in v3:
- Rebased on top of Daniel's timer modularization prep series [3] and
  krzk/for-next commit a15edf91668b ("Merge branch 'next/dt64' into
  for-next")
- Added owner references to Exynos MCT clocksource and clockevent objects.
- Dropped #ifdef MODULE conditional section in favor of just using
  module_platform_driver() which will properly handle setting up the
  of_device_id table based on if the driver is built-in or a module.
- Update commit message for patch 2 based on John's feedback.
- Dropped DT change from v2 as it was picked up by Krzysztof for CPU Idle.

Changes in v2:
- Re-worked patch v1 5 based on Rob Herring's review to use the compatible
  data for retrieving the mct_init function pointer.
- Updated the Kconfig logic to disallow building the Exynos MCT driver as
  a module for ARM32 configurations based on Krzysztof Kozlowski's findings.
- Added comments and clarified commit messages in patches 1 and 2 based on
  reviews from John Stultz and Youngmin Nam.
- Fixed an issue found during testing that resulted in the device getting
  stuck on boot. This is included in v2 as patch 5.
- Collected *-by tags
- Rebased to the latest linux-next/master.
---

Donghoon Yu (2):
  clocksource/drivers/exynos_mct: Don't register as a sched_clock on
    arm64
  clocksource/drivers/exynos_mct: Add module support

Hosung Kim (1):
  clocksource/drivers/exynos_mct: Set local timer interrupts as percpu

Marek Szyprowski (1):
  clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64

Will McVicker (3):
  ARM: make register_current_timer_delay() accessible after init
  clocksource/drivers/exynos_mct: Fix uninitialized irq name warning
  arm64: exynos: Drop select CLKSRC_EXYNOS_MCT

 arch/arm/lib/delay.c             |  2 +-
 arch/arm64/Kconfig.platforms     |  1 -
 drivers/clocksource/Kconfig      |  3 +-
 drivers/clocksource/exynos_mct.c | 81 ++++++++++++++++++++++++++------
 4 files changed, 70 insertions(+), 17 deletions(-)


base-commit: 73f7017e663620a616171cc80d62504a624dc4de
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 1/7] ARM: make register_current_timer_delay() accessible after init
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-23 20:52 ` [PATCH v5 2/7] clocksource/drivers/exynos_mct: Don't register as a sched_clock on arm64 Will McVicker
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

The function register_current_timer_delay() is called from the
exynos_mct clocksource driver at probe time. In the event that the
exynos_mct driver is probed deferred or the platform manually unbinds
and rebinds the driver we need this function available. So drop the
__init tag.

Signed-off-by: Will McVicker <willmcvicker@google.com>
---
 arch/arm/lib/delay.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index b7fe84f68bf1..acfb87143f21 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -62,7 +62,7 @@ static void __timer_udelay(unsigned long usecs)
 	__timer_const_udelay(usecs * UDELAY_MULT);
 }
 
-void __init register_current_timer_delay(const struct delay_timer *timer)
+void register_current_timer_delay(const struct delay_timer *timer)
 {
 	u32 new_mult, new_shift;
 	u64 res;
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 2/7] clocksource/drivers/exynos_mct: Don't register as a sched_clock on arm64
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
  2025-10-23 20:52 ` [PATCH v5 1/7] ARM: make register_current_timer_delay() accessible after init Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-23 20:52 ` [PATCH v5 3/7] clocksource/drivers/exynos_mct: Set local timer interrupts as percpu Will McVicker
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

From: Donghoon Yu <hoony.yu@samsung.com>

The MCT register is unfortunately very slow to access, but importantly
does not halt in the c2 idle state. So for ARM64, we can improve
performance by not registering the MCT for sched_clock, allowing the
system to use the faster ARM architected timer for sched_clock instead.

The MCT is still registered as a clocksource, and a clockevent in order
to be a wakeup source for the arch_timer to exit the "c2" idle state.

Since ARM32 SoCs don't have an architected timer, the MCT must continue
to be used for sched_clock. Detailed discussion on this topic can be
found at [1].

[1] https://lore.kernel.org/linux-samsung-soc/1400188079-21832-1-git-send-email-chirantan@chromium.org/

[Original commit from https://android.googlesource.com/kernel/gs/+/630817f7080e92c5e0216095ff52f6eb8dd00727

Signed-off-by: Donghoon Yu <hoony.yu@samsung.com>
Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
Signed-off-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: John Stultz <jstultz@google.com>
Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
---
 drivers/clocksource/exynos_mct.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index da09f467a6bb..96361d5dc57d 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -219,12 +219,18 @@ static struct clocksource mct_frc = {
 	.resume		= exynos4_frc_resume,
 };
 
+/*
+ * Since ARM devices do not have an architected timer, they need to continue
+ * using the MCT as the main clocksource for timekeeping, sched_clock, and the
+ * delay timer. For AARCH64 SoCs, the architected timer is the preferred
+ * clocksource due to it's superior performance.
+ */
+#if defined(CONFIG_ARM)
 static u64 notrace exynos4_read_sched_clock(void)
 {
 	return exynos4_read_count_32();
 }
 
-#if defined(CONFIG_ARM)
 static struct delay_timer exynos4_delay_timer;
 
 static cycles_t exynos4_read_current_timer(void)
@@ -250,12 +256,13 @@ static int __init exynos4_clocksource_init(bool frc_shared)
 	exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer;
 	exynos4_delay_timer.freq = clk_rate;
 	register_current_timer_delay(&exynos4_delay_timer);
+
+	sched_clock_register(exynos4_read_sched_clock, 32, clk_rate);
 #endif
 
 	if (clocksource_register_hz(&mct_frc, clk_rate))
 		panic("%s: can't register clocksource\n", mct_frc.name);
 
-	sched_clock_register(exynos4_read_sched_clock, 32, clk_rate);
 
 	return 0;
 }
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 3/7] clocksource/drivers/exynos_mct: Set local timer interrupts as percpu
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
  2025-10-23 20:52 ` [PATCH v5 1/7] ARM: make register_current_timer_delay() accessible after init Will McVicker
  2025-10-23 20:52 ` [PATCH v5 2/7] clocksource/drivers/exynos_mct: Don't register as a sched_clock on arm64 Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-23 20:52 ` [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64 Will McVicker
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

From: Hosung Kim <hosung0.kim@samsung.com>

To allow the CPU to handle it's own clock events, we need to set the
IRQF_PERCPU flag. This prevents the local timer interrupts from
migrating to other CPUs.

Signed-off-by: Hosung Kim <hosung0.kim@samsung.com>
[Original commit from https://android.googlesource.com/kernel/gs/+/03267fad19f093bac979ca78309483e9eb3a8d16]
Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com>
Tested-by: Youngmin Nam <youngmin.nam@samsung.com>
Signed-off-by: Will McVicker <willmcvicker@google.com>
---
 drivers/clocksource/exynos_mct.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 96361d5dc57d..a5ef7d64b1c2 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -596,7 +596,8 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
 			irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
 			if (request_irq(mct_irq,
 					exynos4_mct_tick_isr,
-					IRQF_TIMER | IRQF_NOBALANCING,
+					IRQF_TIMER | IRQF_NOBALANCING |
+					IRQF_PERCPU,
 					pcpu_mevt->name, pcpu_mevt)) {
 				pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
 									cpu);
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
                   ` (2 preceding siblings ...)
  2025-10-23 20:52 ` [PATCH v5 3/7] clocksource/drivers/exynos_mct: Set local timer interrupts as percpu Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-24 11:19   ` Marek Szyprowski
  2025-10-23 20:52 ` [PATCH v5 5/7] clocksource/drivers/exynos_mct: Fix uninitialized irq name warning Will McVicker
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel,
	Krzysztof Kozlowski

From: Marek Szyprowski <m.szyprowski@samsung.com>

For some unknown reasons forcing percpu interrupts for local timers
breaks CPU hotplug for 'little' cores on legacy ARM 32bit Exynos based
machines (for example Exynos5422-based Odroid-XU3/XU4 boards). Use percpu
flag only when driver is compiled for newer ARM64 architecture.

Fixes: f3cec54ee3bf ("clocksource/drivers/exynos_mct: Set local timer interrupts as percpu")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index a5ef7d64b1c2..1429b9d03a58 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -597,7 +597,8 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
 			if (request_irq(mct_irq,
 					exynos4_mct_tick_isr,
 					IRQF_TIMER | IRQF_NOBALANCING |
-					IRQF_PERCPU,
+					(IS_ENABLED(CONFIG_ARM64) ?
+					 IRQF_PERCPU : 0),
 					pcpu_mevt->name, pcpu_mevt)) {
 				pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
 									cpu);
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 5/7] clocksource/drivers/exynos_mct: Fix uninitialized irq name warning
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
                   ` (3 preceding siblings ...)
  2025-10-23 20:52 ` [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64 Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-23 20:52 ` [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support Will McVicker
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

The Exynos MCT driver doesn't set the clocksource name until the CPU
hotplug state is setup which happens after the IRQs are requested. This
results in an empty IRQ name which leads to the below warning at
proc_create() time. When this happens, the userdata partition fails to
mount and the device gets stuck in an endless loop printing the error:

  root '/dev/disk/by-partlabel/userdata' doesn't exist or does not contain a /dev.

To fix this, we just need to initialize the name before requesting the
IRQs.

Warning from Pixel 6 kernel log:

[  T430] name len 0
[  T430] WARNING: CPU: 6 PID: 430 at fs/proc/generic.c:407 __proc_create+0x258/0x2b4
[  T430] Modules linked in: dwc3_exynos(E+)
[  T430]  ufs_exynos(E+) phy_exynos_ufs(E)
[  T430]  phy_exynos5_usbdrd(E) exynos_usi(E+) exynos_mct(E+) s3c2410_wdt(E)
[  T430]  arm_dsu_pmu(E) simplefb(E)
[  T430] CPU: 6 UID: 0 PID: 430 Comm: (udev-worker) Tainted:
         ... 6.14.0-next-20250331-4k-00008-g59adf909e40e #1 ...
[  T430] Tainted: [W]=WARN, [E]=UNSIGNED_MODULE
[  T430] Hardware name: Raven (DT)
[...]
[  T430] Call trace:
[  T430]  __proc_create+0x258/0x2b4 (P)
[  T430]  proc_mkdir+0x40/0xa0
[  T430]  register_handler_proc+0x118/0x140
[  T430]  __setup_irq+0x460/0x6d0
[  T430]  request_threaded_irq+0xcc/0x1b0
[  T430]  mct_init_dt+0x244/0x604 [exynos_mct ...]
[  T430]  mct_init_spi+0x18/0x34 [exynos_mct ...]
[  T430]  exynos4_mct_probe+0x30/0x4c [exynos_mct ...]
[  T430]  platform_probe+0x6c/0xe4
[  T430]  really_probe+0xf4/0x38c
[...]
[  T430]  driver_register+0x6c/0x140
[  T430]  __platform_driver_register+0x28/0x38
[  T430]  exynos4_mct_driver_init+0x24/0xfe8 [exynos_mct ...]
[  T430]  do_one_initcall+0x84/0x3c0
[  T430]  do_init_module+0x58/0x208
[  T430]  load_module+0x1de0/0x2500
[  T430]  init_module_from_file+0x8c/0xdc

Signed-off-by: Will McVicker <willmcvicker@google.com>
Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com>
Tested-by: Youngmin Nam <youngmin.nam@samsung.com>
---
 drivers/clocksource/exynos_mct.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 1429b9d03a58..fece6bbc190e 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -465,8 +465,6 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
 		per_cpu_ptr(&percpu_mct_tick, cpu);
 	struct clock_event_device *evt = &mevt->evt;
 
-	snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);
-
 	evt->name = mevt->name;
 	evt->cpumask = cpumask_of(cpu);
 	evt->set_next_event = exynos4_tick_set_next_event;
@@ -567,6 +565,14 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
 	for (i = MCT_L0_IRQ; i < nr_irqs; i++)
 		mct_irqs[i] = irq_of_parse_and_map(np, i);
 
+	for_each_possible_cpu(cpu) {
+		struct mct_clock_event_device *mevt =
+		    per_cpu_ptr(&percpu_mct_tick, cpu);
+
+		snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d",
+			 cpu);
+	}
+
 	if (mct_int_type == MCT_INT_PPI) {
 
 		err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
                   ` (4 preceding siblings ...)
  2025-10-23 20:52 ` [PATCH v5 5/7] clocksource/drivers/exynos_mct: Fix uninitialized irq name warning Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-24 11:14   ` Marek Szyprowski
  2025-10-23 20:52 ` [PATCH v5 7/7] arm64: exynos: Drop select CLKSRC_EXYNOS_MCT Will McVicker
  2025-10-23 20:57 ` [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver William McVicker
  7 siblings, 1 reply; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

From: Donghoon Yu <hoony.yu@samsung.com>

On Arm64 platforms the Exynos MCT driver can be built as a module. On
boot (and even after boot) the arch_timer is used as the clocksource and
tick timer. Once the MCT driver is loaded, it can be used as the wakeup
source for the arch_timer.

Signed-off-by: Donghoon Yu <hoony.yu@samsung.com>
Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
Signed-off-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
[original commit from https://android.googlesource.com/kernel/gs/+/8a52a8288ec7d88ff78f0b37480dbb0e9c65bbfd]
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
---
 drivers/clocksource/Kconfig      |  3 +-
 drivers/clocksource/exynos_mct.c | 56 +++++++++++++++++++++++++++-----
 2 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index ffcd23668763..9450cfaf982f 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -451,7 +451,8 @@ config ATMEL_TCB_CLKSRC
 	  Support for Timer Counter Blocks on Atmel SoCs.
 
 config CLKSRC_EXYNOS_MCT
-	bool "Exynos multi core timer driver" if COMPILE_TEST
+	tristate "Exynos multi core timer driver" if ARM64
+	default y if ARCH_EXYNOS || COMPILE_TEST
 	depends on ARM || ARM64
 	depends on ARCH_ARTPEC || ARCH_EXYNOS || COMPILE_TEST
 	help
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index fece6bbc190e..a87caf3928ef 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -15,9 +15,11 @@
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/percpu.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
 
@@ -217,6 +219,7 @@ static struct clocksource mct_frc = {
 	.mask		= CLOCKSOURCE_MASK(32),
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.resume		= exynos4_frc_resume,
+	.owner		= THIS_MODULE,
 };
 
 /*
@@ -241,7 +244,7 @@ static cycles_t exynos4_read_current_timer(void)
 }
 #endif
 
-static int __init exynos4_clocksource_init(bool frc_shared)
+static int exynos4_clocksource_init(bool frc_shared)
 {
 	/*
 	 * When the frc is shared, the main processor should have already
@@ -336,6 +339,7 @@ static struct clock_event_device mct_comp_device = {
 	.set_state_oneshot	= mct_set_state_shutdown,
 	.set_state_oneshot_stopped = mct_set_state_shutdown,
 	.tick_resume		= mct_set_state_shutdown,
+	.owner			= THIS_MODULE,
 };
 
 static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
@@ -476,6 +480,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
 	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
 			CLOCK_EVT_FEAT_PERCPU;
 	evt->rating = MCT_CLKEVENTS_RATING;
+	evt->owner = THIS_MODULE;
 
 	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
 
@@ -511,7 +516,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
 	return 0;
 }
 
-static int __init exynos4_timer_resources(struct device_node *np)
+static int exynos4_timer_resources(struct device_node *np)
 {
 	struct clk *mct_clk, *tick_clk;
 
@@ -539,7 +544,7 @@ static int __init exynos4_timer_resources(struct device_node *np)
  * @local_idx: array mapping CPU numbers to local timer indices
  * @nr_local: size of @local_idx array
  */
-static int __init exynos4_timer_interrupts(struct device_node *np,
+static int exynos4_timer_interrupts(struct device_node *np,
 					   unsigned int int_type,
 					   const u32 *local_idx,
 					   size_t nr_local)
@@ -653,7 +658,7 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
 	return err;
 }
 
-static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
+static int mct_init_dt(struct device_node *np, unsigned int int_type)
 {
 	bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
 	u32 local_idx[MCT_NR_LOCAL] = {0};
@@ -701,15 +706,48 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
 	return exynos4_clockevent_init();
 }
 
-
-static int __init mct_init_spi(struct device_node *np)
+static int mct_init_spi(struct device_node *np)
 {
 	return mct_init_dt(np, MCT_INT_SPI);
 }
 
-static int __init mct_init_ppi(struct device_node *np)
+static int mct_init_ppi(struct device_node *np)
 {
 	return mct_init_dt(np, MCT_INT_PPI);
 }
-TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
-TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);
+
+static int exynos4_mct_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int (*mct_init)(struct device_node *np);
+
+	mct_init = of_device_get_match_data(dev);
+	if (!mct_init)
+		return -EINVAL;
+
+	return mct_init(dev->of_node);
+}
+
+static const struct of_device_id exynos4_mct_match_table[] = {
+	{ .compatible = "samsung,exynos4210-mct", .data = &mct_init_spi, },
+	{ .compatible = "samsung,exynos4412-mct", .data = &mct_init_ppi, },
+	{}
+};
+MODULE_DEVICE_TABLE(of, exynos4_mct_match_table);
+
+static struct platform_driver exynos4_mct_driver = {
+	.probe		= exynos4_mct_probe,
+	.driver		= {
+		.name	= "exynos-mct",
+		.of_match_table = exynos4_mct_match_table,
+	},
+};
+
+static __init int exynos_mct_init(void)
+{
+  return platform_driver_register(&exynos4_mct_driver);
+}
+module_init(exynos_mct_init);
+
+MODULE_DESCRIPTION("Exynos Multi Core Timer Driver");
+MODULE_LICENSE("GPL");
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 7/7] arm64: exynos: Drop select CLKSRC_EXYNOS_MCT
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
                   ` (5 preceding siblings ...)
  2025-10-23 20:52 ` [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support Will McVicker
@ 2025-10-23 20:52 ` Will McVicker
  2025-10-23 20:57 ` [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver William McVicker
  7 siblings, 0 replies; 15+ messages in thread
From: Will McVicker @ 2025-10-23 20:52 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Will McVicker, Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

Since the Exynos MCT driver can be built as a module for some Arm64 SoCs
like gs101, drop force-selecting it as a built-in driver by ARCH_EXYNOS
and instead depend on `default y if ARCH_EXYNOS` to select it
automatically. This allows platforms like Android to build the driver as
a module if desired.

Signed-off-by: Will McVicker <willmcvicker@google.com>
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com>
Tested-by: Youngmin Nam <youngmin.nam@samsung.com>
---
 arch/arm64/Kconfig.platforms | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 13173795c43d..fc6026c368ca 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -128,7 +128,6 @@ config ARCH_CIX
 config ARCH_EXYNOS
 	bool "Samsung Exynos SoC family"
 	select COMMON_CLK_SAMSUNG
-	select CLKSRC_EXYNOS_MCT
 	select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
 	select EXYNOS_PMU
 	select PINCTRL
-- 
2.51.1.821.gb6fe4d2222-goog



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver
  2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
                   ` (6 preceding siblings ...)
  2025-10-23 20:52 ` [PATCH v5 7/7] arm64: exynos: Drop select CLKSRC_EXYNOS_MCT Will McVicker
@ 2025-10-23 20:57 ` William McVicker
  7 siblings, 0 replies; 15+ messages in thread
From: William McVicker @ 2025-10-23 20:57 UTC (permalink / raw)
  To: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Hosung Kim,
	Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley, Marek Szyprowski,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

Sorry, I missed the "v5" prefix for the patches in the first v5 series. Please
ignore this cover letter and refer to the updated series here:

  https://lore.kernel.org/all/20251023205257.2029526-1-willmcvicker@google.com/

Regards,
Will


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support
  2025-10-23 20:52 ` [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support Will McVicker
@ 2025-10-24 11:14   ` Marek Szyprowski
  2025-10-24 15:53     ` William McVicker
  0 siblings, 1 reply; 15+ messages in thread
From: Marek Szyprowski @ 2025-10-24 11:14 UTC (permalink / raw)
  To: Will McVicker, Russell King, Catalin Marinas, Will Deacon,
	Daniel Lezcano, Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar,
	Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel

On 23.10.2025 22:52, Will McVicker wrote:
> From: Donghoon Yu <hoony.yu@samsung.com>
>
> On Arm64 platforms the Exynos MCT driver can be built as a module. On
> boot (and even after boot) the arch_timer is used as the clocksource and
> tick timer. Once the MCT driver is loaded, it can be used as the wakeup
> source for the arch_timer.
>
> Signed-off-by: Donghoon Yu <hoony.yu@samsung.com>
> Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
> Signed-off-by: Will McVicker <willmcvicker@google.com>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> [original commit from https://android.googlesource.com/kernel/gs/+/8a52a8288ec7d88ff78f0b37480dbb0e9c65bbfd]
> Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
> Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
> ---
>   drivers/clocksource/Kconfig      |  3 +-
>   drivers/clocksource/exynos_mct.c | 56 +++++++++++++++++++++++++++-----
>   2 files changed, 49 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index ffcd23668763..9450cfaf982f 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -451,7 +451,8 @@ config ATMEL_TCB_CLKSRC
>   	  Support for Timer Counter Blocks on Atmel SoCs.
>   
>   config CLKSRC_EXYNOS_MCT
> -	bool "Exynos multi core timer driver" if COMPILE_TEST
> +	tristate "Exynos multi core timer driver" if ARM64
> +	default y if ARCH_EXYNOS || COMPILE_TEST
>   	depends on ARM || ARM64
>   	depends on ARCH_ARTPEC || ARCH_EXYNOS || COMPILE_TEST
>   	help
> diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
> index fece6bbc190e..a87caf3928ef 100644
> --- a/drivers/clocksource/exynos_mct.c
> +++ b/drivers/clocksource/exynos_mct.c
> @@ -15,9 +15,11 @@
>   #include <linux/cpu.h>
>   #include <linux/delay.h>
>   #include <linux/percpu.h>
> +#include <linux/module.h>
>   #include <linux/of.h>
>   #include <linux/of_irq.h>
>   #include <linux/of_address.h>
> +#include <linux/platform_device.h>
>   #include <linux/clocksource.h>
>   #include <linux/sched_clock.h>
>   
> @@ -217,6 +219,7 @@ static struct clocksource mct_frc = {
>   	.mask		= CLOCKSOURCE_MASK(32),
>   	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>   	.resume		= exynos4_frc_resume,
> +	.owner		= THIS_MODULE,
>   };
>   
>   /*
> @@ -241,7 +244,7 @@ static cycles_t exynos4_read_current_timer(void)
>   }
>   #endif
>   
> -static int __init exynos4_clocksource_init(bool frc_shared)
> +static int exynos4_clocksource_init(bool frc_shared)
>   {
>   	/*
>   	 * When the frc is shared, the main processor should have already
> @@ -336,6 +339,7 @@ static struct clock_event_device mct_comp_device = {
>   	.set_state_oneshot	= mct_set_state_shutdown,
>   	.set_state_oneshot_stopped = mct_set_state_shutdown,
>   	.tick_resume		= mct_set_state_shutdown,
> +	.owner			= THIS_MODULE,
>   };
>   
>   static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
> @@ -476,6 +480,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
>   	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
>   			CLOCK_EVT_FEAT_PERCPU;
>   	evt->rating = MCT_CLKEVENTS_RATING;
> +	evt->owner = THIS_MODULE;
>   
>   	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
>   
> @@ -511,7 +516,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
>   	return 0;
>   }
>   
> -static int __init exynos4_timer_resources(struct device_node *np)
> +static int exynos4_timer_resources(struct device_node *np)
>   {
>   	struct clk *mct_clk, *tick_clk;
>   
> @@ -539,7 +544,7 @@ static int __init exynos4_timer_resources(struct device_node *np)
>    * @local_idx: array mapping CPU numbers to local timer indices
>    * @nr_local: size of @local_idx array
>    */
> -static int __init exynos4_timer_interrupts(struct device_node *np,
> +static int exynos4_timer_interrupts(struct device_node *np,
>   					   unsigned int int_type,
>   					   const u32 *local_idx,
>   					   size_t nr_local)
> @@ -653,7 +658,7 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
>   	return err;
>   }
>   
> -static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
> +static int mct_init_dt(struct device_node *np, unsigned int int_type)
>   {
>   	bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
>   	u32 local_idx[MCT_NR_LOCAL] = {0};
> @@ -701,15 +706,48 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
>   	return exynos4_clockevent_init();
>   }
>   
> -
> -static int __init mct_init_spi(struct device_node *np)
> +static int mct_init_spi(struct device_node *np)
>   {
>   	return mct_init_dt(np, MCT_INT_SPI);
>   }
>   
> -static int __init mct_init_ppi(struct device_node *np)
> +static int mct_init_ppi(struct device_node *np)
>   {
>   	return mct_init_dt(np, MCT_INT_PPI);
>   }
> -TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
> -TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);
> +
> +static int exynos4_mct_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	int (*mct_init)(struct device_node *np);
> +
> +	mct_init = of_device_get_match_data(dev);
> +	if (!mct_init)
> +		return -EINVAL;
> +
> +	return mct_init(dev->of_node);
> +}
> +
> +static const struct of_device_id exynos4_mct_match_table[] = {
> +	{ .compatible = "samsung,exynos4210-mct", .data = &mct_init_spi, },
> +	{ .compatible = "samsung,exynos4412-mct", .data = &mct_init_ppi, },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, exynos4_mct_match_table);
> +
> +static struct platform_driver exynos4_mct_driver = {
> +	.probe		= exynos4_mct_probe,
> +	.driver		= {
> +		.name	= "exynos-mct",
> +		.of_match_table = exynos4_mct_match_table,
> +	},
> +};
> +
> +static __init int exynos_mct_init(void)
> +{
> +  return platform_driver_register(&exynos4_mct_driver);
> +}
> +module_init(exynos_mct_init);
> +
> +MODULE_DESCRIPTION("Exynos Multi Core Timer Driver");
> +MODULE_LICENSE("GPL");

Sorry, but this still won't work on legacy ARM 32bit systems with MCT as 
the only clocksource, which needs a driver available very early (that's 
why it used TIMER_OF_DECLAREmacro). You need to make it conditional 
under CONFIG_ARM:

#ifdef CONFIG_ARM

TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);

#else

... (module-based intialization).

#endif

The latter case might skip the legacy exynos4412-style case, as all MCT 
variants used on ARM 64bit systems are exynos4210 compatible.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64
  2025-10-23 20:52 ` [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64 Will McVicker
@ 2025-10-24 11:19   ` Marek Szyprowski
  2025-10-24 15:54     ` William McVicker
  0 siblings, 1 reply; 15+ messages in thread
From: Marek Szyprowski @ 2025-10-24 11:19 UTC (permalink / raw)
  To: Will McVicker, Russell King, Catalin Marinas, Will Deacon,
	Daniel Lezcano, Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar,
	Ingo Molnar, Peter Griffin, Youngmin Nam
  Cc: Donghoon Yu, Rob Herring, Saravana Kannan, John Stultz,
	Tudor Ambarus, André Draszik, Conor Dooley,
	linux-samsung-soc, kernel-team, linux-arm-kernel, linux-kernel,
	Krzysztof Kozlowski

On 23.10.2025 22:52, Will McVicker wrote:
> From: Marek Szyprowski <m.szyprowski@samsung.com>
>
> For some unknown reasons forcing percpu interrupts for local timers
> breaks CPU hotplug for 'little' cores on legacy ARM 32bit Exynos based
> machines (for example Exynos5422-based Odroid-XU3/XU4 boards). Use percpu
> flag only when driver is compiled for newer ARM64 architecture.
>
> Fixes: f3cec54ee3bf ("clocksource/drivers/exynos_mct: Set local timer interrupts as percpu")

This tag doesn't make sense in this patchset. Simply squash this change 
with the previous one, adding the following tags:

Suggested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: 
https://lore.kernel.org/all/20250827102645.1964659-1-m.szyprowski@samsung.com/ 

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
>   drivers/clocksource/exynos_mct.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
> index a5ef7d64b1c2..1429b9d03a58 100644
> --- a/drivers/clocksource/exynos_mct.c
> +++ b/drivers/clocksource/exynos_mct.c
> @@ -597,7 +597,8 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
>   			if (request_irq(mct_irq,
>   					exynos4_mct_tick_isr,
>   					IRQF_TIMER | IRQF_NOBALANCING |
> -					IRQF_PERCPU,
> +					(IS_ENABLED(CONFIG_ARM64) ?
> +					 IRQF_PERCPU : 0),
>   					pcpu_mevt->name, pcpu_mevt)) {
>   				pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
>   									cpu);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support
  2025-10-24 11:14   ` Marek Szyprowski
@ 2025-10-24 15:53     ` William McVicker
  2025-10-24 16:01       ` Marek Szyprowski
  0 siblings, 1 reply; 15+ messages in thread
From: William McVicker @ 2025-10-24 15:53 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Ingo Molnar,
	Peter Griffin, Youngmin Nam, Donghoon Yu, Rob Herring,
	Saravana Kannan, John Stultz, Tudor Ambarus, André Draszik,
	Conor Dooley, linux-samsung-soc, kernel-team, linux-arm-kernel,
	linux-kernel

On 10/24/2025, Marek Szyprowski wrote:
> On 23.10.2025 22:52, Will McVicker wrote:
> > From: Donghoon Yu <hoony.yu@samsung.com>
> >
> > On Arm64 platforms the Exynos MCT driver can be built as a module. On
> > boot (and even after boot) the arch_timer is used as the clocksource and
> > tick timer. Once the MCT driver is loaded, it can be used as the wakeup
> > source for the arch_timer.
> >
> > Signed-off-by: Donghoon Yu <hoony.yu@samsung.com>
> > Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
> > Signed-off-by: Will McVicker <willmcvicker@google.com>
> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > [original commit from https://android.googlesource.com/kernel/gs/+/8a52a8288ec7d88ff78f0b37480dbb0e9c65bbfd]
> > Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
> > Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
> > ---
> >   drivers/clocksource/Kconfig      |  3 +-
> >   drivers/clocksource/exynos_mct.c | 56 +++++++++++++++++++++++++++-----
> >   2 files changed, 49 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index ffcd23668763..9450cfaf982f 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -451,7 +451,8 @@ config ATMEL_TCB_CLKSRC
> >   	  Support for Timer Counter Blocks on Atmel SoCs.
> >   
> >   config CLKSRC_EXYNOS_MCT
> > -	bool "Exynos multi core timer driver" if COMPILE_TEST
> > +	tristate "Exynos multi core timer driver" if ARM64
> > +	default y if ARCH_EXYNOS || COMPILE_TEST
> >   	depends on ARM || ARM64
> >   	depends on ARCH_ARTPEC || ARCH_EXYNOS || COMPILE_TEST
> >   	help
> > diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
> > index fece6bbc190e..a87caf3928ef 100644
> > --- a/drivers/clocksource/exynos_mct.c
> > +++ b/drivers/clocksource/exynos_mct.c
> > @@ -15,9 +15,11 @@
> >   #include <linux/cpu.h>
> >   #include <linux/delay.h>
> >   #include <linux/percpu.h>
> > +#include <linux/module.h>
> >   #include <linux/of.h>
> >   #include <linux/of_irq.h>
> >   #include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> >   #include <linux/clocksource.h>
> >   #include <linux/sched_clock.h>
> >   
> > @@ -217,6 +219,7 @@ static struct clocksource mct_frc = {
> >   	.mask		= CLOCKSOURCE_MASK(32),
> >   	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> >   	.resume		= exynos4_frc_resume,
> > +	.owner		= THIS_MODULE,
> >   };
> >   
> >   /*
> > @@ -241,7 +244,7 @@ static cycles_t exynos4_read_current_timer(void)
> >   }
> >   #endif
> >   
> > -static int __init exynos4_clocksource_init(bool frc_shared)
> > +static int exynos4_clocksource_init(bool frc_shared)
> >   {
> >   	/*
> >   	 * When the frc is shared, the main processor should have already
> > @@ -336,6 +339,7 @@ static struct clock_event_device mct_comp_device = {
> >   	.set_state_oneshot	= mct_set_state_shutdown,
> >   	.set_state_oneshot_stopped = mct_set_state_shutdown,
> >   	.tick_resume		= mct_set_state_shutdown,
> > +	.owner			= THIS_MODULE,
> >   };
> >   
> >   static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
> > @@ -476,6 +480,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
> >   	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
> >   			CLOCK_EVT_FEAT_PERCPU;
> >   	evt->rating = MCT_CLKEVENTS_RATING;
> > +	evt->owner = THIS_MODULE;
> >   
> >   	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
> >   
> > @@ -511,7 +516,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
> >   	return 0;
> >   }
> >   
> > -static int __init exynos4_timer_resources(struct device_node *np)
> > +static int exynos4_timer_resources(struct device_node *np)
> >   {
> >   	struct clk *mct_clk, *tick_clk;
> >   
> > @@ -539,7 +544,7 @@ static int __init exynos4_timer_resources(struct device_node *np)
> >    * @local_idx: array mapping CPU numbers to local timer indices
> >    * @nr_local: size of @local_idx array
> >    */
> > -static int __init exynos4_timer_interrupts(struct device_node *np,
> > +static int exynos4_timer_interrupts(struct device_node *np,
> >   					   unsigned int int_type,
> >   					   const u32 *local_idx,
> >   					   size_t nr_local)
> > @@ -653,7 +658,7 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
> >   	return err;
> >   }
> >   
> > -static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
> > +static int mct_init_dt(struct device_node *np, unsigned int int_type)
> >   {
> >   	bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
> >   	u32 local_idx[MCT_NR_LOCAL] = {0};
> > @@ -701,15 +706,48 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
> >   	return exynos4_clockevent_init();
> >   }
> >   
> > -
> > -static int __init mct_init_spi(struct device_node *np)
> > +static int mct_init_spi(struct device_node *np)
> >   {
> >   	return mct_init_dt(np, MCT_INT_SPI);
> >   }
> >   
> > -static int __init mct_init_ppi(struct device_node *np)
> > +static int mct_init_ppi(struct device_node *np)
> >   {
> >   	return mct_init_dt(np, MCT_INT_PPI);
> >   }
> > -TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
> > -TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);
> > +
> > +static int exynos4_mct_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	int (*mct_init)(struct device_node *np);
> > +
> > +	mct_init = of_device_get_match_data(dev);
> > +	if (!mct_init)
> > +		return -EINVAL;
> > +
> > +	return mct_init(dev->of_node);
> > +}
> > +
> > +static const struct of_device_id exynos4_mct_match_table[] = {
> > +	{ .compatible = "samsung,exynos4210-mct", .data = &mct_init_spi, },
> > +	{ .compatible = "samsung,exynos4412-mct", .data = &mct_init_ppi, },
> > +	{}
> > +};
> > +MODULE_DEVICE_TABLE(of, exynos4_mct_match_table);
> > +
> > +static struct platform_driver exynos4_mct_driver = {
> > +	.probe		= exynos4_mct_probe,
> > +	.driver		= {
> > +		.name	= "exynos-mct",
> > +		.of_match_table = exynos4_mct_match_table,
> > +	},
> > +};
> > +
> > +static __init int exynos_mct_init(void)
> > +{
> > +  return platform_driver_register(&exynos4_mct_driver);
> > +}
> > +module_init(exynos_mct_init);
> > +
> > +MODULE_DESCRIPTION("Exynos Multi Core Timer Driver");
> > +MODULE_LICENSE("GPL");
> 
> Sorry, but this still won't work on legacy ARM 32bit systems with MCT as 
> the only clocksource, which needs a driver available very early (that's 
> why it used TIMER_OF_DECLAREmacro). You need to make it conditional 
> under CONFIG_ARM:

Can we rely on the bootloader to setup the MCT timer and then hand-off at boot
once the driver is initialized?

Daniel was working on a solution to transparently handle calling
TIMER_OF_DECLARE() when a timer driver can be configured as both a module or
built-in here:

  https://lore.kernel.org/all/20250625085715.889837-1-daniel.lezcano@linaro.org/

Daniel, do you have plans to finish that? In the meantime, can we go with the
`#if CONFIG_ARM` solution?

Thanks,
Will

<snip>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64
  2025-10-24 11:19   ` Marek Szyprowski
@ 2025-10-24 15:54     ` William McVicker
  0 siblings, 0 replies; 15+ messages in thread
From: William McVicker @ 2025-10-24 15:54 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Ingo Molnar,
	Peter Griffin, Youngmin Nam, Donghoon Yu, Rob Herring,
	Saravana Kannan, John Stultz, Tudor Ambarus, André Draszik,
	Conor Dooley, linux-samsung-soc, kernel-team, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski

On 10/24/2025, Marek Szyprowski wrote:
> On 23.10.2025 22:52, Will McVicker wrote:
> > From: Marek Szyprowski <m.szyprowski@samsung.com>
> >
> > For some unknown reasons forcing percpu interrupts for local timers
> > breaks CPU hotplug for 'little' cores on legacy ARM 32bit Exynos based
> > machines (for example Exynos5422-based Odroid-XU3/XU4 boards). Use percpu
> > flag only when driver is compiled for newer ARM64 architecture.
> >
> > Fixes: f3cec54ee3bf ("clocksource/drivers/exynos_mct: Set local timer interrupts as percpu")
> 
> This tag doesn't make sense in this patchset. Simply squash this change 
> with the previous one, adding the following tags:
> 
> Suggested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Link: 
> https://lore.kernel.org/all/20250827102645.1964659-1-m.szyprowski@samsung.com/ 

Okay, no problem!

--Will


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support
  2025-10-24 15:53     ` William McVicker
@ 2025-10-24 16:01       ` Marek Szyprowski
  0 siblings, 0 replies; 15+ messages in thread
From: Marek Szyprowski @ 2025-10-24 16:01 UTC (permalink / raw)
  To: William McVicker
  Cc: Russell King, Catalin Marinas, Will Deacon, Daniel Lezcano,
	Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Ingo Molnar,
	Peter Griffin, Youngmin Nam, Donghoon Yu, Rob Herring,
	Saravana Kannan, John Stultz, Tudor Ambarus, André Draszik,
	Conor Dooley, linux-samsung-soc, kernel-team, linux-arm-kernel,
	linux-kernel

On 24.10.2025 17:53, William McVicker wrote:
> On 10/24/2025, Marek Szyprowski wrote:
>> On 23.10.2025 22:52, Will McVicker wrote:
>>> From: Donghoon Yu <hoony.yu@samsung.com>
>>>
>>> On Arm64 platforms the Exynos MCT driver can be built as a module. On
>>> boot (and even after boot) the arch_timer is used as the clocksource and
>>> tick timer. Once the MCT driver is loaded, it can be used as the wakeup
>>> source for the arch_timer.
>>>
>>> Signed-off-by: Donghoon Yu <hoony.yu@samsung.com>
>>> Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
>>> Signed-off-by: Will McVicker <willmcvicker@google.com>
>>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>>> [original commit from https://android.googlesource.com/kernel/gs/+/8a52a8288ec7d88ff78f0b37480dbb0e9c65bbfd]
>>> Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
>>> Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
>>> ---
>>>    drivers/clocksource/Kconfig      |  3 +-
>>>    drivers/clocksource/exynos_mct.c | 56 +++++++++++++++++++++++++++-----
>>>    2 files changed, 49 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>>> index ffcd23668763..9450cfaf982f 100644
>>> --- a/drivers/clocksource/Kconfig
>>> +++ b/drivers/clocksource/Kconfig
>>> @@ -451,7 +451,8 @@ config ATMEL_TCB_CLKSRC
>>>    	  Support for Timer Counter Blocks on Atmel SoCs.
>>>    
>>>    config CLKSRC_EXYNOS_MCT
>>> -	bool "Exynos multi core timer driver" if COMPILE_TEST
>>> +	tristate "Exynos multi core timer driver" if ARM64
>>> +	default y if ARCH_EXYNOS || COMPILE_TEST
>>>    	depends on ARM || ARM64
>>>    	depends on ARCH_ARTPEC || ARCH_EXYNOS || COMPILE_TEST
>>>    	help
>>> diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
>>> index fece6bbc190e..a87caf3928ef 100644
>>> --- a/drivers/clocksource/exynos_mct.c
>>> +++ b/drivers/clocksource/exynos_mct.c
>>> @@ -15,9 +15,11 @@
>>>    #include <linux/cpu.h>
>>>    #include <linux/delay.h>
>>>    #include <linux/percpu.h>
>>> +#include <linux/module.h>
>>>    #include <linux/of.h>
>>>    #include <linux/of_irq.h>
>>>    #include <linux/of_address.h>
>>> +#include <linux/platform_device.h>
>>>    #include <linux/clocksource.h>
>>>    #include <linux/sched_clock.h>
>>>    
>>> @@ -217,6 +219,7 @@ static struct clocksource mct_frc = {
>>>    	.mask		= CLOCKSOURCE_MASK(32),
>>>    	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>>>    	.resume		= exynos4_frc_resume,
>>> +	.owner		= THIS_MODULE,
>>>    };
>>>    
>>>    /*
>>> @@ -241,7 +244,7 @@ static cycles_t exynos4_read_current_timer(void)
>>>    }
>>>    #endif
>>>    
>>> -static int __init exynos4_clocksource_init(bool frc_shared)
>>> +static int exynos4_clocksource_init(bool frc_shared)
>>>    {
>>>    	/*
>>>    	 * When the frc is shared, the main processor should have already
>>> @@ -336,6 +339,7 @@ static struct clock_event_device mct_comp_device = {
>>>    	.set_state_oneshot	= mct_set_state_shutdown,
>>>    	.set_state_oneshot_stopped = mct_set_state_shutdown,
>>>    	.tick_resume		= mct_set_state_shutdown,
>>> +	.owner			= THIS_MODULE,
>>>    };
>>>    
>>>    static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
>>> @@ -476,6 +480,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
>>>    	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
>>>    			CLOCK_EVT_FEAT_PERCPU;
>>>    	evt->rating = MCT_CLKEVENTS_RATING;
>>> +	evt->owner = THIS_MODULE;
>>>    
>>>    	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
>>>    
>>> @@ -511,7 +516,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
>>>    	return 0;
>>>    }
>>>    
>>> -static int __init exynos4_timer_resources(struct device_node *np)
>>> +static int exynos4_timer_resources(struct device_node *np)
>>>    {
>>>    	struct clk *mct_clk, *tick_clk;
>>>    
>>> @@ -539,7 +544,7 @@ static int __init exynos4_timer_resources(struct device_node *np)
>>>     * @local_idx: array mapping CPU numbers to local timer indices
>>>     * @nr_local: size of @local_idx array
>>>     */
>>> -static int __init exynos4_timer_interrupts(struct device_node *np,
>>> +static int exynos4_timer_interrupts(struct device_node *np,
>>>    					   unsigned int int_type,
>>>    					   const u32 *local_idx,
>>>    					   size_t nr_local)
>>> @@ -653,7 +658,7 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
>>>    	return err;
>>>    }
>>>    
>>> -static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
>>> +static int mct_init_dt(struct device_node *np, unsigned int int_type)
>>>    {
>>>    	bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
>>>    	u32 local_idx[MCT_NR_LOCAL] = {0};
>>> @@ -701,15 +706,48 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
>>>    	return exynos4_clockevent_init();
>>>    }
>>>    
>>> -
>>> -static int __init mct_init_spi(struct device_node *np)
>>> +static int mct_init_spi(struct device_node *np)
>>>    {
>>>    	return mct_init_dt(np, MCT_INT_SPI);
>>>    }
>>>    
>>> -static int __init mct_init_ppi(struct device_node *np)
>>> +static int mct_init_ppi(struct device_node *np)
>>>    {
>>>    	return mct_init_dt(np, MCT_INT_PPI);
>>>    }
>>> -TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
>>> -TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);
>>> +
>>> +static int exynos4_mct_probe(struct platform_device *pdev)
>>> +{
>>> +	struct device *dev = &pdev->dev;
>>> +	int (*mct_init)(struct device_node *np);
>>> +
>>> +	mct_init = of_device_get_match_data(dev);
>>> +	if (!mct_init)
>>> +		return -EINVAL;
>>> +
>>> +	return mct_init(dev->of_node);
>>> +}
>>> +
>>> +static const struct of_device_id exynos4_mct_match_table[] = {
>>> +	{ .compatible = "samsung,exynos4210-mct", .data = &mct_init_spi, },
>>> +	{ .compatible = "samsung,exynos4412-mct", .data = &mct_init_ppi, },
>>> +	{}
>>> +};
>>> +MODULE_DEVICE_TABLE(of, exynos4_mct_match_table);
>>> +
>>> +static struct platform_driver exynos4_mct_driver = {
>>> +	.probe		= exynos4_mct_probe,
>>> +	.driver		= {
>>> +		.name	= "exynos-mct",
>>> +		.of_match_table = exynos4_mct_match_table,
>>> +	},
>>> +};
>>> +
>>> +static __init int exynos_mct_init(void)
>>> +{
>>> +  return platform_driver_register(&exynos4_mct_driver);
>>> +}
>>> +module_init(exynos_mct_init);
>>> +
>>> +MODULE_DESCRIPTION("Exynos Multi Core Timer Driver");
>>> +MODULE_LICENSE("GPL");
>> Sorry, but this still won't work on legacy ARM 32bit systems with MCT as
>> the only clocksource, which needs a driver available very early (that's
>> why it used TIMER_OF_DECLAREmacro). You need to make it conditional
>> under CONFIG_ARM:
> Can we rely on the bootloader to setup the MCT timer and then hand-off at boot
> once the driver is initialized?

I'm not sure if we can expect anything from the legacy bootloaders and 
kernel requires timer quite early during boot, much earlier than kernel 
modules get initialized.


> Daniel was working on a solution to transparently handle calling
> TIMER_OF_DECLARE() when a timer driver can be configured as both a module or
> built-in here:
>
>    https://lore.kernel.org/all/20250625085715.889837-1-daniel.lezcano@linaro.org/
>
> Daniel, do you have plans to finish that? In the meantime, can we go with the
> `#if CONFIG_ARM` solution?
>
> Thanks,
> Will
>
> <snip>
>
Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-10-24 16:02 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-23 20:52 [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver Will McVicker
2025-10-23 20:52 ` [PATCH v5 1/7] ARM: make register_current_timer_delay() accessible after init Will McVicker
2025-10-23 20:52 ` [PATCH v5 2/7] clocksource/drivers/exynos_mct: Don't register as a sched_clock on arm64 Will McVicker
2025-10-23 20:52 ` [PATCH v5 3/7] clocksource/drivers/exynos_mct: Set local timer interrupts as percpu Will McVicker
2025-10-23 20:52 ` [PATCH v5 4/7] clocksource/drivers/exynos_mct: Use percpu interrupts only on ARM64 Will McVicker
2025-10-24 11:19   ` Marek Szyprowski
2025-10-24 15:54     ` William McVicker
2025-10-23 20:52 ` [PATCH v5 5/7] clocksource/drivers/exynos_mct: Fix uninitialized irq name warning Will McVicker
2025-10-23 20:52 ` [PATCH v5 6/7] clocksource/drivers/exynos_mct: Add module support Will McVicker
2025-10-24 11:14   ` Marek Szyprowski
2025-10-24 15:53     ` William McVicker
2025-10-24 16:01       ` Marek Szyprowski
2025-10-23 20:52 ` [PATCH v5 7/7] arm64: exynos: Drop select CLKSRC_EXYNOS_MCT Will McVicker
2025-10-23 20:57 ` [PATCH v5 0/7] Add module support for Arm64 Exynos MCT driver William McVicker
  -- strict thread matches above, loose matches on Subject: below --
2025-10-23 20:50 Will McVicker

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).