aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/generic
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2014-03-11 05:03:40 -0400
committerMark Brown <broonie@linaro.org>2014-03-14 15:56:55 -0400
commite512e001dafa54e5ac7244416e340750a4356b41 (patch)
tree270d1e579183a1c5e3ea65b6b42cfbb580b3570b /sound/soc/generic
parent12ffa6fc1958879a81b6af1624c1a2edd83ec04a (diff)
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>
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/simple-card.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5dd47691ba41..dcf37fb69b35 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -105,12 +105,12 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
105 /* get dai->name */ 105 /* get dai->name */
106 ret = snd_soc_of_get_dai_name(np, name); 106 ret = snd_soc_of_get_dai_name(np, name);
107 if (ret < 0) 107 if (ret < 0)
108 goto parse_error; 108 return ret;
109 109
110 /* parse TDM slot */ 110 /* parse TDM slot */
111 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 111 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
112 if (ret) 112 if (ret)
113 goto parse_error; 113 return ret;
114 114
115 /* 115 /*
116 * bitclock-inversion, frame-inversion 116 * bitclock-inversion, frame-inversion
@@ -130,7 +130,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
130 clk = of_clk_get(np, 0); 130 clk = of_clk_get(np, 0);
131 if (IS_ERR(clk)) { 131 if (IS_ERR(clk)) {
132 ret = PTR_ERR(clk); 132 ret = PTR_ERR(clk);
133 goto parse_error; 133 return ret;
134 } 134 }
135 135
136 dai->sysclk = clk_get_rate(clk); 136 dai->sysclk = clk_get_rate(clk);
@@ -144,12 +144,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
144 dai->sysclk = clk_get_rate(clk); 144 dai->sysclk = clk_get_rate(clk);
145 } 145 }
146 146
147 ret = 0; 147 return 0;
148
149parse_error:
150 of_node_put(node);
151
152 return ret;
153} 148}
154 149
155static int asoc_simple_card_parse_of(struct device_node *node, 150static 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,
187 /* CPU sub-node */ 182 /* CPU sub-node */
188 ret = -EINVAL; 183 ret = -EINVAL;
189 np = of_get_child_by_name(node, "simple-audio-card,cpu"); 184 np = of_get_child_by_name(node, "simple-audio-card,cpu");
190 if (np) 185 if (np) {
191 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 186 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
192 &priv->cpu_dai, 187 &priv->cpu_dai,
193 &dai_link->cpu_of_node, 188 &dai_link->cpu_of_node,
194 &dai_link->cpu_dai_name); 189 &dai_link->cpu_dai_name);
190 of_node_put(np);
191 }
195 if (ret < 0) 192 if (ret < 0)
196 return ret; 193 return ret;
197 194
198 /* CODEC sub-node */ 195 /* CODEC sub-node */
199 ret = -EINVAL; 196 ret = -EINVAL;
200 np = of_get_child_by_name(node, "simple-audio-card,codec"); 197 np = of_get_child_by_name(node, "simple-audio-card,codec");
201 if (np) 198 if (np) {
202 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 199 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
203 &priv->codec_dai, 200 &priv->codec_dai,
204 &dai_link->codec_of_node, 201 &dai_link->codec_of_node,
205 &dai_link->codec_dai_name); 202 &dai_link->codec_dai_name);
203 of_node_put(np);
204 }
206 if (ret < 0) 205 if (ret < 0)
207 return ret; 206 return ret;
208 207
@@ -248,6 +247,27 @@ static int asoc_simple_card_parse_of(struct device_node *node,
248 return 0; 247 return 0;
249} 248}
250 249
250/* update the reference count of the devices nodes at end of probe */
251static int asoc_simple_card_unref(struct platform_device *pdev)
252{
253 struct snd_soc_card *card = platform_get_drvdata(pdev);
254 struct snd_soc_dai_link *dai_link;
255 struct device_node *np;
256 int num_links;
257
258 for (num_links = 0, dai_link = card->dai_link;
259 num_links < card->num_links;
260 num_links++, dai_link++) {
261 np = (struct device_node *) dai_link->cpu_of_node;
262 if (np)
263 of_node_put(np);
264 np = (struct device_node *) dai_link->codec_of_node;
265 if (np)
266 of_node_put(np);
267 }
268 return 0;
269}
270
251static int asoc_simple_card_probe(struct platform_device *pdev) 271static int asoc_simple_card_probe(struct platform_device *pdev)
252{ 272{
253 struct simple_card_data *priv; 273 struct simple_card_data *priv;
@@ -275,7 +295,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
275 if (ret < 0) { 295 if (ret < 0) {
276 if (ret != -EPROBE_DEFER) 296 if (ret != -EPROBE_DEFER)
277 dev_err(dev, "parse error %d\n", ret); 297 dev_err(dev, "parse error %d\n", ret);
278 return ret; 298 goto err;
279 } 299 }
280 } else { 300 } else {
281 struct asoc_simple_card_info *cinfo; 301 struct asoc_simple_card_info *cinfo;
@@ -318,7 +338,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
318 338
319 snd_soc_card_set_drvdata(&priv->snd_card, priv); 339 snd_soc_card_set_drvdata(&priv->snd_card, priv);
320 340
321 return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 341 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
342
343err:
344 asoc_simple_card_unref(pdev);
345 return ret;
322} 346}
323 347
324static const struct of_device_id asoc_simple_of_match[] = { 348static const struct of_device_id asoc_simple_of_match[] = {