powerpc/cell: Add missing of_node_put()s in cbe_regs.c
There are several bugs as following: (1) In cbe_get_be_node(), hold the reference returned by of_find_xxx and of_get_xxx OF APIs and use it to call of_node_put(). (2) In cbe_fill_regs_map(), same as above. (3) In cbe_regs_init(), during the iteration of for_each_node_by_type(), the refcount of 'cpu' will be automatically increased and decreased. However, there is a reference escaped out into 'map->cpu_node' and it should be properly handled. Signed-off-by: Liang He <windhl@126.com> [mpe: Drop references before pointer equality test in cbe_get_be_node()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20220701144949.252364-1-windhl@126.com
This commit is contained in:
parent
d9e1c6104d
commit
ad4b323693
|
@ -182,9 +182,16 @@ static struct device_node *__init cbe_get_be_node(int cpu_id)
|
|||
if (WARN_ON_ONCE(!cpu_handle))
|
||||
return np;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
if (of_find_node_by_phandle(cpu_handle[i]) == of_get_cpu_node(cpu_id, NULL))
|
||||
for (i = 0; i < len; i++) {
|
||||
struct device_node *ch_np = of_find_node_by_phandle(cpu_handle[i]);
|
||||
struct device_node *ci_np = of_get_cpu_node(cpu_id, NULL);
|
||||
|
||||
of_node_put(ch_np);
|
||||
of_node_put(ci_np);
|
||||
|
||||
if (ch_np == ci_np)
|
||||
return np;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -193,21 +200,30 @@ static struct device_node *__init cbe_get_be_node(int cpu_id)
|
|||
static void __init cbe_fill_regs_map(struct cbe_regs_map *map)
|
||||
{
|
||||
if(map->be_node) {
|
||||
struct device_node *be, *np;
|
||||
struct device_node *be, *np, *parent_np;
|
||||
|
||||
be = map->be_node;
|
||||
|
||||
for_each_node_by_type(np, "pervasive")
|
||||
if (of_get_parent(np) == be)
|
||||
for_each_node_by_type(np, "pervasive") {
|
||||
parent_np = of_get_parent(np);
|
||||
if (parent_np == be)
|
||||
map->pmd_regs = of_iomap(np, 0);
|
||||
of_node_put(parent_np);
|
||||
}
|
||||
|
||||
for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller")
|
||||
if (of_get_parent(np) == be)
|
||||
for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller") {
|
||||
parent_np = of_get_parent(np);
|
||||
if (parent_np == be)
|
||||
map->iic_regs = of_iomap(np, 2);
|
||||
of_node_put(parent_np);
|
||||
}
|
||||
|
||||
for_each_node_by_type(np, "mic-tm")
|
||||
if (of_get_parent(np) == be)
|
||||
for_each_node_by_type(np, "mic-tm") {
|
||||
parent_np = of_get_parent(np);
|
||||
if (parent_np == be)
|
||||
map->mic_tm_regs = of_iomap(np, 0);
|
||||
of_node_put(parent_np);
|
||||
}
|
||||
} else {
|
||||
struct device_node *cpu;
|
||||
/* That hack must die die die ! */
|
||||
|
@ -261,7 +277,8 @@ void __init cbe_regs_init(void)
|
|||
of_node_put(cpu);
|
||||
return;
|
||||
}
|
||||
map->cpu_node = cpu;
|
||||
of_node_put(map->cpu_node);
|
||||
map->cpu_node = of_node_get(cpu);
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cbe_thread_map *thread = &cbe_thread_map[i];
|
||||
|
|
Loading…
Reference in New Issue