From: Will McVicker <willmcvicker@google.com>
To: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Thomas Gleixner <tglx@linutronix.de>,
Krzysztof Kozlowski <krzk@kernel.org>,
Alim Akhtar <alim.akhtar@samsung.com>
Cc: "Will McVicker" <willmcvicker@google.com>,
"Donghoon Yu" <hoony.yu@samsung.com>,
"Rob Herring" <robh@kernel.org>,
"John Stultz" <jstultz@google.com>,
"Youngmin Nam" <youngmin.nam@samsung.com>,
"Peter Griffin" <peter.griffin@linaro.org>,
"Tudor Ambarus" <tudor.ambarus@linaro.org>,
"André Draszik" <andre.draszik@linaro.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"Russell King (Oracle)" <linux@armlinux.org.uk>,
linux-samsung-soc@vger.kernel.org, kernel-team@android.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v7 5/6] clocksource/drivers/exynos_mct: Add module support for ARM64
Date: Fri, 5 Dec 2025 01:10:18 +0000 [thread overview]
Message-ID: <20251205011027.720512-6-willmcvicker@google.com> (raw)
In-Reply-To: <20251205011027.720512-1-willmcvicker@google.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.
Note, this commit was derived from
https://android.googlesource.com/kernel/gs/+/8a52a8288ec7d88ff78f0b37480dbb0e9c65bbfd.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
Tested-by: Youngmin Nam <youngmin.nam@samsung.com> # AOSP -> Linux port
Signed-off-by: Will McVicker <willmcvicker@google.com>
---
drivers/clocksource/Kconfig | 3 +-
drivers/clocksource/exynos_mct.c | 51 ++++++++++++++++++++++++++++----
2 files changed, 47 insertions(+), 7 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 922c2b519a39..d9a888607726 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>
@@ -232,6 +234,7 @@ static struct clocksource mct_frc = {
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.resume = exynos4_frc_resume,
+ .owner = THIS_MODULE,
};
/*
@@ -256,7 +259,7 @@ static cycles_t exynos4_read_current_timer(void)
}
#endif
-static int __init exynos4_clocksource_init(struct mct_context *ctx, bool frc_shared)
+static int __init_or_module exynos4_clocksource_init(struct mct_context *ctx, bool frc_shared)
{
/*
* When the frc is shared, the main processor should have already
@@ -343,6 +346,7 @@ static struct mct_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,
},
};
@@ -484,6 +488,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);
@@ -520,7 +525,7 @@ static int exynos4_mct_dying_cpu(unsigned int cpu)
return 0;
}
-static int __init exynos4_timer_resources(struct mct_context *ctx,
+static int __init_or_module exynos4_timer_resources(struct mct_context *ctx,
struct device_node *np)
{
struct clk *mct_clk, *tick_clk;
@@ -549,7 +554,7 @@ static int __init exynos4_timer_resources(struct mct_context *ctx,
* @local_idx: array mapping CPU numbers to local timer indices
* @nr_local: size of @local_idx array
*/
-static int __init exynos4_timer_interrupts(struct mct_context *ctx,
+static int __init_or_module exynos4_timer_interrupts(struct mct_context *ctx,
struct device_node *np,
const u32 *local_idx,
size_t nr_local)
@@ -662,7 +667,7 @@ static int __init exynos4_timer_interrupts(struct mct_context *ctx,
return err;
}
-static int __init mct_init_dt(struct mct_context *ctx, struct device_node *np)
+static int __init_or_module mct_init_dt(struct mct_context *ctx, struct device_node *np)
{
bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
u32 local_idx[MCT_NR_LOCAL] = {0};
@@ -722,7 +727,9 @@ static const struct of_device_id exynos4_mct_match_table[] = {
{ .compatible = "samsung,exynos4412-mct", .data = &exynos4412_mct_data, },
{}
};
+MODULE_DEVICE_TABLE(of, exynos4_mct_match_table);
+#if defined(CONFIG_ARM)
/* Note, legacy ARM 32-bit systems depend on the MCT as the only clocksource
* which requires this driver to be initialized very early. We need to keep this
* special condition until we can transparently support modular and early init
@@ -748,13 +755,11 @@ static int __init mct_of_declare_init(struct device_node *np)
if (ret)
goto out_ctx;
-#if defined(CONFIG_ARM)
sched_clock_register(exynos4_read_sched_clock, 32, ctx->clk_rate);
exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer;
exynos4_delay_timer.freq = ctx->clk_rate;
register_current_timer_delay(&exynos4_delay_timer);
-#endif
return 0;
@@ -764,3 +769,37 @@ static int __init mct_of_declare_init(struct device_node *np)
}
TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_of_declare_init);
TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_of_declare_init);
+#else
+static int exynos4_mct_probe(struct platform_device *pdev)
+{
+ struct mct_context *ctx;
+ struct device *dev = &pdev->dev;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->drvdata = of_device_get_match_data(dev);
+ if (!ctx->drvdata)
+ return -EINVAL;
+
+ return mct_init_dt(ctx, dev->of_node);
+}
+
+static struct platform_driver exynos4_mct_driver = {
+ .probe = exynos4_mct_probe,
+ .driver = {
+ .name = "exynos-mct",
+ .of_match_table = exynos4_mct_match_table,
+ },
+};
+
+static int __init 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");
+#endif /* CONFIG_ARM */
--
2.52.0.223.gf5cc29aaa4-goog
next prev parent reply other threads:[~2025-12-05 1:10 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20251205011037eucas1p2bfaec27d78550b53099ebb0ca8713b2f@eucas1p2.samsung.com>
2025-12-05 1:10 ` [PATCH v7 0/6] Add module support for Arm64 Exynos MCT driver Will McVicker
2025-12-05 1:10 ` [PATCH v7 1/6] clocksource/drivers/exynos_mct: Don't register as a sched_clock on arm64 Will McVicker
2025-12-05 1:10 ` [PATCH v7 2/6] clocksource/drivers/exynos_mct: Set percpu local timer interrupts for ARM64 Will McVicker
2025-12-05 1:10 ` [PATCH v7 3/6] clocksource/drivers/exynos_mct: Fix uninitialized irq name warning Will McVicker
2025-12-05 1:10 ` [PATCH v7 4/6] clocksource/drivers/exynos_mct: Refactor driver init Will McVicker
2025-12-05 1:10 ` Will McVicker [this message]
2025-12-05 23:27 ` [PATCH v7 5/6] clocksource/drivers/exynos_mct: Add module support for ARM64 kernel test robot
2025-12-07 8:42 ` kernel test robot
2025-12-05 1:10 ` [PATCH v7 6/6] arm64: exynos: Drop select CLKSRC_EXYNOS_MCT Will McVicker
2025-12-05 9:55 ` [PATCH v7 0/6] Add module support for Arm64 Exynos MCT driver Marek Szyprowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251205011027.720512-6-willmcvicker@google.com \
--to=willmcvicker@google.com \
--cc=alim.akhtar@samsung.com \
--cc=andre.draszik@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=daniel.lezcano@linaro.org \
--cc=hoony.yu@samsung.com \
--cc=jstultz@google.com \
--cc=kernel-team@android.com \
--cc=krzk@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=m.szyprowski@samsung.com \
--cc=peter.griffin@linaro.org \
--cc=robh@kernel.org \
--cc=tglx@linutronix.de \
--cc=tudor.ambarus@linaro.org \
--cc=will@kernel.org \
--cc=youngmin.nam@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.