Commit c6bebefa authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mark Brown

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: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Suggested-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 022c4156
...@@ -1339,20 +1339,35 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv) ...@@ -1339,20 +1339,35 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
/* Create platform device for the secondary PCM */ /* Create platform device for the secondary PCM */
static int i2s_create_secondary_device(struct samsung_i2s_priv *priv) static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
{ {
struct platform_device *pdev; struct platform_device *pdev_sec;
const char *devname;
int ret; int ret;
pdev = platform_device_register_simple("samsung-i2s-sec", -1, NULL, 0); devname = devm_kasprintf(&priv->pdev->dev, GFP_KERNEL, "%s-sec",
if (!pdev) dev_name(&priv->pdev->dev));
if (!devname)
return -ENOMEM; return -ENOMEM;
ret = device_attach(&pdev->dev); pdev_sec = platform_device_alloc(devname, -1);
if (!pdev_sec)
return -ENOMEM;
pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
ret = platform_device_add(pdev_sec);
if (ret < 0) { if (ret < 0) {
dev_info(&pdev->dev, "device_attach() failed\n"); platform_device_put(pdev_sec);
return ret; return ret;
} }
priv->pdev_sec = pdev; ret = device_attach(&pdev_sec->dev);
if (ret <= 0) {
platform_device_unregister(priv->pdev_sec);
dev_info(&pdev_sec->dev, "device_attach() failed\n");
return ret;
}
priv->pdev_sec = pdev_sec;
return 0; return 0;
} }
...@@ -1367,22 +1382,25 @@ static int samsung_i2s_probe(struct platform_device *pdev) ...@@ -1367,22 +1382,25 @@ static int samsung_i2s_probe(struct platform_device *pdev)
{ {
struct i2s_dai *pri_dai, *sec_dai = NULL; struct i2s_dai *pri_dai, *sec_dai = NULL;
struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data; struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
struct resource *res;
u32 regs_base, idma_addr = 0; u32 regs_base, idma_addr = 0;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
const struct samsung_i2s_dai_data *i2s_dai_data; const struct samsung_i2s_dai_data *i2s_dai_data;
int num_dais, ret; const struct platform_device_id *id;
struct samsung_i2s_priv *priv; struct samsung_i2s_priv *priv;
struct resource *res;
int num_dais, ret;
if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
i2s_dai_data = of_device_get_match_data(&pdev->dev); i2s_dai_data = of_device_get_match_data(&pdev->dev);
else } else {
i2s_dai_data = (struct samsung_i2s_dai_data *) id = platform_get_device_id(pdev);
platform_get_device_id(pdev)->driver_data;
/* Nothing to do if it is the secondary device probe */ /* Nothing to do if it is the secondary device probe */
if (!i2s_dai_data) if (!id)
return 0; return 0;
i2s_dai_data = (struct samsung_i2s_dai_data *)id->driver_data;
}
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -1637,8 +1655,6 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = { ...@@ -1637,8 +1655,6 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
{ {
.name = "samsung-i2s", .name = "samsung-i2s",
.driver_data = (kernel_ulong_t)&i2sv3_dai_type, .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
}, {
.name = "samsung-i2s-sec",
}, },
{}, {},
}; };
......
...@@ -185,7 +185,7 @@ static struct snd_soc_dai_link odroid_card_dais[] = { ...@@ -185,7 +185,7 @@ static struct snd_soc_dai_link odroid_card_dais[] = {
.ops = &odroid_card_fe_ops, .ops = &odroid_card_fe_ops,
.name = "Secondary", .name = "Secondary",
.stream_name = "Secondary", .stream_name = "Secondary",
.platform_name = "samsung-i2s-sec", .platform_name = "3830000.i2s-sec",
.dynamic = 1, .dynamic = 1,
.dpcm_playback = 1, .dpcm_playback = 1,
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment