pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails

When the ida allocation fails we need to free up the previously allocated
memory before returning the error code. Let's fix this and while at it,
let's also move the ida allocation to genpd_alloc_data() and the freeing to
genpd_free_data(), as it better belongs there.

Fixes: 899f44531f ("pmdomain: core: Add GENPD_FLAG_DEV_NAME_FW flag")
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Message-ID: <20241122134207.157283-3-ulf.hansson@linaro.org>
This commit is contained in:
Ulf Hansson 2024-11-22 14:42:03 +01:00
parent b8f7bbd1f4
commit 3e3b71d35a

View File

@ -2172,8 +2172,24 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
}
genpd->gd = gd;
return 0;
device_initialize(&genpd->dev);
if (!genpd_is_dev_name_fw(genpd)) {
dev_set_name(&genpd->dev, "%s", genpd->name);
} else {
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
if (ret < 0)
goto put;
genpd->device_id = ret;
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
}
return 0;
put:
put_device(&genpd->dev);
if (genpd->free_states == genpd_free_default_power_state)
kfree(genpd->states);
free:
if (genpd_is_cpu_domain(genpd))
free_cpumask_var(genpd->cpus);
@ -2184,6 +2200,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
static void genpd_free_data(struct generic_pm_domain *genpd)
{
put_device(&genpd->dev);
if (genpd->device_id != -ENXIO)
ida_free(&genpd_ida, genpd->device_id);
if (genpd_is_cpu_domain(genpd))
free_cpumask_var(genpd->cpus);
if (genpd->free_states)
@ -2272,20 +2290,6 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
if (ret)
return ret;
device_initialize(&genpd->dev);
if (!genpd_is_dev_name_fw(genpd)) {
dev_set_name(&genpd->dev, "%s", genpd->name);
} else {
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
if (ret < 0) {
put_device(&genpd->dev);
return ret;
}
genpd->device_id = ret;
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
}
mutex_lock(&gpd_list_lock);
list_add(&genpd->gpd_list_node, &gpd_list);
mutex_unlock(&gpd_list_lock);
@ -2326,8 +2330,6 @@ static int genpd_remove(struct generic_pm_domain *genpd)
genpd_unlock(genpd);
genpd_debug_remove(genpd);
cancel_work_sync(&genpd->power_off_work);
if (genpd->device_id != -ENXIO)
ida_free(&genpd_ida, genpd->device_id);
genpd_free_data(genpd);
pr_debug("%s: removed %s\n", __func__, dev_name(&genpd->dev));