|
@@ -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[] = {
|