diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-30 06:18:43 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-30 06:18:43 -1000 |
| commit | 4517b5a6c8745f244d89971dc34ec69f5a9eb3d5 (patch) | |
| tree | b2fb15a433115d3b1de979c67a7756f28291bf77 /include/linux | |
| parent | d89e1d186ec9271bf78e62771779e9fc03bf0fc3 (diff) | |
| parent | 0d9678b125d8315d62de1261bee67c7e6f21457e (diff) | |
| download | linux-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.h | 25 | ||||
| -rw-r--r-- | include/linux/clk/tegra.h | 2 | ||||
| -rw-r--r-- | include/linux/clk/ti.h | 2 | ||||
| -rw-r--r-- | include/linux/device/driver.h | 31 | ||||
| -rw-r--r-- | include/linux/platform_device.h | 30 |
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( |
