mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
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
Block a user