Skip to content

Commit 3e3b71d

Browse files
committed
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: 899f445 ("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>
1 parent b8f7bbd commit 3e3b71d

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

drivers/pmdomain/core.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,8 +2172,24 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21722172
}
21732173

21742174
genpd->gd = gd;
2175-
return 0;
2175+
device_initialize(&genpd->dev);
2176+
2177+
if (!genpd_is_dev_name_fw(genpd)) {
2178+
dev_set_name(&genpd->dev, "%s", genpd->name);
2179+
} else {
2180+
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
2181+
if (ret < 0)
2182+
goto put;
21762183

2184+
genpd->device_id = ret;
2185+
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
2186+
}
2187+
2188+
return 0;
2189+
put:
2190+
put_device(&genpd->dev);
2191+
if (genpd->free_states == genpd_free_default_power_state)
2192+
kfree(genpd->states);
21772193
free:
21782194
if (genpd_is_cpu_domain(genpd))
21792195
free_cpumask_var(genpd->cpus);
@@ -2184,6 +2200,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21842200
static void genpd_free_data(struct generic_pm_domain *genpd)
21852201
{
21862202
put_device(&genpd->dev);
2203+
if (genpd->device_id != -ENXIO)
2204+
ida_free(&genpd_ida, genpd->device_id);
21872205
if (genpd_is_cpu_domain(genpd))
21882206
free_cpumask_var(genpd->cpus);
21892207
if (genpd->free_states)
@@ -2272,20 +2290,6 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22722290
if (ret)
22732291
return ret;
22742292

2275-
device_initialize(&genpd->dev);
2276-
2277-
if (!genpd_is_dev_name_fw(genpd)) {
2278-
dev_set_name(&genpd->dev, "%s", genpd->name);
2279-
} else {
2280-
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
2281-
if (ret < 0) {
2282-
put_device(&genpd->dev);
2283-
return ret;
2284-
}
2285-
genpd->device_id = ret;
2286-
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
2287-
}
2288-
22892293
mutex_lock(&gpd_list_lock);
22902294
list_add(&genpd->gpd_list_node, &gpd_list);
22912295
mutex_unlock(&gpd_list_lock);
@@ -2326,8 +2330,6 @@ static int genpd_remove(struct generic_pm_domain *genpd)
23262330
genpd_unlock(genpd);
23272331
genpd_debug_remove(genpd);
23282332
cancel_work_sync(&genpd->power_off_work);
2329-
if (genpd->device_id != -ENXIO)
2330-
ida_free(&genpd_ida, genpd->device_id);
23312333
genpd_free_data(genpd);
23322334

23332335
pr_debug("%s: removed %s\n", __func__, dev_name(&genpd->dev));

0 commit comments

Comments
 (0)