Skip to content

Commit a65bdcf

Browse files
committed
drm: apple: audio: Implement runtime PM support
Signed-off-by: Janne Grunau <j@jannau.net>
1 parent ea76a14 commit a65bdcf

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

drivers/gpu/drm/apple/audio.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/of_graph.h>
1919
#include <linux/of_platform.h>
2020
#include <linux/platform_device.h>
21+
#include <linux/pm_runtime.h>
2122
#include <sound/dmaengine_pcm.h>
2223
#include <sound/pcm.h>
2324
#include <sound/pcm_params.h>
@@ -377,6 +378,7 @@ static int dcp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
377378
if (!dcpaud_connection_up(dcpaud))
378379
return -ENXIO;
379380

381+
WARN_ON(pm_runtime_get_sync(dcpaud->dev) < 0);
380382
ret = dcp_audiosrv_startlink(dcpaud->dcp_dev,
381383
&dcpaud->selected_cookie);
382384
if (ret < 0)
@@ -403,6 +405,8 @@ static int dcp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
403405
case SNDRV_PCM_TRIGGER_STOP:
404406
case SNDRV_PCM_TRIGGER_SUSPEND:
405407
ret = dcp_audiosrv_stoplink(dcpaud->dcp_dev);
408+
pm_runtime_mark_last_busy(dcpaud->dev);
409+
__pm_runtime_put_autosuspend(dcpaud->dev);
406410
if (ret < 0)
407411
return ret;
408412
break;
@@ -605,6 +609,13 @@ static int dcpaud_comp_bind(struct device *dev, struct device *main, void *data)
605609
int index;
606610
int ret;
607611

612+
pm_runtime_get_noresume(dev);
613+
pm_runtime_set_active(dev);
614+
615+
ret = devm_pm_runtime_enable(dev);
616+
if (ret)
617+
return dev_err_probe(dev, ret, "Failed to enable runtime PM: %d\n", ret);
618+
608619
/* find linked DCP instance */
609620
endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
610621
if (endpoint) {
@@ -614,35 +625,34 @@ static int dcpaud_comp_bind(struct device *dev, struct device *main, void *data)
614625
if (!dcp_node || !of_device_is_available(dcp_node)) {
615626
of_node_put(dcp_node);
616627
dev_info(dev, "No audio support\n");
617-
return 0;
628+
goto rpm_put;
618629
}
619630

620631
index = of_property_match_string(dev->of_node, "dma-names", "tx");
621632
if (index < 0) {
622633
dev_err(dev, "No dma-names property\n");
623-
return 0;
634+
goto rpm_put;
624635
}
625636

626637
if (of_parse_phandle_with_args(dev->of_node, "dmas", "#dma-cells", index,
627638
&dma_spec) || !dma_spec.np) {
628639
dev_err(dev, "Failed to parse dmas property\n");
629-
return 0;
640+
goto rpm_put;
630641
}
631642

632643
dcp_pdev = of_find_device_by_node(dcp_node);
633644
of_node_put(dcp_node);
634645
if (!dcp_pdev) {
635646
dev_info(dev, "No DP/HDMI audio device, dcp not ready\n");
636-
return 0;
647+
goto rpm_put;
637648
}
638649
dcpaud->dcp_dev = &dcp_pdev->dev;
639650

640-
641651
dma_pdev = of_find_device_by_node(dma_spec.np);
642652
of_node_put(dma_spec.np);
643653
if (!dma_pdev) {
644654
dev_info(dev, "No DMA device\n");
645-
return 0;
655+
goto rpm_put;
646656
}
647657
dcpaud->dma_dev = &dma_pdev->dev;
648658

@@ -663,6 +673,9 @@ static int dcpaud_comp_bind(struct device *dev, struct device *main, void *data)
663673
DCPAUD_PRODUCTATTRS_MAXSIZE);
664674
}
665675

676+
rpm_put:
677+
pm_runtime_put(dev);
678+
666679
return 0;
667680
}
668681

@@ -718,7 +731,22 @@ static void dcpaud_shutdown(struct platform_device *pdev)
718731
component_del(&pdev->dev, &dcpaud_comp_ops);
719732
}
720733

721-
// static DEFINE_SIMPLE_DEV_PM_OPS(dcpaud_pm_ops, dcpaud_suspend, dcpaud_resume);
734+
static __maybe_unused int dcpaud_suspend(struct device *dev)
735+
{
736+
/*
737+
* Using snd_power_change_state() does not work since the sound card
738+
* is what resumes runtime PM.
739+
*/
740+
741+
return 0;
742+
}
743+
744+
static __maybe_unused int dcpaud_resume(struct device *dev)
745+
{
746+
return 0;
747+
}
748+
749+
static DEFINE_RUNTIME_DEV_PM_OPS(dcpaud_pm_ops, dcpaud_suspend, dcpaud_resume, NULL);
722750

723751
static const struct of_device_id dcpaud_of_match[] = {
724752
{ .compatible = "apple,dpaudio" },
@@ -728,7 +756,8 @@ static const struct of_device_id dcpaud_of_match[] = {
728756
static struct platform_driver dcpaud_driver = {
729757
.driver = {
730758
.name = "dcp-dp-audio",
731-
.of_match_table = dcpaud_of_match,
759+
.of_match_table = dcpaud_of_match,
760+
.pm = pm_ptr(&dcpaud_pm_ops),
732761
},
733762
.probe = dcpaud_probe,
734763
.remove = dcpaud_remove,

0 commit comments

Comments
 (0)