Commit 65a73346 authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Bjorn Andersson
Browse files

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: 1b771839 ("clk: qcom: gdsc: enable optional power domain support")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarBryan 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: default avatarBjorn Andersson <andersson@kernel.org>
parent 0e6dfde4
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -506,6 +506,23 @@ static int gdsc_init(struct gdsc *sc)
	return ret;
}

static void gdsc_pm_subdomain_remove(struct gdsc_desc *desc, size_t num)
{
	struct device *dev = desc->dev;
	struct gdsc **scs = desc->scs;
	int i;

	/* Remove subdomains */
	for (i = num - 1; i >= 0; i--) {
		if (!scs[i])
			continue;
		if (scs[i]->parent)
			pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
		else if (!IS_ERR_OR_NULL(dev->pm_domain))
			pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
	}
}

int gdsc_register(struct gdsc_desc *desc,
		  struct reset_controller_dev *rcdev, struct regmap *regmap)
{
@@ -555,30 +572,27 @@ int gdsc_register(struct gdsc_desc *desc,
		if (!scs[i])
			continue;
		if (scs[i]->parent)
			pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
			ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
		else if (!IS_ERR_OR_NULL(dev->pm_domain))
			pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
			ret = pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
		if (ret)
			goto err_pm_subdomain_remove;
	}

	return of_genpd_add_provider_onecell(dev->of_node, data);

err_pm_subdomain_remove:
	gdsc_pm_subdomain_remove(desc, i);

	return ret;
}

void gdsc_unregister(struct gdsc_desc *desc)
{
	int i;
	struct device *dev = desc->dev;
	struct gdsc **scs = desc->scs;
	size_t num = desc->num;

	/* Remove subdomains */
	for (i = num - 1; i >= 0; i--) {
		if (!scs[i])
			continue;
		if (scs[i]->parent)
			pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
		else if (!IS_ERR_OR_NULL(dev->pm_domain))
			pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
	}
	gdsc_pm_subdomain_remove(desc, num);
	of_genpd_del_provider(dev->of_node);
}