summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2019-02-19 10:19:41 -0500
committerMark Brown <broonie@kernel.org>2019-02-19 10:49:42 -0500
commitc6bebefa2f0603fb21ae329521e15461b0486679 (patch)
treea836514595964d7d3c072976d5d57fb5a49e9b49
parent022c4156697b9ae30a00f5cd7cee08ed61554e86 (diff)
ASoC: samsung: i2s: Fix multiple "IIS multi" devices initialization
On some SoCs (e.g. Exynos5433) there are multiple "IIS multi audio interfaces" and the driver will try to register there multiple times same platform device for the secondary FIFO, which of course fails miserably. To fix this we derive the secondary platform device name from the primary device name. The secondary device name will now be <primary_dev_name>-sec instead of fixed "samsung-i2s-sec". The fixed platform_device_id table entry is removed as the secondary device name is now dynamic and device/driver matching is done through driver_override. Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Suggested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Acked-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/samsung/i2s.c50
-rw-r--r--sound/soc/samsung/odroid.c2
2 files changed, 34 insertions, 18 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index cd92bb6e1da1..4231001226f4 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1339,20 +1339,35 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
1339/* Create platform device for the secondary PCM */ 1339/* Create platform device for the secondary PCM */
1340static int i2s_create_secondary_device(struct samsung_i2s_priv *priv) 1340static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
1341{ 1341{
1342 struct platform_device *pdev; 1342 struct platform_device *pdev_sec;
1343 const char *devname;
1343 int ret; 1344 int ret;
1344 1345
1345 pdev = platform_device_register_simple("samsung-i2s-sec", -1, NULL, 0); 1346 devname = devm_kasprintf(&priv->pdev->dev, GFP_KERNEL, "%s-sec",
1346 if (!pdev) 1347 dev_name(&priv->pdev->dev));
1348 if (!devname)
1347 return -ENOMEM; 1349 return -ENOMEM;
1348 1350
1349 ret = device_attach(&pdev->dev); 1351 pdev_sec = platform_device_alloc(devname, -1);
1352 if (!pdev_sec)
1353 return -ENOMEM;
1354
1355 pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
1356
1357 ret = platform_device_add(pdev_sec);
1350 if (ret < 0) { 1358 if (ret < 0) {
1351 dev_info(&pdev->dev, "device_attach() failed\n"); 1359 platform_device_put(pdev_sec);
1352 return ret; 1360 return ret;
1353 } 1361 }
1354 1362
1355 priv->pdev_sec = pdev; 1363 ret = device_attach(&pdev_sec->dev);
1364 if (ret <= 0) {
1365 platform_device_unregister(priv->pdev_sec);
1366 dev_info(&pdev_sec->dev, "device_attach() failed\n");
1367 return ret;
1368 }
1369
1370 priv->pdev_sec = pdev_sec;
1356 1371
1357 return 0; 1372 return 0;
1358} 1373}
@@ -1367,22 +1382,25 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1367{ 1382{
1368 struct i2s_dai *pri_dai, *sec_dai = NULL; 1383 struct i2s_dai *pri_dai, *sec_dai = NULL;
1369 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data; 1384 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1370 struct resource *res;
1371 u32 regs_base, idma_addr = 0; 1385 u32 regs_base, idma_addr = 0;
1372 struct device_node *np = pdev->dev.of_node; 1386 struct device_node *np = pdev->dev.of_node;
1373 const struct samsung_i2s_dai_data *i2s_dai_data; 1387 const struct samsung_i2s_dai_data *i2s_dai_data;
1374 int num_dais, ret; 1388 const struct platform_device_id *id;
1375 struct samsung_i2s_priv *priv; 1389 struct samsung_i2s_priv *priv;
1390 struct resource *res;
1391 int num_dais, ret;
1376 1392
1377 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) 1393 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
1378 i2s_dai_data = of_device_get_match_data(&pdev->dev); 1394 i2s_dai_data = of_device_get_match_data(&pdev->dev);
1379 else 1395 } else {
1380 i2s_dai_data = (struct samsung_i2s_dai_data *) 1396 id = platform_get_device_id(pdev);
1381 platform_get_device_id(pdev)->driver_data;
1382 1397
1383 /* Nothing to do if it is the secondary device probe */ 1398 /* Nothing to do if it is the secondary device probe */
1384 if (!i2s_dai_data) 1399 if (!id)
1385 return 0; 1400 return 0;
1401
1402 i2s_dai_data = (struct samsung_i2s_dai_data *)id->driver_data;
1403 }
1386 1404
1387 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 1405 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1388 if (!priv) 1406 if (!priv)
@@ -1637,8 +1655,6 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
1637 { 1655 {
1638 .name = "samsung-i2s", 1656 .name = "samsung-i2s",
1639 .driver_data = (kernel_ulong_t)&i2sv3_dai_type, 1657 .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
1640 }, {
1641 .name = "samsung-i2s-sec",
1642 }, 1658 },
1643 {}, 1659 {},
1644}; 1660};
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
index 5b2bcd1d3450..bd2c5163dc7f 100644
--- a/sound/soc/samsung/odroid.c
+++ b/sound/soc/samsung/odroid.c
@@ -185,7 +185,7 @@ static struct snd_soc_dai_link odroid_card_dais[] = {
185 .ops = &odroid_card_fe_ops, 185 .ops = &odroid_card_fe_ops,
186 .name = "Secondary", 186 .name = "Secondary",
187 .stream_name = "Secondary", 187 .stream_name = "Secondary",
188 .platform_name = "samsung-i2s-sec", 188 .platform_name = "3830000.i2s-sec",
189 .dynamic = 1, 189 .dynamic = 1,
190 .dpcm_playback = 1, 190 .dpcm_playback = 1,
191 } 191 }