Skip to content

Commit cce4531

Browse files
storulfSasha Levin
authored andcommitted
pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails
[ Upstream commit 3e3b71d ] 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 <[email protected]> Message-ID: <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent deb5267 commit cce4531

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
@@ -2171,8 +2171,24 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21712171
}
21722172

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

2183+
genpd->device_id = ret;
2184+
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
2185+
}
2186+
2187+
return 0;
2188+
put:
2189+
put_device(&genpd->dev);
2190+
if (genpd->free_states == genpd_free_default_power_state)
2191+
kfree(genpd->states);
21762192
free:
21772193
if (genpd_is_cpu_domain(genpd))
21782194
free_cpumask_var(genpd->cpus);
@@ -2183,6 +2199,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21832199
static void genpd_free_data(struct generic_pm_domain *genpd)
21842200
{
21852201
put_device(&genpd->dev);
2202+
if (genpd->device_id != -ENXIO)
2203+
ida_free(&genpd_ida, genpd->device_id);
21862204
if (genpd_is_cpu_domain(genpd))
21872205
free_cpumask_var(genpd->cpus);
21882206
if (genpd->free_states)
@@ -2271,20 +2289,6 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22712289
if (ret)
22722290
return ret;
22732291

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

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

0 commit comments

Comments
 (0)