From 370da75066e32bef008ca17290f4aa644500100c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 16 Apr 2023 12:00:04 -0300 Subject: clk: imx: imx6sx: Remove CLK_SET_RATE_PARENT from the LDB clocks On the i.MX6SX, it is common to use the LDB and LCDIF with the same parent clock, such as the IMX6SX_CLK_PLL5_VIDEO_DIV, for example. Due to the CLK_SET_RATE_PARENT flag, the LDB clock would try to set the clock parent rate, which can mess with the required clock rate calculated from the eLCDIF driver. To prevent this problem, remove the CLK_SET_RATE_PARENT flag from the LDB clocks, so that a correct clock relationship can be achieved. Signed-off-by: Fabio Estevam Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20230416150004.16834-1-festevam@gmail.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx6sx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index 7cf86707bc39..3f1502933e59 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -302,10 +302,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) hws[IMX6SX_CLK_CKO2_SEL] = imx_clk_hw_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); hws[IMX6SX_CLK_CKO] = imx_clk_hw_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); - hws[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT); - hws[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT); - hws[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_hw_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT); - hws[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_hw_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT); + hws[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); + hws[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); + hws[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_hw_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels)); + hws[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_hw_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); hws[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_hw_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT); hws[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_hw_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT); -- cgit v1.2.3 From 912d7af473f163ccdeb02aaabc3534177936b86c Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 21 Apr 2023 13:55:17 +0200 Subject: clk: imx6ul: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Alexander Stein Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20230421115517.1940990-1-alexander.stein@ew.tq-group.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx6ul.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index e3696a88b5a3..f9394e94f69d 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -544,6 +544,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk); clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk); + + imx_register_uart_clocks(); } CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init); -- cgit v1.2.3 From 6077af232cf58bfa4203c2364f99e0218aac7667 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 6 May 2023 17:08:56 +0800 Subject: clk: imx: drop imx_unregister_clocks There is no user using imx_unregister_clocks, so drop it. Signed-off-by: Peng Fan Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20230506090856.3599035-1-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk.c | 8 -------- drivers/clk/imx/clk.h | 1 - 2 files changed, 9 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 19cde59a20cb..e35496af5ceb 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -20,14 +20,6 @@ EXPORT_SYMBOL_GPL(imx_ccm_lock); bool mcore_booted; EXPORT_SYMBOL_GPL(mcore_booted); -void imx_unregister_clocks(struct clk *clks[], unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) - clk_unregister(clks[i]); -} - void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count) { unsigned int i; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 1031468701d7..af19d9f6aed0 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -19,7 +19,6 @@ static inline void imx_register_uart_clocks(void) } #endif void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); -void imx_unregister_clocks(struct clk *clks[], unsigned int count); void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count); extern void imx_cscmr1_fixup(u32 *val); -- cgit v1.2.3 From 632c60ecd25dbacee54d5581fe3aeb834b57010a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 19 Apr 2023 17:23:01 +0300 Subject: clk: imx: scu: use _safe list iterator to avoid a use after free This loop is freeing "clk" so it needs to use list_for_each_entry_safe(). Otherwise it dereferences a freed variable to get the next item on the loop. Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support") Signed-off-by: Dan Carpenter Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/0793fbd1-d2b5-4ec2-9403-3c39343a3e2d@kili.mountain Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-scu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 1e6870f3671f..db307890e4c1 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -707,11 +707,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, void imx_clk_scu_unregister(void) { - struct imx_scu_clk_node *clk; + struct imx_scu_clk_node *clk, *n; int i; for (i = 0; i < IMX_SC_R_LAST; i++) { - list_for_each_entry(clk, &imx_scu_clks[i], node) { + list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) { clk_hw_unregister(clk->hw); kfree(clk); } -- cgit v1.2.3 From f3e788d9ec71c4efbe220fe2ca46368602b698f6 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Thu, 9 Mar 2023 20:44:48 +0000 Subject: clk: microchip: convert SOC_MICROCHIP_POLARFIRE to ARCH_MICROCHIP_POLARFIRE As part of converting RISC-V SOC_FOO symbols to ARCH_FOO to match the use of such symbols on other architectures, convert the Microchip FPGA clock drivers to use the new symbol. Signed-off-by: Conor Dooley Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230309204452.969574-2-conor@kernel.org --- drivers/clk/microchip/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index e33e51978938..0724ce65898f 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -5,8 +5,8 @@ config COMMON_CLK_PIC32 config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" - depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST - default SOC_MICROCHIP_POLARFIRE + depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST + default ARCH_MICROCHIP_POLARFIRE select AUXILIARY_BUS help Supports Clock Configuration for PolarFire SoC -- cgit v1.2.3 From a31988510689e6116921d6c67521c6cf472737f6 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 10 Mar 2023 08:47:01 -0600 Subject: clk: microchip: Use of_property_read_bool() for boolean properties It is preferred to use typed property access functions (i.e. of_property_read_ functions) rather than low-level of_get_property/of_find_property functions for reading properties. Convert reading boolean properties to to of_property_read_bool(). Signed-off-by: Rob Herring Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230310144701.1541573-1-robh@kernel.org --- drivers/clk/microchip/clk-pic32mzda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/microchip/clk-pic32mzda.c b/drivers/clk/microchip/clk-pic32mzda.c index b72c76f9ecd1..eabfc4931fe9 100644 --- a/drivers/clk/microchip/clk-pic32mzda.c +++ b/drivers/clk/microchip/clk-pic32mzda.c @@ -184,7 +184,7 @@ static int pic32mzda_clk_probe(struct platform_device *pdev) clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL, 0, 24000000); /* fixed rate (optional) clock */ - if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) { + if (of_property_read_bool(np, "microchip,pic32mzda-sosc")) { pr_info("pic32-clk: dt requests SOSC.\n"); clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core); } -- cgit v1.2.3 From 8208181fe536bba3b411508f81c4426fc9c71d9a Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 6 May 2023 14:53:25 -0500 Subject: clk: imx: composite-8m: Add imx8m_divider_determine_rate Currently, certain clocks are derrived as a divider from their parent clock. For some clocks, even when CLK_SET_RATE_PARENT is set, the parent clock is not properly set which can lead to some relatively inaccurate clock values. Unlike imx/clk-composite-93 and imx/clk-divider-gate, it cannot rely on calling a standard determine_rate function, because the 8m composite clocks have a pre-divider and post-divider. Because of this, a custom determine_rate function is necessary to determine the maximum clock division which is equivalent to pre-divider * the post-divider. With this added, the system can attempt to adjust the parent rate when the proper flags are set which can lead to a more precise clock value. On the imx8mplus, no clock changes are present. On the Mini and Nano, this can help achieve more accurate lcdif clocks. When trying to get a pixel clock of 31.500MHz on an imx8m Nano, the clocks divided the 594MHz down, but left the parent rate untouched which caused a calulation error. Before: video_pll 594000000 video_pll_bypass 594000000 video_pll_out 594000000 disp_pixel 31263158 disp_pixel_clk 31263158 Variance = -236842 Hz After this patch: video_pll 31500000 video_pll_bypass 31500000 video_pll_out 31500000 disp_pixel 31500000 disp_pixel_clk 31500000 Variance = 0 Hz All other clocks rates and parent were the same. Similar results on imx8mm were found. Fixes: 690dccc4a0bf ("Revert "clk: imx: composite-8m: Add support to determine_rate"") Signed-off-by: Adam Ford Reviewed-by: Abel Vesa Tested-by: Fabio Estevam Link: https://lore.kernel.org/r/20230506195325.876871-1-aford173@gmail.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-composite-8m.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index cbf0d7955a00..7a6e3ce97133 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -119,10 +119,41 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, return ret; } +static int imx8m_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + int prediv_value; + int div_value; + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + val = readl(divider->reg); + prediv_value = val >> divider->shift; + prediv_value &= clk_div_mask(divider->width); + prediv_value++; + + div_value = val >> PCG_DIV_SHIFT; + div_value &= clk_div_mask(PCG_DIV_WIDTH); + div_value++; + + return divider_ro_determine_rate(hw, req, divider->table, + PCG_PREDIV_WIDTH + PCG_DIV_WIDTH, + divider->flags, prediv_value * div_value); + } + + return divider_determine_rate(hw, req, divider->table, + PCG_PREDIV_WIDTH + PCG_DIV_WIDTH, + divider->flags); +} + static const struct clk_ops imx8m_clk_composite_divider_ops = { .recalc_rate = imx8m_clk_composite_divider_recalc_rate, .round_rate = imx8m_clk_composite_divider_round_rate, .set_rate = imx8m_clk_composite_divider_set_rate, + .determine_rate = imx8m_divider_determine_rate, }; static u8 imx8m_clk_composite_mux_get_parent(struct clk_hw *hw) -- cgit v1.2.3 From 1b280598ab3bd8a2dc8b96a12530d5b1ee7a8f4a Mon Sep 17 00:00:00 2001 From: Kai Ma Date: Tue, 18 Apr 2023 11:34:51 +0000 Subject: clk: imx: clk-imxrt1050: fix memory leak in imxrt1050_clocks_probe Use devm_of_iomap() instead of of_iomap() to automatically handle the unused ioremap region. If any error occurs, regions allocated by kzalloc() will leak, but using devm_kzalloc() instead will automatically free the memory using devm_kfree(). Also, fix error handling of hws by adding unregister_hws label, which unregisters remaining hws when iomap failed. Fixes: 7154b046d8f3 ("clk: imx: Add initial support for i.MXRT1050 clock driver") Signed-off-by: Kai Ma Reviewed-by: Peng Fan Acked-by: Jesse Taube Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20230418113451.151312-1-kaima@hust.edu.cn Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imxrt1050.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c index fd5c51fc92c0..08d155feb035 100644 --- a/drivers/clk/imx/clk-imxrt1050.c +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) struct device_node *anp; int ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMXRT1050_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) return -ENOMEM; @@ -53,10 +53,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) hws[IMXRT1050_CLK_OSC] = imx_get_clk_hw_by_name(np, "osc"); anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop"); - pll_base = of_iomap(anp, 0); + pll_base = devm_of_iomap(dev, anp, 0, NULL); of_node_put(anp); - if (WARN_ON(!pll_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(pll_base))) { + ret = PTR_ERR(pll_base); + goto unregister_hws; + } /* Anatop clocks */ hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL); @@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) /* CCM clocks */ ccm_base = devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(ccm_base))) - return PTR_ERR(ccm_base); + if (WARN_ON(IS_ERR(ccm_base))) { + ret = PTR_ERR(ccm_base); + goto unregister_hws; + } hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3); hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2, @@ -149,8 +153,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (ret < 0) { dev_err(dev, "Failed to register clks for i.MXRT1050.\n"); - imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END); + goto unregister_hws; } + return 0; + +unregister_hws: + imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END); return ret; } static const struct of_device_id imxrt1050_clk_of_match[] = { -- cgit v1.2.3 From 188d070de9132667956f5aadd98d2bd87d3eac89 Mon Sep 17 00:00:00 2001 From: Hao Luo Date: Tue, 11 Apr 2023 09:51:07 +0800 Subject: clk: imx: clk-imx8mn: fix memory leak in imx8mn_clocks_probe Use devm_of_iomap() instead of of_iomap() to automatically handle the unused ioremap region. If any error occurs, regions allocated by kzalloc() will leak, but using devm_kzalloc() instead will automatically free the memory using devm_kfree(). Fixes: daeb14545514 ("clk: imx: imx8mn: Switch to clk_hw based API") Fixes: 96d6392b54db ("clk: imx: Add support for i.MX8MN clock driver") Signed-off-by: Hao Luo Reviewed-by: Dongliang Mu Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20230411015107.2645-1-m202171776@hust.edu.cn Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 4b23a4648600..4bd1ed11353b 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) void __iomem *base; int ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MN_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) return -ENOMEM; @@ -340,10 +340,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4"); np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); - base = of_iomap(np, 0); + base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!base)) { - ret = -ENOMEM; + if (WARN_ON(IS_ERR(base))) { + ret = PTR_ERR(base); goto unregister_hws; } -- cgit v1.2.3 From e02ba11b457647050cb16e7cad16cec3c252fade Mon Sep 17 00:00:00 2001 From: Zhanhao Hu Date: Thu, 1 Jun 2023 03:38:25 +0000 Subject: clk: imx93: fix memory leak and missing unwind goto in imx93_clocks_probe In function probe(), it returns directly without unregistered hws when error occurs. Fix this by adding 'goto unregister_hws;' on line 295 and line 310. Use devm_kzalloc() instead of kzalloc() to automatically free the memory using devm_kfree() when error occurs. Replace of_iomap() with devm_of_iomap() to automatically handle the unused ioremap region and delete 'iounmap(anatop_base);' in unregister_hws. Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") Signed-off-by: Zhanhao Hu Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20230601033825.336558-1-zero12113@hust.edu.cn Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx93.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index 07b4a043e449..b6c7c2725906 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -264,7 +264,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) void __iomem *base, *anatop_base; int i, ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX93_CLK_END), GFP_KERNEL); if (!clk_hw_data) return -ENOMEM; @@ -288,10 +288,12 @@ static int imx93_clocks_probe(struct platform_device *pdev) "sys_pll_pfd2", 1, 2); np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); - anatop_base = of_iomap(np, 0); + anatop_base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!anatop_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(anatop_base))) { + ret = PTR_ERR(base); + goto unregister_hws; + } clks[IMX93_CLK_ARM_PLL] = imx_clk_fracn_gppll_integer("arm_pll", "osc_24m", anatop_base + 0x1000, @@ -304,8 +306,8 @@ static int imx93_clocks_probe(struct platform_device *pdev) np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); if (WARN_ON(IS_ERR(base))) { - iounmap(anatop_base); - return PTR_ERR(base); + ret = PTR_ERR(base); + goto unregister_hws; } for (i = 0; i < ARRAY_SIZE(root_array); i++) { @@ -345,7 +347,6 @@ static int imx93_clocks_probe(struct platform_device *pdev) unregister_hws: imx_unregister_hw_clocks(clks, IMX93_CLK_END); - iounmap(anatop_base); return ret; } -- cgit v1.2.3 From 878b02d5f3b56cb090dbe2c70c89273be144087f Mon Sep 17 00:00:00 2001 From: Yuxing Liu Date: Wed, 3 May 2023 07:06:07 +0000 Subject: clk: imx: clk-imx8mp: improve error handling in imx8mp_clocks_probe() Replace of_iomap() and kzalloc() with devm_of_iomap() and devm_kzalloc() which can automatically release the related memory when the device or driver is removed or unloaded to avoid potential memory leak. In this case, iounmap(anatop_base) in line 427,433 are removed as manual release is not required. Besides, referring to clk-imx8mq.c, check the return code of of_clk_add_hw_provider, if it returns negtive, print error info and unregister hws, which makes the program more robust. Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver") Signed-off-by: Yuxing Liu Reviewed-by: Dongliang Mu Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20230503070607.2462-1-lyx2022@hust.edu.cn Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index f26ae8de4cc6..1469249386dd 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np; void __iomem *anatop_base, *ccm_base; + int err; np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); - anatop_base = of_iomap(np, 0); + anatop_base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!anatop_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(anatop_base))) + return PTR_ERR(anatop_base); np = dev->of_node; ccm_base = devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(ccm_base))) { - iounmap(anatop_base); + if (WARN_ON(IS_ERR(ccm_base))) return PTR_ERR(ccm_base); - } - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); - if (WARN_ON(!clk_hw_data)) { - iounmap(anatop_base); + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) return -ENOMEM; - } clk_hw_data->num = IMX8MP_CLK_END; hws = clk_hw_data->hws; @@ -722,7 +719,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) imx_check_clk_hws(hws, IMX8MP_CLK_END); - of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (err < 0) { + dev_err(dev, "failed to register hws for i.MX8MP\n"); + imx_unregister_hw_clocks(hws, IMX8MP_CLK_END); + return err; + } imx_register_uart_clocks(); -- cgit v1.2.3 From a7a0c7d5502217e650d1e996520717212ee54fb9 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 28 Apr 2023 15:00:05 +0800 Subject: clk: sifive: Use devm_platform_ioremap_resource() Convert platform_get_resource(),devm_ioremap_resource() to a single call to devm_platform_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yang Li Link: https://lore.kernel.org/r/20230428070005.41192-1-yang.lee@linux.alibaba.com Signed-off-by: Stephen Boyd --- drivers/clk/sifive/sifive-prci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index 916d2fc28b9c..e317f3454e93 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -567,7 +567,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, static int sifive_prci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; struct __prci_data *pd; const struct prci_clk_desc *desc; int r; @@ -578,8 +577,7 @@ static int sifive_prci_probe(struct platform_device *pdev) if (!pd) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pd->va = devm_ioremap_resource(dev, res); + pd->va = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pd->va)) return PTR_ERR(pd->va); -- cgit v1.2.3 From da2edb3e3c09fd1451b7f400ccd1070ef086619a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Apr 2023 13:41:01 +0300 Subject: clk: bcm: rpi: Fix off by one in raspberrypi_discover_clocks() Smatch detected an off by one in this code: drivers/clk/bcm/clk-raspberrypi.c:374 raspberrypi_discover_clocks() error: buffer overflow 'data->hws' 16 <= 16 The data->hws[] array has RPI_FIRMWARE_NUM_CLK_ID elements so the > comparison needs to changed to >=. Fixes: 12c90f3f27bb ("clk: bcm: rpi: Add variant structure") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/5a850b08-d2f5-4794-aceb-a6b468965139@kili.mountain Reviewed-by: Stefan Wahren Reviewed-by: Florian Fainelli Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-raspberrypi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index eb399a4d141b..829406dc44a2 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, while (clks->id) { struct raspberrypi_clk_variant *variant; - if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) { + if (clks->id >= RPI_FIRMWARE_NUM_CLK_ID) { dev_err(rpi->dev, "Unknown clock id: %u (max: %u)\n", - clks->id, RPI_FIRMWARE_NUM_CLK_ID); + clks->id, RPI_FIRMWARE_NUM_CLK_ID - 1); return -EINVAL; } -- cgit v1.2.3 From 9c632a6396505a019ea6d12b5ab45e659a542a93 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 11 May 2023 20:01:20 +0300 Subject: clk: clocking-wizard: Fix Oops in clk_wzrd_register_divider() Smatch detected this potential error pointer dereference clk_wzrd_register_divider(). If devm_clk_hw_register() fails then it sets "hw" to an error pointer and then dereferences it on the next line. Return the error directly instead. Fixes: 5a853722eb32 ("staging: clocking-wizard: Add support for dynamic reconfiguration") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/f0e39b5c-4554-41e0-80d9-54ca3fabd060@kili.mountain Reviewed-by: Michal Simek Signed-off-by: Stephen Boyd --- drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index e83f104fad02..16df34f46280 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -525,7 +525,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, hw = &div->hw; ret = devm_clk_hw_register(dev, hw); if (ret) - hw = ERR_PTR(ret); + return ERR_PTR(ret); return hw->clk; } -- cgit v1.2.3 From 53a06e5924c0d43c11379a08c5a78529c3e61595 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Fri, 9 Dec 2022 09:41:24 +0000 Subject: clk: tegra: tegra124-emc: Fix potential memory leak The tegra and tegra needs to be freed in the error handling path, otherwise it will be leaked. Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver") Signed-off-by: Yuan Can Link: https://lore.kernel.org/r/20221209094124.71043-1-yuancan@huawei.com Acked-by: Thierry Reding Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra124-emc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 219c80653dbd..2a6db0434281 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, err = load_one_timing_from_dt(tegra, timing, child); if (err) { of_node_put(child); + kfree(tegra->timings); return err; } @@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np err = load_timings_from_dt(tegra, node, node_ram_code); if (err) { of_node_put(node); + kfree(tegra); return ERR_PTR(err); } } -- cgit v1.2.3 From 1fe8150d3b0b6270808f0833d9b9ac159af6b770 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 5 Apr 2023 20:07:38 -0500 Subject: clk: mvebu: Use of_address_to_resource() Replace of_get_property() and of_translate_address() calls with a single call to of_address_to_resource(). Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230406010738.1269781-1-robh@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada_ap_cp_helper.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.c b/drivers/clk/mvebu/armada_ap_cp_helper.c index 6a930f697ee5..e7005de66327 100644 --- a/drivers/clk/mvebu/armada_ap_cp_helper.c +++ b/drivers/clk/mvebu/armada_ap_cp_helper.c @@ -16,15 +16,13 @@ char *ap_cp_unique_name(struct device *dev, struct device_node *np, const char *name) { - const __be32 *reg; - u64 addr; + struct resource res; /* Do not create a name if there is no clock */ if (!name) return NULL; - reg = of_get_property(np, "reg", NULL); - addr = of_translate_address(np, reg); + of_address_to_resource(np, 0, &res); return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", - (unsigned long long)addr, name); + (unsigned long long)res.start, name); } -- cgit v1.2.3 From 595409cf07ade54d6265942f25a3d33b0d76a17c Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 16 May 2023 13:46:25 -0500 Subject: clk: keystone: syscon-clk: Allow the clock node to not be of type syscon There is a helper device_node_to_regmap() we can use that does not force this clock DT node to be a "syscon" node. It should work the same in this case but allow us to remove the unneeded "syscon" compatible. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20230516184626.154892-1-afd@ti.com Signed-off-by: Stephen Boyd --- drivers/clk/keystone/syscon-clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index 5d7cc83682da..bd5cec0bd12d 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -101,10 +101,10 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) if (!data) return -EINVAL; - regmap = syscon_node_to_regmap(dev->of_node); + regmap = device_node_to_regmap(dev->of_node); if (IS_ERR(regmap)) return dev_err_probe(dev, PTR_ERR(regmap), - "failed to find parent regmap\n"); + "failed to get regmap\n"); num_clks = 0; for (p = data; p->name; p++) -- cgit v1.2.3 From 6acab96ee33703497f30b66efa553a7d0ebd5c0f Mon Sep 17 00:00:00 2001 From: Jai Luthra Date: Thu, 15 Jun 2023 17:25:36 +0530 Subject: clk: keystone: syscon-clk: Add support for audio refclk TI's AM62 SoC can optionally provide two audio reference clocks (AUDIO_REFCLKx) to external peripherals. By default this reference clock is looped-back inside the SoC to a mux that goes to McASP AHCLK, but can optionally be enabled as an output to peripherals outside the SoC by setting a bit through CTRL_MMR registers. This bit only controls the direction of the clock, while the parent is a muxed input from sci-clk [1] which may be a configurable PLL or a master clock from one of the McASP instances. Link: http://downloads.ti.com/tisci/esd/latest/5_soc_doc/am62x/clocks.html#clocks-for-board0-device [1] Signed-off-by: Jai Luthra Link: https://lore.kernel.org/r/20230515-refclk-v3-2-37c0b550f406@ti.com Signed-off-by: Stephen Boyd --- drivers/clk/keystone/syscon-clk.c | 45 ++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index bd5cec0bd12d..d33f74119488 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -4,10 +4,12 @@ */ #include +#include #include #include #include #include +#include struct ti_syscon_gate_clk_priv { struct clk_hw hw; @@ -61,21 +63,31 @@ static const struct clk_ops ti_syscon_gate_clk_ops = { static struct clk_hw *ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap, + const char *parent_name, const struct ti_syscon_gate_clk_data *data) { struct ti_syscon_gate_clk_priv *priv; struct clk_init_data init; + char *name = NULL; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return ERR_PTR(-ENOMEM); - init.name = data->name; init.ops = &ti_syscon_gate_clk_ops; - init.parent_names = NULL; - init.num_parents = 0; - init.flags = 0; + if (parent_name) { + name = kasprintf(GFP_KERNEL, "%s:%s", data->name, parent_name); + init.name = name; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = CLK_SET_RATE_PARENT; + } else { + init.name = data->name; + init.parent_names = NULL; + init.num_parents = 0; + init.flags = 0; + } priv->regmap = regmap; priv->reg = data->offset; @@ -83,6 +95,10 @@ static struct clk_hw priv->hw.init = &init; ret = devm_clk_hw_register(dev, &priv->hw); + + if (name) + kfree(init.name); + if (ret) return ERR_PTR(ret); @@ -94,8 +110,9 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) const struct ti_syscon_gate_clk_data *data, *p; struct clk_hw_onecell_data *hw_data; struct device *dev = &pdev->dev; + int num_clks, num_parents, i; + const char *parent_name; struct regmap *regmap; - int num_clks, i; data = device_get_match_data(dev); if (!data) @@ -110,6 +127,13 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) for (p = data; p->name; p++) num_clks++; + num_parents = of_clk_get_parent_count(dev->of_node); + if (of_device_is_compatible(dev->of_node, "ti,am62-audio-refclk") && + num_parents == 0) { + return dev_err_probe(dev, -EINVAL, + "must specify a parent clock\n"); + } + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks), GFP_KERNEL); if (!hw_data) @@ -117,8 +141,10 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) hw_data->num = num_clks; + parent_name = of_clk_get_parent_name(dev->of_node, 0); for (i = 0; i < num_clks; i++) { hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap, + parent_name, &data[i]); if (IS_ERR(hw_data->hws[i])) dev_warn(dev, "failed to register %s\n", @@ -166,6 +192,11 @@ static const struct ti_syscon_gate_clk_data am62_clk_data[] = { { /* Sentinel */ }, }; +static const struct ti_syscon_gate_clk_data am62_audio_clk_data[] = { + TI_SYSCON_CLK_GATE("audio_refclk", 0x0, 15), + { /* Sentinel */ }, +}; + static const struct of_device_id ti_syscon_gate_clk_ids[] = { { .compatible = "ti,am654-ehrpwm-tbclk", @@ -179,6 +210,10 @@ static const struct of_device_id ti_syscon_gate_clk_ids[] = { .compatible = "ti,am62-epwm-tbclk", .data = &am62_clk_data, }, + { + .compatible = "ti,am62-audio-refclk", + .data = &am62_audio_clk_data, + }, { } }; MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids); -- cgit v1.2.3 From 144601f6228de5598f03e693822b60a95c367a17 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:06 +0300 Subject: clk: vc5: check memory returned by kasprintf() kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: f491276a5168 ("clk: vc5: Allow Versaclock driver to support multiple instances") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-2-claudiu.beznea@microchip.com Reviewed-by: Luca Ceresoli Signed-off-by: Stephen Boyd --- drivers/clk/clk-versaclock5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index fa71a57875ce..40fdf2564aa7 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1028,6 +1028,11 @@ static int vc5_probe(struct i2c_client *client) } init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } + init.ops = &vc5_mux_ops; init.flags = 0; init.parent_names = parent_names; @@ -1042,6 +1047,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_dbl_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1057,6 +1066,10 @@ static int vc5_probe(struct i2c_client *client) /* Register PFD */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pfd_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1074,6 +1087,10 @@ static int vc5_probe(struct i2c_client *client) /* Register PLL */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pll_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1093,6 +1110,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d", client->dev.of_node, idx); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_fod_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1111,6 +1132,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1137,6 +1162,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d", client->dev.of_node, idx + 1); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; -- cgit v1.2.3 From bb7d09ddbf361d51eae46f38e7c8a2b85914ea2a Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:07 +0300 Subject: clk: cdce925: check return value of kasprintf() kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: 19fbbbbcd3a3 ("Add TI CDCE925 I2C controlled clock synthesizer driver") Depends-on: e665f029a283 ("clk: Convert to using %pOFn instead of device_node.name") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-3-claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-cdce925.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 6350682f7e6d..87890669297d 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client) for (i = 0; i < data->chip_info->num_plls; ++i) { pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", client->dev.of_node, i); + if (!pll_clk_name[i]) { + err = -ENOMEM; + goto error; + } init.name = pll_clk_name[i]; data->pll[i].chip = data; data->pll[i].hw.init = &init; @@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client) init.num_parents = 1; init.parent_names = &parent_name; /* Mux Y1 to input */ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[0].chip = data; data->clk[0].hw.init = &init; data->clk[0].index = 0; @@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client) for (i = 1; i < data->chip_info->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", client->dev.of_node, i+1); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[i].chip = data; data->clk[i].hw.init = &init; data->clk[i].index = i; -- cgit v1.2.3 From 2560114c06d7a752b3f4639f28cece58fed11267 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:08 +0300 Subject: clk: si5341: return error if one synth clock registration fails In case devm_clk_hw_register() fails for one of synth clocks the probe continues. Later on, when registering output clocks which have as parents all the synth clocks, in case there is registration failure for at least one synth clock the information passed to clk core for registering output clock is not right: init.num_parents is fixed but init.parents may contain an array with less parents. Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-4-claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-si5341.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 0e528d7ba656..6dca3288c894 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1553,7 +1553,7 @@ static int si5341_probe(struct i2c_client *client) struct clk_init_data init; struct clk *input; const char *root_clock_name; - const char *synth_clock_names[SI5341_NUM_SYNTH]; + const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL }; int err; unsigned int i; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; @@ -1705,6 +1705,7 @@ static int si5341_probe(struct i2c_client *client) if (err) { dev_err(&client->dev, "synth N%u registration failed\n", i); + goto free_clk_names; } } @@ -1782,16 +1783,17 @@ static int si5341_probe(struct i2c_client *client) goto cleanup; } +free_clk_names: /* Free the names, clk framework makes copies */ for (i = 0; i < data->num_synth; ++i) devm_kfree(&client->dev, (void *)synth_clock_names[i]); - return 0; - cleanup: - for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { - if (data->clk[i].vddo_reg) - regulator_disable(data->clk[i].vddo_reg); + if (err) { + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + if (data->clk[i].vddo_reg) + regulator_disable(data->clk[i].vddo_reg); + } } return err; } -- cgit v1.2.3 From 36e4ef82016a2b785cf2317eade77e76699b7bff Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:09 +0300 Subject: clk: si5341: check return value of {devm_}kasprintf() {devm_}kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-5-claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-si5341.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 6dca3288c894..b2cf7edc8b30 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1697,6 +1697,10 @@ static int si5341_probe(struct i2c_client *client) for (i = 0; i < data->num_synth; ++i) { synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, "%s.N%u", client->dev.of_node->name, i); + if (!synth_clock_names[i]) { + err = -ENOMEM; + goto free_clk_names; + } init.name = synth_clock_names[i]; data->synth[i].index = i; data->synth[i].data = data; @@ -1715,6 +1719,10 @@ static int si5341_probe(struct i2c_client *client) for (i = 0; i < data->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%s.%d", client->dev.of_node->name, i); + if (!init.name) { + err = -ENOMEM; + goto free_clk_names; + } init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0; data->clk[i].index = i; data->clk[i].data = data; -- cgit v1.2.3 From 267ad94b13c53d8c99a336f0841b1fa1595b1d0f Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:10 +0300 Subject: clk: si5341: free unused memory on probe failure Pointers from synth_clock_names[] should be freed at the end of probe either on probe success or failure path. Fixes: b7bbf6ec4940 ("clk: si5341: Allow different output VDD_SEL values") Fixes: 9b13ff4340df ("clk: si5341: Add sysfs properties to allow checking/resetting device faults") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-6-claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-si5341.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index b2cf7edc8b30..c7d8cbd22bac 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1744,7 +1744,7 @@ static int si5341_probe(struct i2c_client *client) if (err) { dev_err(&client->dev, "output %u registration failed\n", i); - goto cleanup; + goto free_clk_names; } if (config[i].always_on) clk_prepare(data->clk[i].hw.clk); @@ -1754,7 +1754,7 @@ static int si5341_probe(struct i2c_client *client) data); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); - goto cleanup; + goto free_clk_names; } if (initialization_required) { @@ -1762,11 +1762,11 @@ static int si5341_probe(struct i2c_client *client) regcache_cache_only(data->regmap, false); err = regcache_sync(data->regmap); if (err < 0) - goto cleanup; + goto free_clk_names; err = si5341_finalize_defaults(data); if (err < 0) - goto cleanup; + goto free_clk_names; } /* wait for device to report input clock present and PLL lock */ @@ -1775,21 +1775,19 @@ static int si5341_probe(struct i2c_client *client) 10000, 250000); if (err) { dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); - goto cleanup; + goto free_clk_names; } /* clear sticky alarm bits from initialization */ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); if (err) { dev_err(&client->dev, "unable to clear sticky status\n"); - goto cleanup; + goto free_clk_names; } err = sysfs_create_files(&client->dev.kobj, si5341_attributes); - if (err) { + if (err) dev_err(&client->dev, "unable to create sysfs files\n"); - goto cleanup; - } free_clk_names: /* Free the names, clk framework makes copies */ -- cgit v1.2.3 From b73ed981da6d25c921aaefa7ca3df85bbd85b7fc Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:11 +0300 Subject: clk: keystone: sci-clk: check return value of kasprintf() kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") Depends-on: 96488c09b0f4 ("clk: keystone: sci-clk: cut down the clock name length") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-7-claudiu.beznea@microchip.com Reviewed-by: Tony Lindgren Signed-off-by: Stephen Boyd --- drivers/clk/keystone/sci-clk.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 910ecd58c4ca..6c1df4f11536 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -294,6 +294,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider, name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, sci_clk->clk_id); + if (!name) + return -ENOMEM; init.name = name; -- cgit v1.2.3 From bd46cd0b802d9c9576ca78007aa084ae3e74907b Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:12 +0300 Subject: clk: ti: clkctrl: check return value of kasprintf() kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: 852049594b9a ("clk: ti: clkctrl: convert subclocks to use proper names also") Fixes: 6c3090520554 ("clk: ti: clkctrl: Fix hidden dependency to node name") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-8-claudiu.beznea@microchip.com Reviewed-by: Tony Lindgren Signed-off-by: Stephen Boyd --- drivers/clk/ti/clkctrl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index b6fce916967c..8c40f10280b7 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np, if (clkctrl_name && !legacy_naming) { clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", clkctrl_name, offset, index); + if (!clock_name) + return NULL; + strreplace(clock_name, '_', '-'); return clock_name; @@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (clkctrl_name) { provider->clkdm_name = kasprintf(GFP_KERNEL, "%s_clkdm", clkctrl_name); + if (!provider->clkdm_name) { + kfree(provider); + return; + } goto clkdm_found; } -- cgit v1.2.3 From b1356ed1a4461de06dfdc02bf549c3e8750162e5 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 30 May 2023 12:39:13 +0300 Subject: clk: clocking-wizard: check return value of devm_kasprintf() devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script). Fixes: 2046338dcbc6 ("ARM: mxs: Use soc bus infrastructure") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230530093913.1656095-9-claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd --- drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index e83f104fad02..20e0e91552bc 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -648,6 +648,11 @@ static int clk_wzrd_probe(struct platform_device *pdev) } clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev)); + if (!clkout_name) { + ret = -ENOMEM; + goto err_disable_clk; + } + if (nr_outputs == 1) { clk_wzrd->clkout[0] = clk_wzrd_register_divider (&pdev->dev, clkout_name, -- cgit v1.2.3 From 1949c0ebc8d660d35ea968ed609c528076b7d44f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 9 Jun 2023 12:13:46 -0600 Subject: clk: mvebu: Use of_get_cpu_hwid() to read CPU ID Use of_get_cpu_hwid() rather than the open coded reading of the CPU nodes "reg" property. The existing code is in fact wrong as the "reg" address cells size is 2 cells for arm64. The existing code happens to work because the DTS files are wrong as well. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230327-mvebu-clk-fixes-v2-2-8333729ee45d@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap-cpu-clk.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 71bdd7c3ff03..d8a7a4c90d54 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -253,12 +253,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) */ nclusters = 1; for_each_of_cpu_node(dn) { - int cpu, err; + u64 cpu; - err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) { + cpu = of_get_cpu_hwid(dn, 0); + if (WARN_ON(cpu == OF_BAD_ADDR)) { of_node_put(dn); - return err; + return -EINVAL; } /* If cpu2 or cpu3 is enabled */ @@ -288,12 +288,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) struct clk_init_data init; const char *parent_name; struct clk *parent; - int cpu, err; + u64 cpu; - err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) { + cpu = of_get_cpu_hwid(dn, 0); + if (WARN_ON(cpu == OF_BAD_ADDR)) { of_node_put(dn); - return err; + return -EINVAL; } cluster_index = cpu & APN806_CLUSTER_NUM_MASK; -- cgit v1.2.3 From bd73d1fd63d4f67dc78640c9ae4f83e20a021d76 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 9 Jun 2023 12:13:47 -0600 Subject: clk: mvebu: Iterate over possible CPUs instead of DT CPU nodes Rework iterating over DT CPU nodes to iterate over possible CPUs instead. There's no need to walk the DT CPU nodes again. Possible CPUs is equal to the number of CPUs defined in the DT. Using the "reg" value for an array index is fragile as it assumes "reg" is 0-N which often is not the case. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230327-mvebu-clk-fixes-v2-3-8333729ee45d@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/clk-cpu.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index c2af3395cf13..db2b38c21304 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -168,8 +168,8 @@ static void __init of_cpu_clk_setup(struct device_node *node) struct cpu_clk *cpuclk; void __iomem *clock_complex_base = of_iomap(node, 0); void __iomem *pmu_dfs_base = of_iomap(node, 1); - int ncpus = 0; - struct device_node *dn; + int ncpus = num_possible_cpus(); + int cpu; if (clock_complex_base == NULL) { pr_err("%s: clock-complex base register not set\n", @@ -181,9 +181,6 @@ static void __init of_cpu_clk_setup(struct device_node *node) pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n", __func__); - for_each_of_cpu_node(dn) - ncpus++; - cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL); if (WARN_ON(!cpuclk)) goto cpuclk_out; @@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node) if (WARN_ON(!clks)) goto clks_out; - for_each_of_cpu_node(dn) { + for_each_possible_cpu(cpu) { struct clk_init_data init; struct clk *clk; char *clk_name = kzalloc(5, GFP_KERNEL); - int cpu, err; if (WARN_ON(!clk_name)) goto bail_out; - err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) - goto bail_out; - sprintf(clk_name, "cpu%d", cpu); cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0); -- cgit v1.2.3 From 7fb933e56f77a57ef7cfc59fc34cbbf1b1fa31ff Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Mon, 19 Jun 2023 11:22:53 +0800 Subject: clk: Fix memory leak in devm_clk_notifier_register() devm_clk_notifier_register() allocates a devres resource for clk notifier but didn't register that to the device, so the notifier didn't get unregistered on device detach and the allocated resource was leaked. Fix the issue by registering the resource through devres_add(). This issue was found with kmemleak on a Chromebook. Fixes: 6d30d50d037d ("clk: add devm variant of clk_notifier_register") Signed-off-by: Fei Shao Link: https://lore.kernel.org/r/20230619112253.v2.1.I13f060c10549ef181603e921291bdea95f83033c@changeid Reviewed-by: Dan Carpenter Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/clk') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 27c30a533759..ce9dbef314d5 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4695,6 +4695,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk, if (!ret) { devres->clk = clk; devres->nb = nb; + devres_add(dev, devres); } else { devres_free(devres); } -- cgit v1.2.3