[PATCH 13/13] clk: amlogic: Add support for building as combined kernel module

Chuan Liu via B4 Relay
2026-02-09T05:49:27Z

From: Chuan Liu <chuan.liu@amlogic.com>

Some use cases require clock drivers to be built as kernel modules
and loaded using insmod after system initialization. This patch combines
multiple clock drivers into a single module to reduce system call
overhead caused by multiple insmod invocations during boot process.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
---
drivers/clk/amlogic/Kconfig | 17 ++++++------
drivers/clk/amlogic/Makefile | 1 +
drivers/clk/amlogic/a9-misc-ccu.c | 12 ++++++++-
drivers/clk/amlogic/a9-model-ccu.c | 12 ++++++++-
drivers/clk/amlogic/a9-pll.c | 12 ++++++++-
drivers/clk/amlogic/clk-module.c | 42 ++++++++++++++++++++++++++++++
drivers/clk/amlogic/clk-module.h | 53 ++++++++++++++++++++++++++++++++++++++
7 files changed, 138 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/amlogic/Kconfig b/drivers/clk/amlogic/Kconfig
index 502aca5332bc..1b60725b80d8 100644
--- a/drivers/clk/amlogic/Kconfig
+++ b/drivers/clk/amlogic/Kconfig
@@ -9,7 +9,7 @@ config COMMON_CLK_AMLOGIC
help
This driver provides the basic clock infrastructure for Amlogic SoCs,
offering read and write interfaces for various clock control units.
- Select Y if your target SoC needs clock driver support.
+ Select M or Y if your target SoC needs clock driver support.

config COMMON_CLK_AMLOGIC_MISC
tristate "Amlogic Misc Clock Control Units"
@@ -17,8 +17,8 @@ config COMMON_CLK_AMLOGIC_MISC
help
Supports non-standard module clock control units in Amlogic SoC clock
trees, such as sc-ccu (for smart card controller) and ts-ccu (for
- temperature sensor). Select Y if the current SoC contains these module
- clock control units.
+ temperature sensor). Select M or Y if the current SoC contains these
+ module clock control units.

config COMMON_CLK_AMLOGIC_MODEL
tristate "Amlogic Standardized Model Clock Control Units"
@@ -27,8 +27,8 @@ config COMMON_CLK_AMLOGIC_MODEL
Supports standardized model clock control units commonly used in Amlogic
SoC clock trees, such as composite-ccu, noglitch-ccu, and sysbus-ccu.
Most peripheral clock controllers in Amlogic SoCs are composed of
- these models. Select Y if the current SoC contains these clock control
- unit models.
+ these models. Select M or Y if the current SoC contains these clock
+ control unit models.

config COMMON_CLK_AMLOGIC_PLL
tristate "Amlogic PLL Controller"
@@ -36,8 +36,8 @@ config COMMON_CLK_AMLOGIC_PLL
help
Supports PLL controller used in Amlogic SoCs. The PLL supports dynamic
configuration of output clock frequency, enabling flexible frequency
- settings to provide clocks for other modules. Select Y if the current
- SoC contains PLLs.
+ settings to provide clocks for other modules. Select M or Y if the
+ current SoC contains PLLs.

config COMMON_CLK_AMLOGIC_A9
tristate "Amlogic A9 Family Clock Controller"
@@ -48,4 +48,5 @@ config COMMON_CLK_AMLOGIC_A9
select COMMON_CLK_AMLOGIC_PLL
help
Support for the clock controller present on the Amlogic A9 family
- SoCs. Select Y if A9 family SoC needs to support clock controller.
+ SoCs. Select M or Y if A9 family SoC needs to support clock
+ controller.
diff --git a/drivers/clk/amlogic/Makefile b/drivers/clk/amlogic/Makefile
index b174dce61ae9..2778d3859a5e 100644
--- a/drivers/clk/amlogic/Makefile
+++ b/drivers/clk/amlogic/Makefile
@@ -8,6 +8,7 @@ clk-amlogic-y += clk-composite.o
clk-amlogic-y += clk-dualdiv.o
clk-amlogic-y += clk-noglitch.o
clk-amlogic-y += clk-pll.o
+clk-amlogic-y += clk-module.o

ifneq ($(CONFIG_COMMON_CLK_AMLOGIC_MISC),)
clk-amlogic-y += a9-misc-ccu.o
diff --git a/drivers/clk/amlogic/a9-misc-ccu.c b/drivers/clk/amlogic/a9-misc-ccu.c
index db130d84ccdd..6fd2c9ae3cd0 100644
--- a/drivers/clk/amlogic/a9-misc-ccu.c
+++ b/drivers/clk/amlogic/a9-misc-ccu.c
@@ -10,6 +10,7 @@
#include "clk-basic.h"
#include "clk-composite.h"
#include "clk-dualdiv.h"
+#include "clk-module.h"
#include "clk-noglitch.h"
#include "clk-pll.h"

@@ -952,7 +953,16 @@ static struct platform_driver of_aml_clk_misc_driver = {
.of_match_table = of_aml_clk_misc_match_table,
},
};
-module_platform_driver(of_aml_clk_misc_driver);
+
+int __init aml_clk_misc_driver_init(void)
+{
+ return platform_driver_register(&of_aml_clk_misc_driver);
+}
+
+void __exit aml_clk_misc_driver_exit(void)
+{
+ platform_driver_unregister(&of_aml_clk_misc_driver);
+}

