soc: qcom: rpmh-rsc: manage PM notifiers with devres

rpmh_rsc_probe() registers CPU PM or genpd notifiers before populating
child devices. If child population fails, the CPU PM notifier path is not
unwound and the genpd path needs open-coded cleanup.

Use devm_pm_runtime_enable() for the genpd path and
devm_add_action_or_reset() for both notifier registrations. This makes
probe failure and driver detach use the same cleanup model while keeping
devm_of_platform_populate() responsible for child devices.

Fixes: 25092e6100 ("soc: qcom: rpmh-rsc: Attach RSC to cluster PM domain")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260623015501.31129-1-pengpeng@iscas.ac.cn
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
Pengpeng Hou 2026-06-23 09:55:01 +08:00 committed by Bjorn Andersson
parent cfe9b47ef1
commit 75e918aa87

View File

@ -944,17 +944,30 @@ static int rpmh_rsc_pd_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
static void rpmh_rsc_pd_detach(void *data)
{
dev_pm_genpd_remove_notifier(data);
}
static int rpmh_rsc_pd_attach(struct rsc_drv *drv, struct device *dev)
{
int ret;
pm_runtime_enable(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
return ret;
drv->genpd_nb.notifier_call = rpmh_rsc_pd_callback;
ret = dev_pm_genpd_add_notifier(dev, &drv->genpd_nb);
if (ret)
pm_runtime_disable(dev);
return ret;
return ret;
return devm_add_action_or_reset(dev, rpmh_rsc_pd_detach, dev);
}
static void rpmh_rsc_cpu_pm_unregister(void *data)
{
cpu_pm_unregister_notifier(data);
}
static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *drv)
@ -1107,7 +1120,15 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
return ret;
} else {
drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback;
cpu_pm_register_notifier(&drv->rsc_pm);
ret = cpu_pm_register_notifier(&drv->rsc_pm);
if (ret)
return ret;
ret = devm_add_action_or_reset(&pdev->dev,
rpmh_rsc_cpu_pm_unregister,
&drv->rsc_pm);
if (ret)
return ret;
}
}
@ -1122,13 +1143,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, drv);
drv->dev = &pdev->dev;
ret = devm_of_platform_populate(&pdev->dev);
if (ret && pdev->dev.pm_domain) {
dev_pm_genpd_remove_notifier(&pdev->dev);
pm_runtime_disable(&pdev->dev);
}
return ret;
return devm_of_platform_populate(&pdev->dev);
}
static const struct of_device_id rpmh_drv_match[] = {