]>
Commit | Line | Data |
---|---|---|
59d24dff SL |
1 | From d24a41764912ea9a45a4d49667d24486e694d753 Mon Sep 17 00:00:00 2001 |
2 | From: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
3 | Date: Wed, 14 Nov 2018 14:58:20 +0200 | |
4 | Subject: ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred | |
5 | probing | |
6 | ||
7 | [ Upstream commit 76836fd354922ebe4798a64fda01f8dc6a8b0984 ] | |
8 | ||
9 | The machine driver fails to probe in next-20181113 with: | |
10 | ||
11 | [ 2.539093] omap-abe-twl6040 sound: ASoC: CODEC DAI twl6040-legacy not registered | |
12 | [ 2.546630] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -517 | |
13 | ... | |
14 | [ 3.693206] omap-abe-twl6040 sound: ASoC: Both platform name/of_node are set for TWL6040 | |
15 | [ 3.701446] omap-abe-twl6040 sound: ASoC: failed to init link TWL6040 | |
16 | [ 3.708007] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -22 | |
17 | [ 3.715148] omap-abe-twl6040: probe of sound failed with error -22 | |
18 | ||
19 | Bisect pointed to a merge commit: | |
20 | first bad commit: [0f688ab20a540aafa984c5dbd68a71debebf4d7f] Merge remote-tracking branch 'net-next/master' | |
21 | ||
22 | and a diff between a working kernel does not reveal anything which would | |
23 | explain the change in behavior. | |
24 | ||
25 | Further investigation showed that on the second try of loading fails | |
26 | because the dai_link->platform is no longer NULL and it might be pointing | |
27 | to uninitialized memory. | |
28 | ||
29 | The fix is to move the snd_soc_dai_link and snd_soc_card inside of the | |
30 | abe_twl6040 struct, which is dynamically allocated every time the driver | |
31 | probes. | |
32 | ||
33 | Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
34 | Signed-off-by: Mark Brown <broonie@kernel.org> | |
35 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
36 | --- | |
37 | sound/soc/omap/omap-abe-twl6040.c | 67 +++++++++++++------------------ | |
38 | 1 file changed, 29 insertions(+), 38 deletions(-) | |
39 | ||
40 | diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c | |
41 | index 89fe95e877db..07af30017b48 100644 | |
42 | --- a/sound/soc/omap/omap-abe-twl6040.c | |
43 | +++ b/sound/soc/omap/omap-abe-twl6040.c | |
44 | @@ -36,6 +36,8 @@ | |
45 | #include "../codecs/twl6040.h" | |
46 | ||
47 | struct abe_twl6040 { | |
48 | + struct snd_soc_card card; | |
49 | + struct snd_soc_dai_link dai_links[2]; | |
50 | int jack_detection; /* board can detect jack events */ | |
51 | int mclk_freq; /* MCLK frequency speed for twl6040 */ | |
52 | }; | |
53 | @@ -208,40 +210,10 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) | |
54 | ARRAY_SIZE(dmic_audio_map)); | |
55 | } | |
56 | ||
57 | -/* Digital audio interface glue - connects codec <--> CPU */ | |
58 | -static struct snd_soc_dai_link abe_twl6040_dai_links[] = { | |
59 | - { | |
60 | - .name = "TWL6040", | |
61 | - .stream_name = "TWL6040", | |
62 | - .codec_dai_name = "twl6040-legacy", | |
63 | - .codec_name = "twl6040-codec", | |
64 | - .init = omap_abe_twl6040_init, | |
65 | - .ops = &omap_abe_ops, | |
66 | - }, | |
67 | - { | |
68 | - .name = "DMIC", | |
69 | - .stream_name = "DMIC Capture", | |
70 | - .codec_dai_name = "dmic-hifi", | |
71 | - .codec_name = "dmic-codec", | |
72 | - .init = omap_abe_dmic_init, | |
73 | - .ops = &omap_abe_dmic_ops, | |
74 | - }, | |
75 | -}; | |
76 | - | |
77 | -/* Audio machine driver */ | |
78 | -static struct snd_soc_card omap_abe_card = { | |
79 | - .owner = THIS_MODULE, | |
80 | - | |
81 | - .dapm_widgets = twl6040_dapm_widgets, | |
82 | - .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), | |
83 | - .dapm_routes = audio_map, | |
84 | - .num_dapm_routes = ARRAY_SIZE(audio_map), | |
85 | -}; | |
86 | - | |
87 | static int omap_abe_probe(struct platform_device *pdev) | |
88 | { | |
89 | struct device_node *node = pdev->dev.of_node; | |
90 | - struct snd_soc_card *card = &omap_abe_card; | |
91 | + struct snd_soc_card *card; | |
92 | struct device_node *dai_node; | |
93 | struct abe_twl6040 *priv; | |
94 | int num_links = 0; | |
95 | @@ -252,12 +224,18 @@ static int omap_abe_probe(struct platform_device *pdev) | |
96 | return -ENODEV; | |
97 | } | |
98 | ||
99 | - card->dev = &pdev->dev; | |
100 | - | |
101 | priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); | |
102 | if (priv == NULL) | |
103 | return -ENOMEM; | |
104 | ||
105 | + card = &priv->card; | |
106 | + card->dev = &pdev->dev; | |
107 | + card->owner = THIS_MODULE; | |
108 | + card->dapm_widgets = twl6040_dapm_widgets; | |
109 | + card->num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets); | |
110 | + card->dapm_routes = audio_map; | |
111 | + card->num_dapm_routes = ARRAY_SIZE(audio_map); | |
112 | + | |
113 | if (snd_soc_of_parse_card_name(card, "ti,model")) { | |
114 | dev_err(&pdev->dev, "Card name is not provided\n"); | |
115 | return -ENODEV; | |
116 | @@ -274,14 +252,27 @@ static int omap_abe_probe(struct platform_device *pdev) | |
117 | dev_err(&pdev->dev, "McPDM node is not provided\n"); | |
118 | return -EINVAL; | |
119 | } | |
120 | - abe_twl6040_dai_links[0].cpu_of_node = dai_node; | |
121 | - abe_twl6040_dai_links[0].platform_of_node = dai_node; | |
122 | + | |
123 | + priv->dai_links[0].name = "DMIC"; | |
124 | + priv->dai_links[0].stream_name = "TWL6040"; | |
125 | + priv->dai_links[0].cpu_of_node = dai_node; | |
126 | + priv->dai_links[0].platform_of_node = dai_node; | |
127 | + priv->dai_links[0].codec_dai_name = "twl6040-legacy"; | |
128 | + priv->dai_links[0].codec_name = "twl6040-codec"; | |
129 | + priv->dai_links[0].init = omap_abe_twl6040_init; | |
130 | + priv->dai_links[0].ops = &omap_abe_ops; | |
131 | ||
132 | dai_node = of_parse_phandle(node, "ti,dmic", 0); | |
133 | if (dai_node) { | |
134 | num_links = 2; | |
135 | - abe_twl6040_dai_links[1].cpu_of_node = dai_node; | |
136 | - abe_twl6040_dai_links[1].platform_of_node = dai_node; | |
137 | + priv->dai_links[1].name = "TWL6040"; | |
138 | + priv->dai_links[1].stream_name = "DMIC Capture"; | |
139 | + priv->dai_links[1].cpu_of_node = dai_node; | |
140 | + priv->dai_links[1].platform_of_node = dai_node; | |
141 | + priv->dai_links[1].codec_dai_name = "dmic-hifi"; | |
142 | + priv->dai_links[1].codec_name = "dmic-codec"; | |
143 | + priv->dai_links[1].init = omap_abe_dmic_init; | |
144 | + priv->dai_links[1].ops = &omap_abe_dmic_ops; | |
145 | } else { | |
146 | num_links = 1; | |
147 | } | |
148 | @@ -300,7 +291,7 @@ static int omap_abe_probe(struct platform_device *pdev) | |
149 | return -ENODEV; | |
150 | } | |
151 | ||
152 | - card->dai_link = abe_twl6040_dai_links; | |
153 | + card->dai_link = priv->dai_links; | |
154 | card->num_links = num_links; | |
155 | ||
156 | snd_soc_card_set_drvdata(card, priv); | |
157 | -- | |
158 | 2.19.1 | |
159 |