Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Maxim Kochetkov and committed by
Mark Brown
c00018ca ac9a7868

+22 -6
+21 -6
sound/soc/dwc/dwc-i2s.c
··· 17 17 #include <linux/io.h> 18 18 #include <linux/interrupt.h> 19 19 #include <linux/module.h> 20 + #include <linux/reset.h> 20 21 #include <linux/slab.h> 21 22 #include <linux/pm_runtime.h> 22 23 #include <sound/designware_i2s.h> ··· 649 648 if (IS_ERR(dev->i2s_base)) 650 649 return PTR_ERR(dev->i2s_base); 651 650 651 + dev->reset = devm_reset_control_array_get_optional_shared(&pdev->dev); 652 + if (IS_ERR(dev->reset)) 653 + return PTR_ERR(dev->reset); 654 + 655 + ret = reset_control_deassert(dev->reset); 656 + if (ret) 657 + return ret; 658 + 652 659 dev->dev = &pdev->dev; 653 660 654 661 irq = platform_get_irq_optional(pdev, 0); ··· 665 656 pdev->name, dev); 666 657 if (ret < 0) { 667 658 dev_err(&pdev->dev, "failed to request irq\n"); 668 - return ret; 659 + goto err_assert_reset; 669 660 } 670 661 } 671 662 ··· 685 676 ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); 686 677 } 687 678 if (ret < 0) 688 - return ret; 679 + goto err_assert_reset; 689 680 690 681 if (dev->capability & DW_I2S_MASTER) { 691 682 if (pdata) { 692 683 dev->i2s_clk_cfg = pdata->i2s_clk_cfg; 693 684 if (!dev->i2s_clk_cfg) { 694 685 dev_err(&pdev->dev, "no clock configure method\n"); 695 - return -ENODEV; 686 + ret = -ENODEV; 687 + goto err_assert_reset; 696 688 } 697 689 } 698 690 dev->clk = devm_clk_get(&pdev->dev, clk_id); 699 691 700 - if (IS_ERR(dev->clk)) 701 - return PTR_ERR(dev->clk); 692 + if (IS_ERR(dev->clk)) { 693 + ret = PTR_ERR(dev->clk); 694 + goto err_assert_reset; 695 + } 702 696 703 697 ret = clk_prepare_enable(dev->clk); 704 698 if (ret < 0) 705 - return ret; 699 + goto err_assert_reset; 706 700 } 707 701 708 702 dev_set_drvdata(&pdev->dev, dev); ··· 739 727 err_clk_disable: 740 728 if (dev->capability & DW_I2S_MASTER) 741 729 clk_disable_unprepare(dev->clk); 730 + err_assert_reset: 731 + reset_control_assert(dev->reset); 742 732 return ret; 743 733 } 744 734 ··· 751 737 if (dev->capability & DW_I2S_MASTER) 752 738 clk_disable_unprepare(dev->clk); 753 739 740 + reset_control_assert(dev->reset); 754 741 pm_runtime_disable(&pdev->dev); 755 742 } 756 743
+1
sound/soc/dwc/local.h
··· 89 89 struct dw_i2s_dev { 90 90 void __iomem *i2s_base; 91 91 struct clk *clk; 92 + struct reset_control *reset; 92 93 int active; 93 94 unsigned int capability; 94 95 unsigned int quirks;