aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h1
-rw-r--r--sound/soc/soc-core.c147
2 files changed, 62 insertions, 86 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index b8163ddf94d2..9e238fa2eb17 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -896,7 +896,6 @@ struct snd_soc_pcm_runtime {
896 enum snd_soc_pcm_subclass pcm_subclass; 896 enum snd_soc_pcm_subclass pcm_subclass;
897 struct snd_pcm_ops ops; 897 struct snd_pcm_ops ops;
898 898
899 unsigned int complete:1;
900 unsigned int dev_registered:1; 899 unsigned int dev_registered:1;
901 900
902 long pmdown_time; 901 long pmdown_time;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 61b51b673d49..cab72f87c194 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -54,7 +54,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
54#endif 54#endif
55 55
56static DEFINE_MUTEX(client_mutex); 56static DEFINE_MUTEX(client_mutex);
57static LIST_HEAD(card_list);
58static LIST_HEAD(dai_list); 57static LIST_HEAD(dai_list);
59static LIST_HEAD(platform_list); 58static LIST_HEAD(platform_list);
60static LIST_HEAD(codec_list); 59static LIST_HEAD(codec_list);
@@ -785,15 +784,9 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
785 struct snd_soc_dai *codec_dai, *cpu_dai; 784 struct snd_soc_dai *codec_dai, *cpu_dai;
786 const char *platform_name; 785 const char *platform_name;
787 786
788 if (rtd->complete)
789 return 1;
790 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); 787 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
791 788
792 /* do we already have the CPU DAI for this link ? */ 789 /* Find CPU DAI from registered DAIs*/
793 if (rtd->cpu_dai) {
794 goto find_codec;
795 }
796 /* no, then find CPU DAI from registered DAIs*/
797 list_for_each_entry(cpu_dai, &dai_list, list) { 790 list_for_each_entry(cpu_dai, &dai_list, list) {
798 if (dai_link->cpu_dai_of_node) { 791 if (dai_link->cpu_dai_of_node) {
799 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 792 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
@@ -804,18 +797,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
804 } 797 }
805 798
806 rtd->cpu_dai = cpu_dai; 799 rtd->cpu_dai = cpu_dai;
807 goto find_codec;
808 } 800 }
809 dev_dbg(card->dev, "CPU DAI %s not registered\n",
810 dai_link->cpu_dai_name);
811 801
812find_codec: 802 if (!rtd->cpu_dai) {
813 /* do we already have the CODEC for this link ? */ 803 dev_dbg(card->dev, "CPU DAI %s not registered\n",
814 if (rtd->codec) { 804 dai_link->cpu_dai_name);
815 goto find_platform; 805 return -EPROBE_DEFER;
816 } 806 }
817 807
818 /* no, then find CODEC from registered CODECs*/ 808 /* Find CODEC from registered CODECs */
819 list_for_each_entry(codec, &codec_list, list) { 809 list_for_each_entry(codec, &codec_list, list) {
820 if (dai_link->codec_of_node) { 810 if (dai_link->codec_of_node) {
821 if (codec->dev->of_node != dai_link->codec_of_node) 811 if (codec->dev->of_node != dai_link->codec_of_node)
@@ -837,28 +827,28 @@ find_codec:
837 dai_link->codec_dai_name)) { 827 dai_link->codec_dai_name)) {
838 828
839 rtd->codec_dai = codec_dai; 829 rtd->codec_dai = codec_dai;
840 goto find_platform;
841 } 830 }
842 } 831 }
843 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
844 dai_link->codec_dai_name);
845 832
846 goto find_platform; 833 if (!rtd->codec_dai) {
834 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
835 dai_link->codec_dai_name);
836 return -EPROBE_DEFER;
837 }
847 } 838 }
848 dev_dbg(card->dev, "CODEC %s not registered\n",
849 dai_link->codec_name);
850 839
851find_platform: 840 if (!rtd->codec) {
852 /* do we need a platform? */ 841 dev_dbg(card->dev, "CODEC %s not registered\n",
853 if (rtd->platform) 842 dai_link->codec_name);
854 goto out; 843 return -EPROBE_DEFER;
844 }
855 845
856 /* if there's no platform we match on the empty platform */ 846 /* if there's no platform we match on the empty platform */
857 platform_name = dai_link->platform_name; 847 platform_name = dai_link->platform_name;
858 if (!platform_name && !dai_link->platform_of_node) 848 if (!platform_name && !dai_link->platform_of_node)
859 platform_name = "snd-soc-dummy"; 849 platform_name = "snd-soc-dummy";
860 850
861 /* no, then find one from the set of registered platforms */ 851 /* find one from the set of registered platforms */
862 list_for_each_entry(platform, &platform_list, list) { 852 list_for_each_entry(platform, &platform_list, list) {
863 if (dai_link->platform_of_node) { 853 if (dai_link->platform_of_node) {
864 if (platform->dev->of_node != 854 if (platform->dev->of_node !=
@@ -870,20 +860,16 @@ find_platform:
870 } 860 }
871 861
872 rtd->platform = platform; 862 rtd->platform = platform;
873 goto out;
874 } 863 }
875 864 if (!rtd->platform) {
876 dev_dbg(card->dev, "platform %s not registered\n", 865 dev_dbg(card->dev, "platform %s not registered\n",
877 dai_link->platform_name); 866 dai_link->platform_name);
878 return 0; 867 return -EPROBE_DEFER;
879
880out:
881 /* mark rtd as complete if we found all 4 of our client devices */
882 if (rtd->codec && rtd->codec_dai && rtd->platform && rtd->cpu_dai) {
883 rtd->complete = 1;
884 card->num_rtd++;
885 } 868 }
886 return 1; 869
870 card->num_rtd++;
871
872 return 0;
887} 873}
888 874
889static void soc_remove_codec(struct snd_soc_codec *codec) 875static void soc_remove_codec(struct snd_soc_codec *codec)
@@ -1346,6 +1332,20 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1346} 1332}
1347#endif 1333#endif
1348 1334
1335static int soc_check_aux_dev(struct snd_soc_card *card, int num)
1336{
1337 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1338 struct snd_soc_codec *codec;
1339
1340 /* find CODEC from registered CODECs*/
1341 list_for_each_entry(codec, &codec_list, list) {
1342 if (!strcmp(codec->name, aux_dev->codec_name))
1343 return 0;
1344 }
1345
1346 return -EPROBE_DEFER;
1347}
1348
1349static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1349static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1350{ 1350{
1351 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1351 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
@@ -1366,7 +1366,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1366 } 1366 }
1367 /* codec not found */ 1367 /* codec not found */
1368 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); 1368 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
1369 goto out; 1369 return -EPROBE_DEFER;
1370 1370
1371found: 1371found:
1372 ret = soc_probe_codec(card, codec); 1372 ret = soc_probe_codec(card, codec);
@@ -1416,7 +1416,7 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1416 return 0; 1416 return 0;
1417} 1417}
1418 1418
1419static void snd_soc_instantiate_card(struct snd_soc_card *card) 1419static int snd_soc_instantiate_card(struct snd_soc_card *card)
1420{ 1420{
1421 struct snd_soc_codec *codec; 1421 struct snd_soc_codec *codec;
1422 struct snd_soc_codec_conf *codec_conf; 1422 struct snd_soc_codec_conf *codec_conf;
@@ -1426,19 +1426,18 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1426 1426
1427 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); 1427 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
1428 1428
1429 if (card->instantiated) {
1430 mutex_unlock(&card->mutex);
1431 return;
1432 }
1433
1434 /* bind DAIs */ 1429 /* bind DAIs */
1435 for (i = 0; i < card->num_links; i++) 1430 for (i = 0; i < card->num_links; i++) {
1436 soc_bind_dai_link(card, i); 1431 ret = soc_bind_dai_link(card, i);
1432 if (ret != 0)
1433 goto base_error;
1434 }
1437 1435
1438 /* bind completed ? */ 1436 /* check aux_devs too */
1439 if (card->num_rtd != card->num_links) { 1437 for (i = 0; i < card->num_aux_devs; i++) {
1440 mutex_unlock(&card->mutex); 1438 ret = soc_check_aux_dev(card, i);
1441 return; 1439 if (ret != 0)
1440 goto base_error;
1442 } 1441 }
1443 1442
1444 /* initialize the register cache for each available codec */ 1443 /* initialize the register cache for each available codec */
@@ -1458,10 +1457,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1458 } 1457 }
1459 } 1458 }
1460 ret = snd_soc_init_codec_cache(codec, compress_type); 1459 ret = snd_soc_init_codec_cache(codec, compress_type);
1461 if (ret < 0) { 1460 if (ret < 0)
1462 mutex_unlock(&card->mutex); 1461 goto base_error;
1463 return;
1464 }
1465 } 1462 }
1466 1463
1467 /* card bind complete so register a sound card */ 1464 /* card bind complete so register a sound card */
@@ -1470,8 +1467,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1470 if (ret < 0) { 1467 if (ret < 0) {
1471 pr_err("asoc: can't create sound card for card %s: %d\n", 1468 pr_err("asoc: can't create sound card for card %s: %d\n",
1472 card->name, ret); 1469 card->name, ret);
1473 mutex_unlock(&card->mutex); 1470 goto base_error;
1474 return;
1475 } 1471 }
1476 card->snd_card->dev = card->dev; 1472 card->snd_card->dev = card->dev;
1477 1473
@@ -1611,7 +1607,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1611 card->instantiated = 1; 1607 card->instantiated = 1;
1612 snd_soc_dapm_sync(&card->dapm); 1608 snd_soc_dapm_sync(&card->dapm);
1613 mutex_unlock(&card->mutex); 1609 mutex_unlock(&card->mutex);
1614 return; 1610
1611 return 0;
1615 1612
1616probe_aux_dev_err: 1613probe_aux_dev_err:
1617 for (i = 0; i < card->num_aux_devs; i++) 1614 for (i = 0; i < card->num_aux_devs; i++)
@@ -1626,18 +1623,10 @@ card_probe_error:
1626 1623
1627 snd_card_free(card->snd_card); 1624 snd_card_free(card->snd_card);
1628 1625
1626base_error:
1629 mutex_unlock(&card->mutex); 1627 mutex_unlock(&card->mutex);
1630}
1631 1628
1632/* 1629 return ret;
1633 * Attempt to initialise any uninitialised cards. Must be called with
1634 * client_mutex.
1635 */
1636static void snd_soc_instantiate_cards(void)
1637{
1638 struct snd_soc_card *card;
1639 list_for_each_entry(card, &card_list, list)
1640 snd_soc_instantiate_card(card);
1641} 1630}
1642 1631
1643/* probes a new socdev */ 1632/* probes a new socdev */
@@ -3072,7 +3061,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3072 */ 3061 */
3073int snd_soc_register_card(struct snd_soc_card *card) 3062int snd_soc_register_card(struct snd_soc_card *card)
3074{ 3063{
3075 int i; 3064 int i, ret;
3076 3065
3077 if (!card->name || !card->dev) 3066 if (!card->name || !card->dev)
3078 return -EINVAL; 3067 return -EINVAL;
@@ -3136,14 +3125,11 @@ int snd_soc_register_card(struct snd_soc_card *card)
3136 mutex_init(&card->mutex); 3125 mutex_init(&card->mutex);
3137 mutex_init(&card->dapm_mutex); 3126 mutex_init(&card->dapm_mutex);
3138 3127
3139 mutex_lock(&client_mutex); 3128 ret = snd_soc_instantiate_card(card);
3140 list_add(&card->list, &card_list); 3129 if (ret != 0)
3141 snd_soc_instantiate_cards(); 3130 soc_cleanup_card_debugfs(card);
3142 mutex_unlock(&client_mutex);
3143 3131
3144 dev_dbg(card->dev, "Registered card '%s'\n", card->name); 3132 return ret;
3145
3146 return 0;
3147} 3133}
3148EXPORT_SYMBOL_GPL(snd_soc_register_card); 3134EXPORT_SYMBOL_GPL(snd_soc_register_card);
3149 3135
@@ -3157,9 +3143,6 @@ int snd_soc_unregister_card(struct snd_soc_card *card)
3157{ 3143{
3158 if (card->instantiated) 3144 if (card->instantiated)
3159 soc_cleanup_card_resources(card); 3145 soc_cleanup_card_resources(card);
3160 mutex_lock(&client_mutex);
3161 list_del(&card->list);
3162 mutex_unlock(&client_mutex);
3163 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); 3146 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
3164 3147
3165 return 0; 3148 return 0;
@@ -3256,7 +3239,6 @@ int snd_soc_register_dai(struct device *dev,
3256 3239
3257 mutex_lock(&client_mutex); 3240 mutex_lock(&client_mutex);
3258 list_add(&dai->list, &dai_list); 3241 list_add(&dai->list, &dai_list);
3259 snd_soc_instantiate_cards();
3260 mutex_unlock(&client_mutex); 3242 mutex_unlock(&client_mutex);
3261 3243
3262 pr_debug("Registered DAI '%s'\n", dai->name); 3244 pr_debug("Registered DAI '%s'\n", dai->name);
@@ -3338,9 +3320,6 @@ int snd_soc_register_dais(struct device *dev,
3338 pr_debug("Registered DAI '%s'\n", dai->name); 3320 pr_debug("Registered DAI '%s'\n", dai->name);
3339 } 3321 }
3340 3322
3341 mutex_lock(&client_mutex);
3342 snd_soc_instantiate_cards();
3343 mutex_unlock(&client_mutex);
3344 return 0; 3323 return 0;
3345 3324
3346err: 3325err:
@@ -3398,7 +3377,6 @@ int snd_soc_register_platform(struct device *dev,
3398 3377
3399 mutex_lock(&client_mutex); 3378 mutex_lock(&client_mutex);
3400 list_add(&platform->list, &platform_list); 3379 list_add(&platform->list, &platform_list);
3401 snd_soc_instantiate_cards();
3402 mutex_unlock(&client_mutex); 3380 mutex_unlock(&client_mutex);
3403 3381
3404 pr_debug("Registered platform '%s'\n", platform->name); 3382 pr_debug("Registered platform '%s'\n", platform->name);
@@ -3557,7 +3535,6 @@ int snd_soc_register_codec(struct device *dev,
3557 3535
3558 mutex_lock(&client_mutex); 3536 mutex_lock(&client_mutex);
3559 list_add(&codec->list, &codec_list); 3537 list_add(&codec->list, &codec_list);
3560 snd_soc_instantiate_cards();
3561 mutex_unlock(&client_mutex); 3538 mutex_unlock(&client_mutex);
3562 3539
3563 pr_debug("Registered codec '%s'\n", codec->name); 3540 pr_debug("Registered codec '%s'\n", codec->name);