MODULE_DESCRIPTION("Amlogic A9 Misc Clock Control Units Driver");
MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
diff --git a/drivers/clk/amlogic/a9-model-ccu.c b/drivers/clk/amlogic/a9-model-ccu.c
index 5d5bf1538f73..58babd42aca3 100644
--- a/drivers/clk/amlogic/a9-model-ccu.c
+++ b/drivers/clk/amlogic/a9-model-ccu.c
@@ -9,6 +9,7 @@
#include "clk.h"
#include "clk-basic.h"
#include "clk-composite.h"
+#include "clk-module.h"
#include "clk-noglitch.h"

/*
@@ -457,7 +458,16 @@ static struct platform_driver of_aml_clk_model_driver = {
.of_match_table = of_aml_clk_model_match_table,
},
};
-module_platform_driver(of_aml_clk_model_driver);
+
+int __init aml_clk_model_driver_init(void)
+{
+ return platform_driver_register(&of_aml_clk_model_driver);
+}
+
+void __exit aml_clk_model_driver_exit(void)
+{
+ platform_driver_unregister(&of_aml_clk_model_driver);
+}

MODULE_DESCRIPTION("Amlogic A9 Standardized Model Clock Control Units Driver");
MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
diff --git a/drivers/clk/amlogic/a9-pll.c b/drivers/clk/amlogic/a9-pll.c
index c4c695caa8ed..fe2a77382509 100644
--- a/drivers/clk/amlogic/a9-pll.c
+++ b/drivers/clk/amlogic/a9-pll.c
@@ -7,6 +7,7 @@
#include <linux/module.h>

#include "clk.h"
+#include "clk-module.h"
#include "clk-pll.h"

static const struct aml_pll_data a9_mclk_pll_data = {
@@ -138,7 +139,16 @@ static struct platform_driver of_aml_clk_pll_driver = {
.of_match_table = of_aml_clk_pll_match_table,
},
};
-module_platform_driver(of_aml_clk_pll_driver);
+
+int __init aml_pll_driver_init(void)
+{
+ return platform_driver_register(&of_aml_clk_pll_driver);
+}
+
+void __exit aml_pll_driver_exit(void)
+{
+ platform_driver_unregister(&of_aml_clk_pll_driver);
+}

MODULE_DESCRIPTION("Amlogic A9 PLL Controllers Driver");
MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
diff --git a/drivers/clk/amlogic/clk-module.c b/drivers/clk/amlogic/clk-module.c
new file mode 100644
index 000000000000..506926c1f908
--- /dev/null
+++ b/drivers/clk/amlogic/clk-module.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (c) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <linux/module.h>
+
+#include "clk-module.h"
+
+static int __init aml_clk_driver_init(void)
+{
+ int ret;
+
+ ret = aml_pll_driver_init();
+ if (ret)
+ return ret;
+
+ ret = aml_clk_model_driver_init();
+ if (ret)
+ return ret;
+
+ ret = aml_clk_misc_driver_init();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void __exit aml_clk_driver_exit(void)
+{
+ aml_clk_misc_driver_exit();
+ aml_clk_model_driver_exit();
+ aml_pll_driver_exit();
+}
+
+module_init(aml_clk_driver_init);
+module_exit(aml_clk_driver_exit);
+
+MODULE_DESCRIPTION("Amlogic Clock Controllers Driver Register");
+MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_AMLOGIC");
diff --git a/drivers/clk/amlogic/clk-module.h b/drivers/clk/amlogic/clk-module.h
new file mode 100644
index 000000000000..6091a50803df
--- /dev/null
+++ b/drivers/clk/amlogic/clk-module.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#ifndef __AML_CLK_MODULE_H
+#define __AML_CLK_MODULE_H
+
+#include <linux/kconfig.h>
+
+#if IS_ENABLED(CONFIG_COMMON_CLK_AMLOGIC_PLL)
+extern int aml_pll_driver_init(void);
+extern void aml_pll_driver_exit(void);
+#else /* CONFIG_COMMON_CLK_AMLOGIC_PLL */
+static inline int aml_pll_driver_init(void)
+{
+ return 0;
+}
+
+static inline void aml_pll_driver_exit(void)
+{
+}
+#endif /* CONFIG_COMMON_CLK_AMLOGIC_PLL */
+
+#if IS_ENABLED(CONFIG_COMMON_CLK_AMLOGIC_MODEL)
+extern int aml_clk_model_driver_init(void);
+extern void aml_clk_model_driver_exit(void);
+#else /* CONFIG_COMMON_CLK_AMLOGIC_MODEL */
+static inline int aml_clk_model_driver_init(void)
+{
+ return 0;
+}
+
+static inline void aml_clk_model_driver_exit(void)
+{
+}
+#endif /* CONFIG_COMMON_CLK_AMLOGIC_MODEL */
+
+#if IS_ENABLED(CONFIG_COMMON_CLK_AMLOGIC_MISC)
+extern int aml_clk_misc_driver_init(void);
+extern void aml_clk_misc_driver_exit(void);
+#else /* CONFIG_COMMON_CLK_AMLOGIC_MISC */
+static inline int aml_clk_misc_driver_init(void)
+{
+ return 0;
+}
+
+static inline void aml_clk_misc_driver_exit(void)
+{
+}
+#endif /* CONFIG_COMMON_CLK_AMLOGIC_MISC */
+
+#endif /* __AML_CLK_MODULE_H */

--
2.42.0