diff options
Diffstat (limited to 'sound/soc/stm/stm32_i2s.c')
-rw-r--r-- | sound/soc/stm/stm32_i2s.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 3e7226a53e53..7c4d63c33f15 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -831,25 +831,33 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, /* Get clocks */ i2s->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(i2s->pclk)) { - dev_err(&pdev->dev, "Could not get pclk\n"); + if (PTR_ERR(i2s->pclk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Could not get pclk: %ld\n", + PTR_ERR(i2s->pclk)); return PTR_ERR(i2s->pclk); } i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk"); if (IS_ERR(i2s->i2sclk)) { - dev_err(&pdev->dev, "Could not get i2sclk\n"); + if (PTR_ERR(i2s->i2sclk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Could not get i2sclk: %ld\n", + PTR_ERR(i2s->i2sclk)); return PTR_ERR(i2s->i2sclk); } i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); if (IS_ERR(i2s->x8kclk)) { - dev_err(&pdev->dev, "missing x8k parent clock\n"); + if (PTR_ERR(i2s->x8kclk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Could not get x8k parent clock: %ld\n", + PTR_ERR(i2s->x8kclk)); return PTR_ERR(i2s->x8kclk); } i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); if (IS_ERR(i2s->x11kclk)) { - dev_err(&pdev->dev, "missing x11k parent clock\n"); + if (PTR_ERR(i2s->x11kclk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Could not get x11k parent clock: %ld\n", + PTR_ERR(i2s->x11kclk)); return PTR_ERR(i2s->x11kclk); } @@ -866,12 +874,24 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, } /* Reset */ - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (!IS_ERR(rst)) { - reset_control_assert(rst); - udelay(2); - reset_control_deassert(rst); + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); + if (IS_ERR(rst)) { + if (PTR_ERR(rst) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Reset controller error %ld\n", + PTR_ERR(rst)); + return PTR_ERR(rst); } + reset_control_assert(rst); + udelay(2); + reset_control_deassert(rst); + + return 0; +} + +static int stm32_i2s_remove(struct platform_device *pdev) +{ + snd_dmaengine_pcm_unregister(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } @@ -903,42 +923,51 @@ static int stm32_i2s_probe(struct platform_device *pdev) i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk", i2s->base, i2s->regmap_conf); if (IS_ERR(i2s->regmap)) { - dev_err(&pdev->dev, "regmap init failed\n"); + if (PTR_ERR(i2s->regmap) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Regmap init error %ld\n", + PTR_ERR(i2s->regmap)); return PTR_ERR(i2s->regmap); } - ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component, - i2s->dai_drv, 1); - if (ret) + ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0); + if (ret) { + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); return ret; + } - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, - &stm32_i2s_pcm_config, 0); - if (ret) + ret = snd_soc_register_component(&pdev->dev, &stm32_i2s_component, + i2s->dai_drv, 1); + if (ret) { + snd_dmaengine_pcm_unregister(&pdev->dev); return ret; + } /* Set SPI/I2S in i2s mode */ ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD); if (ret) - return ret; + goto error; ret = regmap_read(i2s->regmap, STM32_I2S_IPIDR_REG, &val); if (ret) - return ret; + goto error; if (val == I2S_IPIDR_NUMBER) { ret = regmap_read(i2s->regmap, STM32_I2S_HWCFGR_REG, &val); if (ret) - return ret; + goto error; if (!FIELD_GET(I2S_HWCFGR_I2S_SUPPORT_MASK, val)) { dev_err(&pdev->dev, "Device does not support i2s mode\n"); - return -EPERM; + ret = -EPERM; + goto error; } ret = regmap_read(i2s->regmap, STM32_I2S_VERR_REG, &val); + if (ret) + goto error; dev_dbg(&pdev->dev, "I2S version: %lu.%lu registered\n", FIELD_GET(I2S_VERR_MAJ_MASK, val), @@ -946,6 +975,11 @@ static int stm32_i2s_probe(struct platform_device *pdev) } return ret; + +error: + stm32_i2s_remove(pdev); + + return ret; } MODULE_DEVICE_TABLE(of, stm32_i2s_ids); @@ -981,6 +1015,7 @@ static struct platform_driver stm32_i2s_driver = { .pm = &stm32_i2s_pm_ops, }, .probe = stm32_i2s_probe, + .remove = stm32_i2s_remove, }; module_platform_driver(stm32_i2s_driver); |