summaryrefslogtreecommitdiff
path: root/sound/soc/dwc
diff options
context:
space:
mode:
authorMaxim Kochetkov <fido_max@inbox.ru>2023-05-04 10:16:17 +0300
committerMark Brown <broonie@kernel.org>2023-05-08 08:48:42 +0900
commitc00018cadfbf07b95d10b0e152c4edd7d5d19779 (patch)
tree72a8736487b79ad74e6dca8671cd5d08c99e6927 /sound/soc/dwc
parentac9a78681b921877518763ba0e89202254349d1b (diff)
ASoC: dwc: add optional reset support
Some SoC may have resets for I2S subsystem. So add optional reset support. Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru Link: https://lore.kernel.org/r/20230504071618.52012-1-fido_max@inbox.ru Signed-off-by: Mark Brown <broonie@kernel.org
Diffstat (limited to 'sound/soc/dwc')
-rw-r--r--sound/soc/dwc/dwc-i2s.c27
-rw-r--r--sound/soc/dwc/local.h1
2 files changed, 22 insertions, 6 deletions
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index acdf98b2ee9c..e2b2ba014a2e 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <sound/designware_i2s.h>
@@ -648,6 +649,14 @@ static int dw_i2s_probe(struct platform_device *pdev)
if (IS_ERR(dev->i2s_base))
return PTR_ERR(dev->i2s_base);
+ dev->reset = devm_reset_control_array_get_optional_shared(&pdev->dev);
+ if (IS_ERR(dev->reset))
+ return PTR_ERR(dev->reset);
+
+ ret = reset_control_deassert(dev->reset);
+ if (ret)
+ return ret;
+
dev->dev = &pdev->dev;
irq = platform_get_irq_optional(pdev, 0);
@@ -656,7 +665,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
pdev->name, dev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to request irq\n");
- return ret;
+ goto err_assert_reset;
}
}
@@ -676,24 +685,27 @@ static int dw_i2s_probe(struct platform_device *pdev)
ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
}
if (ret < 0)
- return ret;
+ goto err_assert_reset;
if (dev->capability & DW_I2S_MASTER) {
if (pdata) {
dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
if (!dev->i2s_clk_cfg) {
dev_err(&pdev->dev, "no clock configure method\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_assert_reset;
}
}
dev->clk = devm_clk_get(&pdev->dev, clk_id);
- if (IS_ERR(dev->clk))
- return PTR_ERR(dev->clk);
+ if (IS_ERR(dev->clk)) {
+ ret = PTR_ERR(dev->clk);
+ goto err_assert_reset;
+ }
ret = clk_prepare_enable(dev->clk);
if (ret < 0)
- return ret;
+ goto err_assert_reset;
}
dev_set_drvdata(&pdev->dev, dev);
@@ -727,6 +739,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
err_clk_disable:
if (dev->capability & DW_I2S_MASTER)
clk_disable_unprepare(dev->clk);
+err_assert_reset:
+ reset_control_assert(dev->reset);
return ret;
}
@@ -737,6 +751,7 @@ static void dw_i2s_remove(struct platform_device *pdev)
if (dev->capability & DW_I2S_MASTER)
clk_disable_unprepare(dev->clk);
+ reset_control_assert(dev->reset);
pm_runtime_disable(&pdev->dev);
}
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
index 1c361eb6127e..d64bd4f8fd34 100644
--- a/sound/soc/dwc/local.h
+++ b/sound/soc/dwc/local.h
@@ -89,6 +89,7 @@ union dw_i2s_snd_dma_data {
struct dw_i2s_dev {
void __iomem *i2s_base;
struct clk *clk;
+ struct reset_control *reset;
int active;
unsigned int capability;
unsigned int quirks;