Skip to content

Commit f28783c

Browse files
storulfmehmetb0
authored andcommitted
pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails
BugLink: https://bugs.launchpad.net/bugs/2096827 [ 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]> Signed-off-by: Koichiro Den <[email protected]>
1 parent 48974fd commit f28783c

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
@@ -2129,8 +2129,24 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21292129
}
21302130

21312131
genpd->gd = gd;
2132-
return 0;
2132+
device_initialize(&genpd->dev);
2133+
2134+
if (!genpd_is_dev_name_fw(genpd)) {
2135+
dev_set_name(&genpd->dev, "%s", genpd->name);
2136+
} else {
2137+
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
2138+
if (ret < 0)
2139+
goto put;
21332140

2141+
genpd->device_id = ret;
2142+
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
2143+
}
2144+
2145+
return 0;
2146+
put:
2147+
put_device(&genpd->dev);
2148+
if (genpd->free_states == genpd_free_default_power_state)
2149+
kfree(genpd->states);
21342150
free:
21352151
if (genpd_is_cpu_domain(genpd))
21362152
free_cpumask_var(genpd->cpus);
@@ -2141,6 +2157,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
21412157
static void genpd_free_data(struct generic_pm_domain *genpd)
21422158
{
21432159
put_device(&genpd->dev);
2160+
if (genpd->device_id != -ENXIO)
2161+
ida_free(&genpd_ida, genpd->device_id);
21442162
if (genpd_is_cpu_domain(genpd))
21452163
free_cpumask_var(genpd->cpus);
21462164
if (genpd->free_states)
@@ -2226,20 +2244,6 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22262244
if (ret)
22272245
return ret;
22282246

2229-
device_initialize(&genpd->dev);
2230-
2231-
if (!genpd_is_dev_name_fw(genpd)) {
2232-
dev_set_name(&genpd->dev, "%s", genpd->name);
2233-
} else {
2234-
ret = ida_alloc(&genpd_ida, GFP_KERNEL);
2235-
if (ret < 0) {
2236-
put_device(&genpd->dev);
2237-
return ret;
2238-
}
2239-
genpd->device_id = ret;
2240-
dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
2241-
}
2242-
22432247
mutex_lock(&gpd_list_lock);
22442248
list_add(&genpd->gpd_list_node, &gpd_list);
22452249
mutex_unlock(&gpd_list_lock);
@@ -2280,8 +2284,6 @@ static int genpd_remove(struct generic_pm_domain *genpd)
22802284
genpd_unlock(genpd);
22812285
genpd_debug_remove(genpd);
22822286
cancel_work_sync(&genpd->power_off_work);
2283-
if (genpd->device_id != -ENXIO)
2284-
ida_free(&genpd_ida, genpd->device_id);
22852287
genpd_free_data(genpd);
22862288

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

0 commit comments

Comments
 (0)