mirror of https://gitee.com/openkylin/linux.git
ASoC: simple-card: Fix the reference count of device nodes
The reference count of some device nodes is not correctly reset at end of card probe. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
12ffa6fc19
commit
e512e001da
|
@ -105,12 +105,12 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
|
|||
/* get dai->name */
|
||||
ret = snd_soc_of_get_dai_name(np, name);
|
||||
if (ret < 0)
|
||||
goto parse_error;
|
||||
return ret;
|
||||
|
||||
/* parse TDM slot */
|
||||
ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
|
||||
if (ret)
|
||||
goto parse_error;
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* bitclock-inversion, frame-inversion
|
||||
|
@ -130,7 +130,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
|
|||
clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto parse_error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dai->sysclk = clk_get_rate(clk);
|
||||
|
@ -144,12 +144,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
|
|||
dai->sysclk = clk_get_rate(clk);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
parse_error:
|
||||
of_node_put(node);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asoc_simple_card_parse_of(struct device_node *node,
|
||||
|
@ -187,22 +182,26 @@ static int asoc_simple_card_parse_of(struct device_node *node,
|
|||
/* CPU sub-node */
|
||||
ret = -EINVAL;
|
||||
np = of_get_child_by_name(node, "simple-audio-card,cpu");
|
||||
if (np)
|
||||
if (np) {
|
||||
ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
|
||||
&priv->cpu_dai,
|
||||
&dai_link->cpu_of_node,
|
||||
&dai_link->cpu_dai_name);
|
||||
of_node_put(np);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* CODEC sub-node */
|
||||
ret = -EINVAL;
|
||||
np = of_get_child_by_name(node, "simple-audio-card,codec");
|
||||
if (np)
|
||||
if (np) {
|
||||
ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
|
||||
&priv->codec_dai,
|
||||
&dai_link->codec_of_node,
|
||||
&dai_link->codec_dai_name);
|
||||
of_node_put(np);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -248,6 +247,27 @@ static int asoc_simple_card_parse_of(struct device_node *node,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* update the reference count of the devices nodes at end of probe */
|
||||
static int asoc_simple_card_unref(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
struct device_node *np;
|
||||
int num_links;
|
||||
|
||||
for (num_links = 0, dai_link = card->dai_link;
|
||||
num_links < card->num_links;
|
||||
num_links++, dai_link++) {
|
||||
np = (struct device_node *) dai_link->cpu_of_node;
|
||||
if (np)
|
||||
of_node_put(np);
|
||||
np = (struct device_node *) dai_link->codec_of_node;
|
||||
if (np)
|
||||
of_node_put(np);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asoc_simple_card_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct simple_card_data *priv;
|
||||
|
@ -275,7 +295,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
|
|||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "parse error %d\n", ret);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
struct asoc_simple_card_info *cinfo;
|
||||
|
@ -318,7 +338,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
|
|||
|
||||
snd_soc_card_set_drvdata(&priv->snd_card, priv);
|
||||
|
||||
return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
|
||||
|
||||
err:
|
||||
asoc_simple_card_unref(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id asoc_simple_of_match[] = {
|
||||
|
|
Loading…
Reference in New Issue