Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
From: Tudor Ambarus <tudor.ambarus@linaro.org>
Date: 2025-08-25 12:28:19
Also in:
linux-clk, linux-devicetree, linux-samsung-soc, lkml
On 8/24/25 6:10 PM, Krzysztof Kozlowski wrote:
On 19/08/2025 13:45, Tudor Ambarus wrote:quoted
+ +static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct acpm_clk *clk = to_acpm_clk(hw); + + return clk->handle->ops.dvfs_ops.set_rate(clk->handle, + clk->acpm_chan_id, clk->id, rate); +} + +static const struct clk_ops acpm_clk_ops = { + .recalc_rate = acpm_clk_recalc_rate, + .round_rate = acpm_clk_round_rate,This should be determine_rate. Check recent patchset from Brian Masney. I applied the samsung bits from it to samsung soc tree.
Will do.
...quoted
+ +static int __init acpm_clk_probe(struct platform_device *pdev)module probe for sure should not be __init.
Ah, indeed, both __init and __refdata are wrong here, my appologies. I assume they came from the time I considered the driver only needed at boot time. Will drop them.
quoted
+{ + const struct acpm_clk_match_data *match_data; + const struct acpm_handle *acpm_handle; + struct clk_hw_onecell_data *clk_data; + struct clk_hw **hws; + struct device *dev = &pdev->dev; + struct acpm_clk *aclks; + unsigned int acpm_chan_id; + int i, err, count; + + acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node); + if (IS_ERR(acpm_handle)) + return dev_err_probe(dev, PTR_ERR(acpm_handle), + "Failed to get acpm handle.\n"); + + match_data = of_device_get_match_data(dev); + if (!match_data) + return dev_err_probe(dev, -EINVAL, + "Failed to get match data.\n"); + + count = match_data->nr_clks; + acpm_chan_id = match_data->acpm_chan_id; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = count; + hws = clk_data->hws; + + aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL); + if (!aclks) + return -ENOMEM; + + for (i = 0; i < count; i++) { + const struct acpm_clk_variant *variant = &match_data->clks[i]; + struct acpm_clk *aclk = &aclks[i]; + + hws[i] = &aclk->hw; + + aclk->id = variant->id; + aclk->handle = acpm_handle; + aclk->acpm_chan_id = acpm_chan_id; + + err = acpm_clk_ops_init(dev, aclk, variant->name); + if (err) + return dev_err_probe(dev, err, + "Failed to register clock.\n"); + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + clk_data); +} + +#define ACPM_CLK(_id, cname) \ + { \ + .id = _id, \ + .name = cname, \ + } + +static const struct acpm_clk_variant gs101_acpm_clks[] __initconst = {This goes to top of the file, after struct declarations.
Okay, will do.
quoted
+ ACPM_CLK(CLK_ACPM_DVFS_MIF, "mif"), + ACPM_CLK(CLK_ACPM_DVFS_INT, "int"), + ACPM_CLK(CLK_ACPM_DVFS_CPUCL0, "cpucl0"), + ACPM_CLK(CLK_ACPM_DVFS_CPUCL1, "cpucl1"), + ACPM_CLK(CLK_ACPM_DVFS_CPUCL2, "cpucl2"), + ACPM_CLK(CLK_ACPM_DVFS_G3D, "g3d"), + ACPM_CLK(CLK_ACPM_DVFS_G3DL2, "g3dl2"), + ACPM_CLK(CLK_ACPM_DVFS_TPU, "tpu"), + ACPM_CLK(CLK_ACPM_DVFS_INTCAM, "intcam"), + ACPM_CLK(CLK_ACPM_DVFS_TNR, "tnr"), + ACPM_CLK(CLK_ACPM_DVFS_CAM, "cam"), + ACPM_CLK(CLK_ACPM_DVFS_MFC, "mfc"), + ACPM_CLK(CLK_ACPM_DVFS_DISP, "disp"), + ACPM_CLK(CLK_ACPM_DVFS_BO, "b0"), +}; + +static const struct acpm_clk_match_data acpm_clk_gs101 __initconst = {Are you going to have more of such clk_match_data? More variants?
I see downstream that gs101 and gs201 have the same clock IDs, clock names and acpm_chan_id. But I can't tell about others. I assume it's safer to assume there will be other variants. Anyway, I'll pass this as platform data, if I understood correctly. Thanks, ta
quoted
+ .clks = gs101_acpm_clks, + .nr_clks = ARRAY_SIZE(gs101_acpm_clks), + .acpm_chan_id = 0, +}; +