diff mbox series

clk: mediatek: clk-mt8173: fix potential memory leak

Message ID 1581651274-5933-1-git-send-email-qiwuchen55@gmail.com (mailing list archive)
State New, archived
Headers show
Series clk: mediatek: clk-mt8173: fix potential memory leak | expand

Commit Message

chenqiwu Feb. 14, 2020, 3:34 a.m. UTC
From: chenqiwu <chenqiwu@xiaomi.com>

Free clk_data or iomem resources if init is not successful.

Signed-off-by: chenqiwu <chenqiwu@xiaomi.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 43 +++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 9 deletions(-)

Comments

Matthias Brugger Feb. 14, 2020, 9:47 a.m. UTC | #1
On 14/02/2020 04:34, qiwuchen55@gmail.com wrote:
> From: chenqiwu <chenqiwu@xiaomi.com>
> 
> Free clk_data or iomem resources if init is not successful.
> 
> Signed-off-by: chenqiwu <chenqiwu@xiaomi.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 43 +++++++++++++++++++++++++++++++--------
>  1 file changed, 34 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 537a7f4..eaf4e70 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -7,6 +7,7 @@
>  #include <linux/clk.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include <linux/slab.h>
>  
>  #include "clk-mtk.h"
>  #include "clk-gate.h"
> @@ -941,9 +942,13 @@ static void __init mtk_topckgen_init(struct device_node *node)
>  			&mt8173_clk_lock, clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);

we have to free clk_data->clks as well, don't we?
This holds for all the other hunks in this patch as well.

Actually a better solution would be to change mtk_alloc_clk_data to pass it a
struct device and do devm_kzalloc etc. This way we won't need to deal with
freeing data in case of error. This is an API change and includes changes to all
clock drivers of MediaTek though.

Regards,
Matthias

> +		clk_data = NULL;
> +		iounmap(base);
> +	}
>  
>  	mtk_clk_enable_critical();
>  }
> @@ -964,9 +969,11 @@ static void __init mtk_infrasys_init(struct device_node *node)
>  				  clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  
>  	mtk_register_reset_controller(node, 2, 0x30);
>  }
> @@ -992,9 +999,12 @@ static void __init mtk_pericfg_init(struct device_node *node)
>  			&mt8173_clk_lock, clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +		iounmap(base);
> +	}
>  
>  	mtk_register_reset_controller(node, 2, 0);
>  }
> @@ -1117,9 +1127,14 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
>  	clk_data->clks[CLK_APMIXED_HDMI_REF] = clk;
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		clk_unregister_divider(clk);
> +		kfree(clk_data);
> +		clk_data = NULL;
> +		iounmap(base);
> +	}
>  
>  	mtk_clk_enable_critical();
>  }
> @@ -1138,9 +1153,11 @@ static void __init mtk_imgsys_init(struct device_node *node)
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
>  
> @@ -1155,9 +1172,11 @@ static void __init mtk_mmsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
>  
> @@ -1172,9 +1191,11 @@ static void __init mtk_vdecsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
>  
> @@ -1189,9 +1210,11 @@ static void __init mtk_vencsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
>  
> @@ -1206,8 +1229,10 @@ static void __init mtk_vencltsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
>
diff mbox series

Patch

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 537a7f4..eaf4e70 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -7,6 +7,7 @@ 
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/slab.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -941,9 +942,13 @@  static void __init mtk_topckgen_init(struct device_node *node)
 			&mt8173_clk_lock, clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+		clk_data = NULL;
+		iounmap(base);
+	}
 
 	mtk_clk_enable_critical();
 }
@@ -964,9 +969,11 @@  static void __init mtk_infrasys_init(struct device_node *node)
 				  clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 
 	mtk_register_reset_controller(node, 2, 0x30);
 }
@@ -992,9 +999,12 @@  static void __init mtk_pericfg_init(struct device_node *node)
 			&mt8173_clk_lock, clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+		iounmap(base);
+	}
 
 	mtk_register_reset_controller(node, 2, 0);
 }
@@ -1117,9 +1127,14 @@  static void __init mtk_apmixedsys_init(struct device_node *node)
 	clk_data->clks[CLK_APMIXED_HDMI_REF] = clk;
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		clk_unregister_divider(clk);
+		kfree(clk_data);
+		clk_data = NULL;
+		iounmap(base);
+	}
 
 	mtk_clk_enable_critical();
 }
@@ -1138,9 +1153,11 @@  static void __init mtk_imgsys_init(struct device_node *node)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
 
@@ -1155,9 +1172,11 @@  static void __init mtk_mmsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
 
@@ -1172,9 +1191,11 @@  static void __init mtk_vdecsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
 
@@ -1189,9 +1210,11 @@  static void __init mtk_vencsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
 
@@ -1206,8 +1229,10 @@  static void __init mtk_vencltsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);