Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: gdsc: Capture pm_genpd_add_subdomain result code

Adding a new clause to this if/else I noticed the existing usage of
pm_genpd_add_subdomain() wasn't capturing and returning the result code.

pm_genpd_add_subdomain() returns an int and can fail. Capture that result
code and throw it up the call stack if something goes wrong.

Fixes: 1b771839de05 ("clk: qcom: gdsc: enable optional power domain support")
Cc: stable@vger.kernel.org
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Link: https://lore.kernel.org/r/20250117-b4-linux-next-24-11-18-clock-multiple-power-domains-v10-2-13f2bb656dad@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Bryan O'Donoghue and committed by
Bjorn Andersson
65a73346 0e6dfde4

+27 -13
+27 -13
drivers/clk/qcom/gdsc.c
··· 506 506 return ret; 507 507 } 508 508 509 + static void gdsc_pm_subdomain_remove(struct gdsc_desc *desc, size_t num) 510 + { 511 + struct device *dev = desc->dev; 512 + struct gdsc **scs = desc->scs; 513 + int i; 514 + 515 + /* Remove subdomains */ 516 + for (i = num - 1; i >= 0; i--) { 517 + if (!scs[i]) 518 + continue; 519 + if (scs[i]->parent) 520 + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); 521 + else if (!IS_ERR_OR_NULL(dev->pm_domain)) 522 + pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); 523 + } 524 + } 525 + 509 526 int gdsc_register(struct gdsc_desc *desc, 510 527 struct reset_controller_dev *rcdev, struct regmap *regmap) 511 528 { ··· 572 555 if (!scs[i]) 573 556 continue; 574 557 if (scs[i]->parent) 575 - pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); 558 + ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); 576 559 else if (!IS_ERR_OR_NULL(dev->pm_domain)) 577 - pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); 560 + ret = pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); 561 + if (ret) 562 + goto err_pm_subdomain_remove; 578 563 } 579 564 580 565 return of_genpd_add_provider_onecell(dev->of_node, data); 566 + 567 + err_pm_subdomain_remove: 568 + gdsc_pm_subdomain_remove(desc, i); 569 + 570 + return ret; 581 571 } 582 572 583 573 void gdsc_unregister(struct gdsc_desc *desc) 584 574 { 585 - int i; 586 575 struct device *dev = desc->dev; 587 - struct gdsc **scs = desc->scs; 588 576 size_t num = desc->num; 589 577 590 - /* Remove subdomains */ 591 - for (i = num - 1; i >= 0; i--) { 592 - if (!scs[i]) 593 - continue; 594 - if (scs[i]->parent) 595 - pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); 596 - else if (!IS_ERR_OR_NULL(dev->pm_domain)) 597 - pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); 598 - } 578 + gdsc_pm_subdomain_remove(desc, num); 599 579 of_genpd_del_provider(dev->of_node); 600 580 } 601 581