mirror of https://gitee.com/openkylin/linux.git
ASoC: simple-card: Fix of-node refcount unbalance in DAI-link parser
The function simple_for_each_link() has a few missing places that forgot unrefereing of-nodes after the use. The main do-while loop may abort when loop=0, and this leaves the node object still referenced. A similar leak is found in the error handling of NULL codec that aborts the loop as well. Last but not least, the inner for_each_child_of_node() loop may abort in the middle, and this leaks the refcount of the iterator node. This patch addresses these missing refcount issues. Signed-off-by: Takashi Iwai <tiwai@suse.de> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
44662f90cd
commit
0b9c9ed6dd
|
@ -442,6 +442,7 @@ static int simple_for_each_link(struct simple_priv *priv,
|
||||||
struct device_node *top = dev->of_node;
|
struct device_node *top = dev->of_node;
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
bool is_top = 0;
|
bool is_top = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/* Check if it has dai-link */
|
/* Check if it has dai-link */
|
||||||
node = of_get_child_by_name(top, PREFIX "dai-link");
|
node = of_get_child_by_name(top, PREFIX "dai-link");
|
||||||
|
@ -456,13 +457,14 @@ static int simple_for_each_link(struct simple_priv *priv,
|
||||||
struct device_node *codec;
|
struct device_node *codec;
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
int num = of_get_child_count(node);
|
int num = of_get_child_count(node);
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* get codec */
|
/* get codec */
|
||||||
codec = of_get_child_by_name(node, is_top ?
|
codec = of_get_child_by_name(node, is_top ?
|
||||||
PREFIX "codec" : "codec");
|
PREFIX "codec" : "codec");
|
||||||
if (!codec)
|
if (!codec) {
|
||||||
return -ENODEV;
|
ret = -ENODEV;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
of_node_put(codec);
|
of_node_put(codec);
|
||||||
|
|
||||||
|
@ -485,14 +487,18 @@ static int simple_for_each_link(struct simple_priv *priv,
|
||||||
else
|
else
|
||||||
ret = func_noml(priv, np, codec, li, is_top);
|
ret = func_noml(priv, np, codec, li, is_top);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return ret;
|
of_node_put(np);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = of_get_next_child(top, node);
|
node = of_get_next_child(top, node);
|
||||||
} while (!is_top && node);
|
} while (!is_top && node);
|
||||||
|
|
||||||
return 0;
|
error:
|
||||||
|
of_node_put(node);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int simple_parse_aux_devs(struct device_node *node,
|
static int simple_parse_aux_devs(struct device_node *node,
|
||||||
|
|
Loading…
Reference in New Issue