diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/soc-core.c | 99 |
1 files changed, 79 insertions, 20 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ffae370b45df..717db0e6499b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -780,30 +780,54 @@ static int soc_resume(struct platform_device *pdev) | |||
780 | #define soc_resume NULL | 780 | #define soc_resume NULL |
781 | #endif | 781 | #endif |
782 | 782 | ||
783 | /* probes a new socdev */ | 783 | static void snd_soc_instantiate_card(struct snd_soc_card *card) |
784 | static int soc_probe(struct platform_device *pdev) | 784 | { |
785 | { | 785 | struct platform_device *pdev = container_of(card->dev, |
786 | int ret = 0, i; | 786 | struct platform_device, |
787 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 787 | dev); |
788 | struct snd_soc_card *card = socdev->card; | 788 | struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev; |
789 | struct snd_soc_platform *platform = card->platform; | 789 | struct snd_soc_platform *platform; |
790 | struct snd_soc_codec_device *codec_dev = socdev->codec_dev; | 790 | struct snd_soc_dai *dai; |
791 | 791 | int i, found, ret; | |
792 | /* Bodge while we push things out of socdev */ | 792 | |
793 | card->socdev = socdev; | 793 | if (card->instantiated) |
794 | return; | ||
795 | |||
796 | found = 0; | ||
797 | list_for_each_entry(platform, &platform_list, list) | ||
798 | if (card->platform == platform) { | ||
799 | found = 1; | ||
800 | break; | ||
801 | } | ||
802 | if (!found) { | ||
803 | dev_dbg(card->dev, "Platform %s not registered\n", | ||
804 | card->platform->name); | ||
805 | return; | ||
806 | } | ||
794 | 807 | ||
795 | /* Bodge while we unpick instantiation */ | 808 | for (i = 0; i < card->num_links; i++) { |
796 | card->dev = &pdev->dev; | 809 | found = 0; |
797 | ret = snd_soc_register_card(card); | 810 | list_for_each_entry(dai, &dai_list, list) |
798 | if (ret != 0) { | 811 | if (card->dai_link[i].cpu_dai == dai) { |
799 | dev_err(&pdev->dev, "Failed to register card\n"); | 812 | found = 1; |
800 | return ret; | 813 | break; |
814 | } | ||
815 | if (!found) { | ||
816 | dev_dbg(card->dev, "DAI %s not registered\n", | ||
817 | card->dai_link[i].cpu_dai->name); | ||
818 | return; | ||
819 | } | ||
801 | } | 820 | } |
802 | 821 | ||
822 | /* Note that we do not current check for codec components */ | ||
823 | |||
824 | dev_dbg(card->dev, "All components present, instantiating\n"); | ||
825 | |||
826 | /* Found everything, bring it up */ | ||
803 | if (card->probe) { | 827 | if (card->probe) { |
804 | ret = card->probe(pdev); | 828 | ret = card->probe(pdev); |
805 | if (ret < 0) | 829 | if (ret < 0) |
806 | return ret; | 830 | return; |
807 | } | 831 | } |
808 | 832 | ||
809 | for (i = 0; i < card->num_links; i++) { | 833 | for (i = 0; i < card->num_links; i++) { |
@@ -834,7 +858,9 @@ static int soc_probe(struct platform_device *pdev) | |||
834 | INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); | 858 | INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); |
835 | #endif | 859 | #endif |
836 | 860 | ||
837 | return 0; | 861 | card->instantiated = 1; |
862 | |||
863 | return; | ||
838 | 864 | ||
839 | platform_err: | 865 | platform_err: |
840 | if (codec_dev->remove) | 866 | if (codec_dev->remove) |
@@ -849,8 +875,38 @@ cpu_dai_err: | |||
849 | 875 | ||
850 | if (card->remove) | 876 | if (card->remove) |
851 | card->remove(pdev); | 877 | card->remove(pdev); |
878 | } | ||
852 | 879 | ||
853 | return ret; | 880 | /* |
881 | * Attempt to initialise any uninitalised cards. Must be called with | ||
882 | * client_mutex. | ||
883 | */ | ||
884 | static void snd_soc_instantiate_cards(void) | ||
885 | { | ||
886 | struct snd_soc_card *card; | ||
887 | list_for_each_entry(card, &card_list, list) | ||
888 | snd_soc_instantiate_card(card); | ||
889 | } | ||
890 | |||
891 | /* probes a new socdev */ | ||
892 | static int soc_probe(struct platform_device *pdev) | ||
893 | { | ||
894 | int ret = 0; | ||
895 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
896 | struct snd_soc_card *card = socdev->card; | ||
897 | |||
898 | /* Bodge while we push things out of socdev */ | ||
899 | card->socdev = socdev; | ||
900 | |||
901 | /* Bodge while we unpick instantiation */ | ||
902 | card->dev = &pdev->dev; | ||
903 | ret = snd_soc_register_card(card); | ||
904 | if (ret != 0) { | ||
905 | dev_err(&pdev->dev, "Failed to register card\n"); | ||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | return 0; | ||
854 | } | 910 | } |
855 | 911 | ||
856 | /* removes a socdev */ | 912 | /* removes a socdev */ |
@@ -1994,6 +2050,7 @@ static int snd_soc_register_card(struct snd_soc_card *card) | |||
1994 | 2050 | ||
1995 | mutex_lock(&client_mutex); | 2051 | mutex_lock(&client_mutex); |
1996 | list_add(&card->list, &card_list); | 2052 | list_add(&card->list, &card_list); |
2053 | snd_soc_instantiate_cards(); | ||
1997 | mutex_unlock(&client_mutex); | 2054 | mutex_unlock(&client_mutex); |
1998 | 2055 | ||
1999 | dev_dbg(card->dev, "Registered card '%s'\n", card->name); | 2056 | dev_dbg(card->dev, "Registered card '%s'\n", card->name); |
@@ -2039,6 +2096,7 @@ int snd_soc_register_dai(struct snd_soc_dai *dai) | |||
2039 | 2096 | ||
2040 | mutex_lock(&client_mutex); | 2097 | mutex_lock(&client_mutex); |
2041 | list_add(&dai->list, &dai_list); | 2098 | list_add(&dai->list, &dai_list); |
2099 | snd_soc_instantiate_cards(); | ||
2042 | mutex_unlock(&client_mutex); | 2100 | mutex_unlock(&client_mutex); |
2043 | 2101 | ||
2044 | pr_debug("Registered DAI '%s'\n", dai->name); | 2102 | pr_debug("Registered DAI '%s'\n", dai->name); |
@@ -2117,6 +2175,7 @@ int snd_soc_register_platform(struct snd_soc_platform *platform) | |||
2117 | 2175 | ||
2118 | mutex_lock(&client_mutex); | 2176 | mutex_lock(&client_mutex); |
2119 | list_add(&platform->list, &platform_list); | 2177 | list_add(&platform->list, &platform_list); |
2178 | snd_soc_instantiate_cards(); | ||
2120 | mutex_unlock(&client_mutex); | 2179 | mutex_unlock(&client_mutex); |
2121 | 2180 | ||
2122 | pr_debug("Registered platform '%s'\n", platform->name); | 2181 | pr_debug("Registered platform '%s'\n", platform->name); |