]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
clk: microchip: mpfs-ccc: fix peripheral driver registration failures after oob fix
authorConor Dooley <conor.dooley@microchip.com>
Thu, 30 Apr 2026 18:30:28 +0000 (19:30 +0100)
committerConor Dooley <conor.dooley@microchip.com>
Wed, 20 May 2026 15:51:28 +0000 (16:51 +0100)
Commit 2f7ae8ab6aa73 ("clk: microchip: mpfs-ccc: fix out of bounds
access during output registration") fixed the out of bounds access, but
it did so by packing sparse indices into a linear space. When
peripheral drivers request clocks, they obviously don't care for this
compression and use the sparse indices, and therefore try to request the
wrong clocks or clocks that don't exist.

The most straightforward fix here seems to stop being clever with the
packing and just overallocate the array.

Fixes: 2f7ae8ab6aa73 ("clk: microchip: mpfs-ccc: fix out of bounds access during output registration")
Fixes: d39fb172760e ("clk: microchip: add PolarFire SoC fabric clock support")
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
drivers/clk/microchip/clk-mpfs-ccc.c

index 0a76a1aaa50f7f3950057d99ddab0ae7a040dc7c..40c17593e5941dd011953945670c00249d864484 100644 (file)
@@ -32,6 +32,7 @@
 #define MPFS_CCC_FIXED_DIV             4
 #define MPFS_CCC_OUTPUTS_PER_PLL       4
 #define MPFS_CCC_REFS_PER_PLL          2
+#define MPFS_CCC_NUM_CLKS              16
 
 struct mpfs_ccc_data {
        void __iomem **pll_base;
@@ -178,7 +179,7 @@ static int mpfs_ccc_register_outputs(struct device *dev, struct mpfs_ccc_out_hw_
                        return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
                                             out_hw->id);
 
-               data->hw_data.hws[out_hw->id - 2] = &out_hw->divider.hw;
+               data->hw_data.hws[out_hw->id] = &out_hw->divider.hw;
        }
 
        return 0;
@@ -231,17 +232,9 @@ static int mpfs_ccc_probe(struct platform_device *pdev)
 {
        struct mpfs_ccc_data *clk_data;
        void __iomem *pll_base[ARRAY_SIZE(mpfs_ccc_pll_clks)];
-       unsigned int num_clks;
        int ret;
 
-       /*
-        * If DLLs get added here, mpfs_ccc_register_outputs() currently packs
-        * sparse clock IDs in the hws array
-        */
-       num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
-                  ARRAY_SIZE(mpfs_ccc_pll1out_clks);
-
-       clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hw_data.hws, num_clks),
+       clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hw_data.hws, MPFS_CCC_NUM_CLKS),
                                GFP_KERNEL);
        if (!clk_data)
                return -ENOMEM;
@@ -255,7 +248,7 @@ static int mpfs_ccc_probe(struct platform_device *pdev)
                return PTR_ERR(pll_base[1]);
 
        clk_data->pll_base = pll_base;
-       clk_data->hw_data.num = num_clks;
+       clk_data->hw_data.num = MPFS_CCC_NUM_CLKS;
        clk_data->dev = &pdev->dev;
 
        ret = mpfs_ccc_register_plls(clk_data->dev, mpfs_ccc_pll_clks,