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 |
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 --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);