summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-30 06:18:43 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-30 06:18:43 -1000
commit4517b5a6c8745f244d89971dc34ec69f5a9eb3d5 (patch)
treeb2fb15a433115d3b1de979c67a7756f28291bf77 /include/linux
parentd89e1d186ec9271bf78e62771779e9fc03bf0fc3 (diff)
parent0d9678b125d8315d62de1261bee67c7e6f21457e (diff)
downloadlinux-4517b5a6c8745f244d89971dc34ec69f5a9eb3d5.tar.gz
linux-4517b5a6c8745f244d89971dc34ec69f5a9eb3d5.zip
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "Here's the clk changes for the merge window which is dominated in the diffstat by Qualcomm churning out new SoCs that need clk drivers. Looking beyond the sheer amount of lines of mostly data there we have a clk nexus DT binding change in the core clk framework and a driver core patch to add a subsys driver macro. The clock nexus support is useful for devices that map clks internally or for connectors on a board that route clock signals to another board. I suspect the use of this will expand in the future, so we have unit tests to make sure it doesn't break. The driver core change adds subsys_driver() and subsys_platform_driver() so we can register early drivers without open-coding that all (module_platform_driver() is at device initcall level so it isn't be used). Beyond the core framework bits we have lots of changes all over the tree to initialize 'struct clk_init_data'. The potential risk here is that someone forgets to initialize all the members of that structure and either the clk flags cause weird behavior later on or the parents are pointing at junk and the clk is orphaned forever. The patches just initialize the thing with zeroes to be safe. Longer term we should probably move this struct out of 'struct clk_hw' and pass it during clk registration time. That's a much bigger change and would require restructuring entire drivers that rely on the pointer being there. Finally, we have the usual fixes like calculation updates for dividers, handling error paths during clk registration, or fixing clk data now that drivers are using them. Those patches are dwarfed by the amount of new SoC support and only affect those SoCs and the consumers of those clks. Overall I'm more concerned the clk_init_data patches are going to expose some latent bugs that we didn't notice before because something was relying on clks being orphaned and now they're not. Core: - subsys_driver() / subsys_platform_driver() macros - Clock nexus DT binding support (with KUnit tests) - Spread-spectrum configuration validation - Fully initialize struct clk_init_data across many drivers New Drivers: - Anlogic DR1V90 CRU - ZTE zx297520v3 top, matrix, and LSP clocks - Samsung Exynos5515 and ACPM driver extended to Exynos850. - Qualcomm Eliza camera, camera-BIST, GPU, and video clks - Qualcomm Hawi / Maili camera and GPU controllers - Qualcomm Kuno global, RPMh - Qualcomm MSM8952 global, RPM - Qualcomm Nord camera/video clocks, EMAC interconnect, PHY resets - Qualcomm IPQ5210 / IPQ9650 network clocks - i.MX93 350 MHz fractional-N GP-PLL for display - i.MX pll14xx spread-spectrum clock generation - Amlogic A9 SCMI clock controller - Allwinner single-divider "update bit" support - EN7523 Serdes port selection" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (316 commits) clk: imx: pll14xx: support spread spectrum clock generation clk: cdce925: Size the PLL child name buffer for any int clk: stm32: fix clock array size for STM32MP21 dt-bindings: clock: Convert HiSilicon clocks to DT schema clk: lmk04832: Handle reset GPIO lookup errors dt-bindings: clock: anlogic,dr1v90-cru: make external clocks optional clk: tegra: bpmp: remove kcalloc clk: mmp2-audio: add missing PM_CLK dependency clk: zte: Introduce a driver for zx297520v3 LSP clocks clk: zte: Introduce a driver for zx297520v3 matrix clocks clk: zte: Introduce a driver for zx297520v3 top clocks clk: zte: Add zx PLL support infrastructure clk: zte: Add regmap-based clocks clk: zte: Add Clock registration infrastructure dt-bindings: clk: zte: Add zx297520v3 LSP clock and reset controller dt-bindings: clk: zte: Add zx297520v3 matrix clock and reset controller dt-bindings: clk: zte: Add zx297520v3 top clock and reset controller clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/clk-provider.h25
-rw-r--r--include/linux/clk/tegra.h2
-rw-r--r--include/linux/clk/ti.h2
-rw-r--r--include/linux/device/driver.h31
-rw-r--r--include/linux/platform_device.h30
5 files changed, 84 insertions, 6 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index dc8e161f9c2c..a355d1ee5189 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -7,6 +7,7 @@
#define __LINUX_CLK_PROVIDER_H
#include <dt-bindings/clock/clock.h>
+#include <linux/bits.h>
#include <linux/of.h>
#include <linux/of_clk.h>
@@ -50,6 +51,7 @@ struct clk;
struct clk_hw;
struct clk_core;
struct dentry;
+struct module;
/**
* struct clk_rate_request - Structure encoding the clk constraints that
@@ -351,8 +353,9 @@ struct clk_init_data {
* @core: pointer to the struct clk_core instance that points back to this
* struct clk_hw instance
*
- * @clk: pointer to the per-user struct clk instance that can be used to call
- * into the clk API
+ * @clk: pointer to the per-user struct clk instance. This will be removed at
+ * some point in the future, Please consider the field obsolete and do not use
+ * it. Use clk_hw_get_clk() to get a per-user struct clk from a struct clk_hw.
*
* @init: pointer to struct clk_init_data that contains the init data shared
* with the common clock framework. This pointer will be set to NULL once
@@ -755,7 +758,7 @@ struct clk_divider {
spinlock_t *lock;
};
-#define clk_div_mask(width) ((1 << (width)) - 1)
+#define clk_div_mask(width) GENMASK((width) - 1, 0)
#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
#define CLK_DIVIDER_ONE_BASED BIT(0)
@@ -1474,10 +1477,24 @@ static inline struct clk_hw *__clk_get_hw(struct clk *clk)
}
#endif
-struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id);
+struct clk *__clk_hw_get_clk(struct clk_hw *hw, const char *con_id,
+ struct module *owner);
struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw,
const char *con_id);
+/**
+ * clk_hw_get_clk - get clk consumer given a clk_hw
+ * @hw: clk_hw associated with the clk being consumed
+ * @con_id: connection ID string on device
+ *
+ * Return: new clk consumer
+ * This is the function to be used by providers which need
+ * to get a consumer clk and act on the clock element
+ * Calls to this function must be balanced with calls to clk_put()
+ */
+#define clk_hw_get_clk(hw, con_id) \
+ __clk_hw_get_clk((hw), (con_id), THIS_MODULE)
+
unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index 3650e926e93f..f1034e14c1a4 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -170,7 +170,7 @@ struct tegra210_clk_emc_provider {
struct module *owner;
struct device *dev;
- struct tegra210_clk_emc_config *configs;
+ struct tegra210_clk_emc_config *configs __counted_by_ptr(num_configs);
unsigned int num_configs;
int (*set_rate)(struct device *dev,
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 54a3fa370004..61c4abf19995 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -51,7 +51,7 @@ struct clk_omap_reg {
* @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
* @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
* @dcc_mask: mask of the DPLL DCC correction bitfield @mult_div1_reg
- * @dcc_rate: rate atleast which DCC @dcc_mask must be set
+ * @dcc_rate: rate at least which DCC @dcc_mask must be set
* @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
* @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg
* @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index 768a1334c0a1..29fbc01ef06f 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -297,4 +297,35 @@ static int __init __driver##_init(void) \
} \
device_initcall(__driver##_init);
+/**
+ * subsys_driver() - Helper macro for drivers that don't do anything special
+ * in init/exit but have to register earlier, at subsys_initcall level, when
+ * built in. This eliminates a lot of boilerplate. Each driver may only use
+ * this macro once, and calling it replaces the init/exit boilerplate.
+ *
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ * @...: Additional arguments to be passed to __register and __unregister.
+ *
+ * This is meant to be a direct parallel of module_driver() above, but with
+ * the init call promoted to subsys_initcall() for built-in drivers so they
+ * are available earlier during boot. When built as a module subsys_initcall()
+ * collapses to module_init() and the normal module init/exit paths are used.
+ *
+ * Use this macro to construct bus specific macros for registering drivers,
+ * and do not use it on its own.
+ */
+#define subsys_driver(__driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+ return __register(&(__driver), ##__VA_ARGS__); \
+} \
+subsys_initcall(__driver##_init) \
+static void __exit __driver##_exit(void) \
+{ \
+ __unregister(&(__driver), ##__VA_ARGS__); \
+} \
+module_exit(__driver##_exit)
+
#endif /* _DEVICE_DRIVER_H_ */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 3d5bbcbae730..3bd0f1f0d870 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -344,6 +344,19 @@ static inline void platform_set_drvdata(struct platform_device *pdev,
#define builtin_platform_driver(__platform_driver) \
builtin_driver(__platform_driver, platform_driver_register)
+/*
+ * subsys_platform_driver() - Helper macro for drivers that don't do anything
+ * special in module init/exit but need to register earlier, at
+ * subsys_initcall level, when built in. This eliminates a lot of
+ * boilerplate. Each driver may only use this macro once, and calling it
+ * replaces module_init() and module_exit(). This is meant to be a parallel
+ * of module_platform_driver() above, but with the init call promoted to
+ * subsys_initcall() so built-in providers are available earlier during boot.
+ */
+#define subsys_platform_driver(__platform_driver) \
+ subsys_driver(__platform_driver, platform_driver_register, \
+ platform_driver_unregister)
+
/* module_platform_driver_probe() - Helper macro for drivers that don't do
* anything special in module init/exit. This eliminates a lot of
* boilerplate. Each module may only use this macro once, and
@@ -376,6 +389,23 @@ static int __init __platform_driver##_init(void) \
} \
device_initcall(__platform_driver##_init); \
+/*
+ * subsys_platform_driver_probe() - Helper macro for drivers that don't do
+ * anything special in device init and have no exit, but need to register
+ * earlier, at subsys_initcall level. This eliminates some boilerplate. Each
+ * driver may only use this macro once, and using it replaces subsys_initcall.
+ * This is meant to be a parallel of builtin_platform_driver_probe above, but
+ * with the init call promoted to subsys_initcall so the provider is available
+ * earlier during boot.
+ */
+#define subsys_platform_driver_probe(__platform_driver, __platform_probe) \
+static int __init __platform_driver##_init(void) \
+{ \
+ return platform_driver_probe(&(__platform_driver), \
+ __platform_probe); \
+} \
+subsys_initcall(__platform_driver##_init) \
+
#define platform_create_bundle(driver, probe, res, n_res, data, size) \
__platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME)
extern struct platform_device *__platform_create_bundle(