Unverified Commit c00018ca authored by Maxim Kochetkov's avatar Maxim Kochetkov Committed by Mark Brown
Browse files

ASoC: dwc: add optional reset support



Some SoC may have resets for I2S subsystem. So add optional reset support.

Signed-off-by: default avatarMaxim Kochetkov <fido_max@inbox.ru>
Link: https://lore.kernel.org/r/20230504071618.52012-1-fido_max@inbox.ru


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent ac9a7868
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -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);
}

+1 −0
Original line number Diff line number Diff line
@@ -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;