Message ID | 20210629203919.2956918-1-dmitry.baryshkov@linaro.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | [1/2] clk: qcom: fix error_path in gdsc_register | expand |
Quoting Dmitry Baryshkov (2021-06-29 13:39:18) > Properly handle and cleanup errors in gdsc_register() instead of just > returning an error and leaving some of resources registered/hanging in > the system. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Any Fixes tag? Also, please send multi-patch series with a cover letter and Cc Taniya Das <tdas@codeaurora.org> on qcom clk patches. -Stephen > --- > drivers/clk/qcom/gdsc.c | 32 ++++++++++++++++++++++++++++---- > 1 file changed, 28 insertions(+), 4 deletions(-) > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > index 51ed640e527b..241186d9d08c 100644 > --- a/drivers/clk/qcom/gdsc.c > +++ b/drivers/clk/qcom/gdsc.c > @@ -429,7 +429,7 @@ int gdsc_register(struct gdsc_desc *desc, > scs[i]->rcdev = rcdev; > ret = gdsc_init(scs[i]); > if (ret) > - return ret; > + goto err_init; > data->domains[i] = &scs[i]->pd; > } > > @@ -437,11 +437,35 @@ int gdsc_register(struct gdsc_desc *desc, > for (i = 0; i < num; i++) { > if (!scs[i]) > continue; > - if (scs[i]->parent) > - pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); > + if (scs[i]->parent) { > + ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); > + if (ret) > + goto err_subdomain; > + } > } > > - return of_genpd_add_provider_onecell(dev->of_node, data); > + ret = of_genpd_add_provider_onecell(dev->of_node, data); > + if (!ret) > + return 0; > + > +err_subdomain: > + i--; > + for (; i >= 0; i--) { > + if (!scs[i] || !scs[i]->parent) > + continue; > + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); > + } > + i = num; > + > +err_init: > + i--; > + for (; i >= 0; i--) { > + if (!scs[i]) > + continue; > + pm_genpd_remove(&scs[i]->pd); > + } > + > + return ret; > } > > void gdsc_unregister(struct gdsc_desc *desc) > --
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 51ed640e527b..241186d9d08c 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -429,7 +429,7 @@ int gdsc_register(struct gdsc_desc *desc, scs[i]->rcdev = rcdev; ret = gdsc_init(scs[i]); if (ret) - return ret; + goto err_init; data->domains[i] = &scs[i]->pd; } @@ -437,11 +437,35 @@ int gdsc_register(struct gdsc_desc *desc, for (i = 0; i < num; i++) { if (!scs[i]) continue; - if (scs[i]->parent) - pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + if (scs[i]->parent) { + ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + if (ret) + goto err_subdomain; + } } - return of_genpd_add_provider_onecell(dev->of_node, data); + ret = of_genpd_add_provider_onecell(dev->of_node, data); + if (!ret) + return 0; + +err_subdomain: + i--; + for (; i >= 0; i--) { + if (!scs[i] || !scs[i]->parent) + continue; + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + } + i = num; + +err_init: + i--; + for (; i >= 0; i--) { + if (!scs[i]) + continue; + pm_genpd_remove(&scs[i]->pd); + } + + return ret; } void gdsc_unregister(struct gdsc_desc *desc)
Properly handle and cleanup errors in gdsc_register() instead of just returning an error and leaving some of resources registered/hanging in the system. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/clk/qcom/gdsc.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-)