diff options
Diffstat (limited to 'sound/soc/tegra/tegra30_i2s.c')
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 69 |
1 files changed, 20 insertions, 49 deletions
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 6740df541508..36344f0a64c1 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -35,7 +36,7 @@ #define DRV_NAME "tegra30-i2s" -static int tegra30_i2s_runtime_suspend(struct device *dev) +static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev) { struct tegra30_i2s *i2s = dev_get_drvdata(dev); @@ -46,7 +47,7 @@ static int tegra30_i2s_runtime_suspend(struct device *dev) return 0; } -static int tegra30_i2s_runtime_resume(struct device *dev) +static __maybe_unused int tegra30_i2s_runtime_resume(struct device *dev) { struct tegra30_i2s *i2s = dev_get_drvdata(dev); int ret; @@ -58,8 +59,18 @@ static int tegra30_i2s_runtime_resume(struct device *dev) } regcache_cache_only(i2s->regmap, false); + regcache_mark_dirty(i2s->regmap); + + ret = regcache_sync(i2s->regmap); + if (ret) + goto disable_clocks; return 0; + +disable_clocks: + clk_disable_unprepare(i2s->clk_i2s); + + return ret; } static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, @@ -427,7 +438,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) i2s->playback_i2s_cif = cif_ids[0]; i2s->capture_i2s_cif = cif_ids[1]; - i2s->clk_i2s = clk_get(&pdev->dev, NULL); + i2s->clk_i2s = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(i2s->clk_i2s)) { dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); ret = PTR_ERR(i2s->clk_i2s); @@ -437,7 +448,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) { ret = PTR_ERR(regs); - goto err_clk_put; + goto err; } i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, @@ -445,16 +456,11 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) if (IS_ERR(i2s->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); ret = PTR_ERR(i2s->regmap); - goto err_clk_put; + goto err; } regcache_cache_only(i2s->regmap, true); pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { - ret = tegra30_i2s_runtime_resume(&pdev->dev); - if (ret) - goto err_pm_disable; - } i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->playback_dma_data.maxburst = 4; @@ -464,7 +470,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) &i2s->playback_dma_data.addr); if (ret) { dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret); - goto err_suspend; + goto err_pm_disable; } ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, i2s->playback_fifo_cif); @@ -518,13 +524,8 @@ err_unroute_tx_fifo: tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); err_free_tx_fifo: tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); -err_suspend: - if (!pm_runtime_status_suspended(&pdev->dev)) - tegra30_i2s_runtime_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); -err_clk_put: - clk_put(i2s->clk_i2s); err: return ret; } @@ -533,10 +534,6 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) { struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev); - pm_runtime_disable(&pdev->dev); - if (!pm_runtime_status_suspended(&pdev->dev)) - tegra30_i2s_runtime_suspend(&pdev->dev); - tegra_pcm_platform_unregister(&pdev->dev); snd_soc_unregister_component(&pdev->dev); @@ -546,42 +543,16 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); - clk_put(i2s->clk_i2s); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int tegra30_i2s_suspend(struct device *dev) -{ - struct tegra30_i2s *i2s = dev_get_drvdata(dev); - - regcache_mark_dirty(i2s->regmap); + pm_runtime_disable(&pdev->dev); return 0; } -static int tegra30_i2s_resume(struct device *dev) -{ - struct tegra30_i2s *i2s = dev_get_drvdata(dev); - int ret; - - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put(dev); - return ret; - } - ret = regcache_sync(i2s->regmap); - pm_runtime_put(dev); - - return ret; -} -#endif - static const struct dev_pm_ops tegra30_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, tegra30_i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(tegra30_i2s_suspend, tegra30_i2s_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) }; static struct platform_driver tegra30_i2s_driver = { |