diff options
author | Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu@amd.com> | 2015-12-04 18:40:31 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-12-07 14:52:02 -0500 |
commit | f48303122d2fd94b719e546cf8a39d412c7eee69 (patch) | |
tree | f57a5429b0ef2e8f08e8d601c42fa55bea5c6186 | |
parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (diff) |
ASoC: dwc: add runtime suspend/resume functionality
When DW controller is in master mode, it can disable/enable clock
during the device runtime suspend/resume sequence.
Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/dwc/designware_i2s.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 6e6a70c5c2bd..3d7754c115ec 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/pm_runtime.h> | ||
21 | #include <sound/designware_i2s.h> | 22 | #include <sound/designware_i2s.h> |
22 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 24 | #include <sound/pcm_params.h> |
@@ -394,6 +395,23 @@ static const struct snd_soc_component_driver dw_i2s_component = { | |||
394 | }; | 395 | }; |
395 | 396 | ||
396 | #ifdef CONFIG_PM | 397 | #ifdef CONFIG_PM |
398 | static int dw_i2s_runtime_suspend(struct device *dev) | ||
399 | { | ||
400 | struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev); | ||
401 | |||
402 | if (dw_dev->capability & DW_I2S_MASTER) | ||
403 | clk_disable(dw_dev->clk); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int dw_i2s_runtime_resume(struct device *dev) | ||
408 | { | ||
409 | struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev); | ||
410 | |||
411 | if (dw_dev->capability & DW_I2S_MASTER) | ||
412 | clk_enable(dw_dev->clk); | ||
413 | return 0; | ||
414 | } | ||
397 | 415 | ||
398 | static int dw_i2s_suspend(struct snd_soc_dai *dai) | 416 | static int dw_i2s_suspend(struct snd_soc_dai *dai) |
399 | { | 417 | { |
@@ -649,7 +667,7 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
649 | goto err_clk_disable; | 667 | goto err_clk_disable; |
650 | } | 668 | } |
651 | } | 669 | } |
652 | 670 | pm_runtime_enable(&pdev->dev); | |
653 | return 0; | 671 | return 0; |
654 | 672 | ||
655 | err_clk_disable: | 673 | err_clk_disable: |
@@ -665,6 +683,7 @@ static int dw_i2s_remove(struct platform_device *pdev) | |||
665 | if (dev->capability & DW_I2S_MASTER) | 683 | if (dev->capability & DW_I2S_MASTER) |
666 | clk_disable_unprepare(dev->clk); | 684 | clk_disable_unprepare(dev->clk); |
667 | 685 | ||
686 | pm_runtime_disable(&pdev->dev); | ||
668 | return 0; | 687 | return 0; |
669 | } | 688 | } |
670 | 689 | ||
@@ -677,12 +696,17 @@ static const struct of_device_id dw_i2s_of_match[] = { | |||
677 | MODULE_DEVICE_TABLE(of, dw_i2s_of_match); | 696 | MODULE_DEVICE_TABLE(of, dw_i2s_of_match); |
678 | #endif | 697 | #endif |
679 | 698 | ||
699 | static const struct dev_pm_ops dwc_pm_ops = { | ||
700 | SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL) | ||
701 | }; | ||
702 | |||
680 | static struct platform_driver dw_i2s_driver = { | 703 | static struct platform_driver dw_i2s_driver = { |
681 | .probe = dw_i2s_probe, | 704 | .probe = dw_i2s_probe, |
682 | .remove = dw_i2s_remove, | 705 | .remove = dw_i2s_remove, |
683 | .driver = { | 706 | .driver = { |
684 | .name = "designware-i2s", | 707 | .name = "designware-i2s", |
685 | .of_match_table = of_match_ptr(dw_i2s_of_match), | 708 | .of_match_table = of_match_ptr(dw_i2s_of_match), |
709 | .pm = &dwc_pm_ops, | ||
686 | }, | 710 | }, |
687 | }; | 711 | }; |
688 | 712 | ||