diff --git a/sound/soc/tegra-alt/tegra210_adsp_alt.c b/sound/soc/tegra-alt/tegra210_adsp_alt.c index ee7f5fdb..a4936b7e 100644 --- a/sound/soc/tegra-alt/tegra210_adsp_alt.c +++ b/sound/soc/tegra-alt/tegra210_adsp_alt.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -1909,6 +1911,7 @@ static int tegra210_adsp_codec_probe(struct snd_soc_codec *codec) static struct snd_soc_codec_driver tegra210_adsp_codec = { .probe = tegra210_adsp_codec_probe, + .idle_bias_off = 1, }; static struct snd_soc_platform_driver tegra210_adsp_platform = { @@ -1947,6 +1950,15 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev) pdev->dev.dma_mask = &tegra_dma_mask; pdev->dev.coherent_dma_mask = tegra_dma_mask; + tegra_ape_pd_add_device(&pdev->dev); + pm_genpd_dev_need_save(&pdev->dev, true); + pm_genpd_dev_need_restore(&pdev->dev, true); + + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) + goto err_pm_disable; + + pm_runtime_get_sync(&pdev->dev); /* HACK : Should be handled through dma-engine */ for (i = 0; i < TEGRA210_ADSP_ADMA_CHANNEL_COUNT; i++) { ret = tegra_agic_route_interrupt( @@ -1954,10 +1966,11 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev) TEGRA_AGIC_ADSP); if (ret < 0) { dev_err(&pdev->dev, "Failed to route INT to ADSP"); - return ret; + goto err_pm_disable; } } /* HACK end */ + pm_runtime_put(&pdev->dev); for (i = 0; i < TEGRA210_ADSP_VIRT_REG_MAX; i++) adsp->apps[i].reg = i; @@ -1971,7 +1984,7 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev) ret = snd_soc_register_platform(&pdev->dev, &tegra210_adsp_platform); if (ret) { dev_err(&pdev->dev, "Could not register platform: %d\n", ret); - goto err; + goto err_pm_disable; } ret = snd_soc_register_component(&pdev->dev, &tegra210_adsp_component, @@ -1994,12 +2007,16 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev) err_unregister_platform: snd_soc_unregister_platform(&pdev->dev); -err: +err_pm_disable: + pm_runtime_disable(&pdev->dev); + tegra_ape_pd_remove_device(&pdev->dev); return ret; } static int tegra210_adsp_audio_platform_remove(struct platform_device *pdev) { + pm_runtime_disable(&pdev->dev); + tegra_ape_pd_remove_device(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); return 0; } diff --git a/sound/soc/tegra-alt/tegra210_xbar_alt.c b/sound/soc/tegra-alt/tegra210_xbar_alt.c index 6f983d98..62e2d191 100644 --- a/sound/soc/tegra-alt/tegra210_xbar_alt.c +++ b/sound/soc/tegra-alt/tegra210_xbar_alt.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -82,9 +83,16 @@ static int tegra210_xbar_runtime_resume(struct device *dev) } #ifdef CONFIG_PM_SLEEP +static int tegra210_xbar_child_suspend(struct device *dev, void *data) +{ + return platform_pm_suspend(dev); +} + static int tegra210_xbar_suspend(struct device *dev) { regcache_mark_dirty(xbar->regmap); + device_for_each_child(dev, NULL, tegra210_xbar_child_suspend); + return 0; } #endif @@ -904,6 +912,10 @@ static int tegra210_xbar_probe(struct platform_device *pdev) } regcache_cache_only(xbar->regmap, true); + tegra_ape_pd_add_device(&pdev->dev); + pm_genpd_dev_need_save(&pdev->dev, true); + pm_genpd_dev_need_restore(&pdev->dev, true); + pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra210_xbar_runtime_resume(&pdev->dev); @@ -927,6 +939,7 @@ err_suspend: tegra210_xbar_runtime_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); + tegra_ape_pd_remove_device(&pdev->dev); err_clk_set_parent: clk_set_parent(xbar->clk, parent_clk); err_clk_put_ape: @@ -947,6 +960,8 @@ static int tegra210_xbar_remove(struct platform_device *pdev) if (!pm_runtime_status_suspended(&pdev->dev)) tegra210_xbar_runtime_suspend(&pdev->dev); + tegra_ape_pd_remove_device(&pdev->dev); + devm_clk_put(&pdev->dev, xbar->clk); clk_put(xbar->clk_parent); clk_put(xbar->clk_ape);