Skip to content

Commit

Permalink
ASoC: simple-card: Fix the reference count of device nodes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
moinejf authored and broonie committed Mar 14, 2014
1 parent 12ffa6f commit e512e00
Showing 1 changed file with 37 additions and 13 deletions.
50 changes: 37 additions & 13 deletions sound/soc/generic/simple-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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[] = {
Expand Down

0 comments on commit e512e00

Please sign in to comment.