mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
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:
parent
cfe9b47ef1
commit
75e918aa87
|
|
@ -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[] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user