diff options
| -rw-r--r-- | sound/soc/generic/simple-card.c | 50 |
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 | |||
| 149 | parse_error: | ||
| 150 | of_node_put(node); | ||
| 151 | |||
| 152 | return ret; | ||
| 153 | } | 148 | } |
| 154 | 149 | ||
| 155 | static int asoc_simple_card_parse_of(struct device_node *node, | 150 | 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, | |||
| 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 */ | ||
| 251 | static 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 | |||
| 251 | static int asoc_simple_card_probe(struct platform_device *pdev) | 271 | static 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 | |||
| 343 | err: | ||
| 344 | asoc_simple_card_unref(pdev); | ||
| 345 | return ret; | ||
| 322 | } | 346 | } |
| 323 | 347 | ||
| 324 | static const struct of_device_id asoc_simple_of_match[] = { | 348 | static const struct of_device_id asoc_simple_of_match[] = { |
