aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorolivier moysan <olivier.moysan@st.com>2017-11-22 10:02:26 -0500
committerMark Brown <broonie@kernel.org>2017-11-27 08:09:49 -0500
commit7dd0d835582ff72b0b3bd0f4fa074967dff1ce82 (patch)
treec408d015506d2b986d1d6c1b16707df3e54cf75e
parent4be0ffdf284046eb7289fa66cc7b2eb8d7efdc64 (diff)
ASoC: stm32: sai: simplify sync modes management
Use function of_find_device_by_node() to retrieve SAI synchro provider device and private data. This allows to remove registration of probed SAI in a linked list. Signed-off-by: Olivier Moysan <olivier.moysan@st.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/stm/stm32_sai.c105
1 files changed, 22 insertions, 83 deletions
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index d6f71a3406e9..0a1f06418bf4 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -28,16 +28,6 @@
28 28
29#include "stm32_sai.h" 29#include "stm32_sai.h"
30 30
31static LIST_HEAD(sync_providers);
32static DEFINE_MUTEX(sync_mutex);
33
34struct sync_provider {
35 struct list_head link;
36 struct device_node *node;
37 int (*sync_conf)(void *data, int synco);
38 void *data;
39};
40
41static const struct stm32_sai_conf stm32_sai_conf_f4 = { 31static const struct stm32_sai_conf stm32_sai_conf_f4 = {
42 .version = SAI_STM32F4, 32 .version = SAI_STM32F4,
43}; 33};
@@ -70,9 +60,8 @@ static int stm32_sai_sync_conf_client(struct stm32_sai_data *sai, int synci)
70 return 0; 60 return 0;
71} 61}
72 62
73static int stm32_sai_sync_conf_provider(void *data, int synco) 63static int stm32_sai_sync_conf_provider(struct stm32_sai_data *sai, int synco)
74{ 64{
75 struct stm32_sai_data *sai = (struct stm32_sai_data *)data;
76 u32 prev_synco; 65 u32 prev_synco;
77 int ret; 66 int ret;
78 67
@@ -103,73 +92,34 @@ static int stm32_sai_sync_conf_provider(void *data, int synco)
103 return 0; 92 return 0;
104} 93}
105 94
106static int stm32_sai_set_sync_provider(struct device_node *np, int synco) 95static int stm32_sai_set_sync(struct stm32_sai_data *sai_client,
96 struct device_node *np_provider,
97 int synco, int synci)
107{ 98{
108 struct sync_provider *provider; 99 struct platform_device *pdev = of_find_device_by_node(np_provider);
100 struct stm32_sai_data *sai_provider;
109 int ret; 101 int ret;
110 102
111 mutex_lock(&sync_mutex); 103 if (!pdev) {
112 list_for_each_entry(provider, &sync_providers, link) { 104 dev_err(&sai_client->pdev->dev,
113 if (provider->node == np) { 105 "Device not found for node %s\n", np_provider->name);
114 ret = provider->sync_conf(provider->data, synco); 106 return -ENODEV;
115 mutex_unlock(&sync_mutex);
116 return ret;
117 }
118 } 107 }
119 mutex_unlock(&sync_mutex);
120 108
121 /* SAI sync provider not found */ 109 sai_provider = platform_get_drvdata(pdev);
122 return -ENODEV; 110 if (!sai_provider) {
123} 111 dev_err(&sai_client->pdev->dev,
124 112 "SAI sync provider data not found\n");
125static int stm32_sai_set_sync(struct stm32_sai_data *sai, 113 return -EINVAL;
126 struct device_node *np_provider, 114 }
127 int synco, int synci)
128{
129 int ret;
130 115
131 /* Configure sync client */ 116 /* Configure sync client */
132 stm32_sai_sync_conf_client(sai, synci); 117 ret = stm32_sai_sync_conf_client(sai_client, synci);
118 if (ret < 0)
119 return ret;
133 120
134 /* Configure sync provider */ 121 /* Configure sync provider */
135 ret = stm32_sai_set_sync_provider(np_provider, synco); 122 return stm32_sai_sync_conf_provider(sai_provider, synco);
136
137 return ret;
138}
139
140static int stm32_sai_sync_add_provider(struct platform_device *pdev,
141 void *data)
142{
143 struct sync_provider *sp;
144
145 sp = devm_kzalloc(&pdev->dev, sizeof(*sp), GFP_KERNEL);
146 if (!sp)
147 return -ENOMEM;
148
149 sp->node = of_node_get(pdev->dev.of_node);
150 sp->data = data;
151 sp->sync_conf = &stm32_sai_sync_conf_provider;
152
153 mutex_lock(&sync_mutex);
154 list_add(&sp->link, &sync_providers);
155 mutex_unlock(&sync_mutex);
156
157 return 0;
158}
159
160static void stm32_sai_sync_del_provider(struct device_node *np)
161{
162 struct sync_provider *sp;
163
164 mutex_lock(&sync_mutex);
165 list_for_each_entry(sp, &sync_providers, link) {
166 if (sp->node == np) {
167 list_del(&sp->link);
168 of_node_put(sp->node);
169 break;
170 }
171 }
172 mutex_unlock(&sync_mutex);
173} 123}
174 124
175static int stm32_sai_probe(struct platform_device *pdev) 125static int stm32_sai_probe(struct platform_device *pdev)
@@ -179,7 +129,6 @@ static int stm32_sai_probe(struct platform_device *pdev)
179 struct reset_control *rst; 129 struct reset_control *rst;
180 struct resource *res; 130 struct resource *res;
181 const struct of_device_id *of_id; 131 const struct of_device_id *of_id;
182 int ret;
183 132
184 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); 133 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
185 if (!sai) 134 if (!sai)
@@ -231,27 +180,17 @@ static int stm32_sai_probe(struct platform_device *pdev)
231 reset_control_deassert(rst); 180 reset_control_deassert(rst);
232 } 181 }
233 182
234 ret = stm32_sai_sync_add_provider(pdev, sai);
235 if (ret < 0)
236 return ret;
237 sai->set_sync = &stm32_sai_set_sync;
238
239 sai->pdev = pdev; 183 sai->pdev = pdev;
184 sai->set_sync = &stm32_sai_set_sync;
240 platform_set_drvdata(pdev, sai); 185 platform_set_drvdata(pdev, sai);
241 186
242 ret = of_platform_populate(np, NULL, NULL, &pdev->dev); 187 return of_platform_populate(np, NULL, NULL, &pdev->dev);
243 if (ret < 0)
244 stm32_sai_sync_del_provider(np);
245
246 return ret;
247} 188}
248 189
249static int stm32_sai_remove(struct platform_device *pdev) 190static int stm32_sai_remove(struct platform_device *pdev)
250{ 191{
251 of_platform_depopulate(&pdev->dev); 192 of_platform_depopulate(&pdev->dev);
252 193
253 stm32_sai_sync_del_provider(pdev->dev.of_node);
254
255 return 0; 194 return 0;
256} 195}
257 196