1111#include <linux/debugfs.h>
1212#include <linux/sched/signal.h>
1313#include "sof-priv.h"
14+ #include "sof-audio.h"
1415#include "ops.h"
1516#include "sof-utils.h"
1617
@@ -263,7 +264,7 @@ static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
263264 if (ret )
264265 return ret ;
265266
266- if (! sdev -> dtrace_is_enabled && sdev -> dtrace_draining ) {
267+ if (sdev -> dtrace_state != SOF_DTRACE_ENABLED && sdev -> dtrace_draining ) {
267268 /*
268269 * tracing has ended and all traces have been
269270 * read by client, return EOF
@@ -337,7 +338,7 @@ static int sof_dfsentry_trace_release(struct inode *inode, struct file *file)
337338 struct snd_sof_dev * sdev = dfse -> sdev ;
338339
339340 /* avoid duplicate traces at next open */
340- if (! sdev -> dtrace_is_enabled )
341+ if (sdev -> dtrace_state != SOF_DTRACE_ENABLED )
341342 sdev -> host_offset = 0 ;
342343
343344 return 0 ;
@@ -377,7 +378,7 @@ static int trace_debugfs_create(struct snd_sof_dev *sdev)
377378 return 0 ;
378379}
379380
380- int snd_sof_init_trace_ipc (struct snd_sof_dev * sdev )
381+ static int snd_sof_enable_trace (struct snd_sof_dev * sdev )
381382{
382383 struct sof_ipc_fw_ready * ready = & sdev -> fw_ready ;
383384 struct sof_ipc_fw_version * v = & ready -> version ;
@@ -388,9 +389,12 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
388389 if (!sdev -> dtrace_is_supported )
389390 return 0 ;
390391
391- if (sdev -> dtrace_is_enabled || !sdev -> dma_trace_pages )
392+ if (sdev -> dtrace_state == SOF_DTRACE_ENABLED || !sdev -> dma_trace_pages )
392393 return - EINVAL ;
393394
395+ if (sdev -> dtrace_state == SOF_DTRACE_STOPPED )
396+ goto start ;
397+
394398 /* set IPC parameters */
395399 params .hdr .cmd = SOF_IPC_GLB_TRACE_MSG ;
396400 /* PARAMS_EXT is only supported from ABI 3.7.0 onwards */
@@ -428,14 +432,15 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
428432 goto trace_release ;
429433 }
430434
435+ start :
431436 ret = snd_sof_dma_trace_trigger (sdev , SNDRV_PCM_TRIGGER_START );
432437 if (ret < 0 ) {
433438 dev_err (sdev -> dev ,
434439 "error: snd_sof_dma_trace_trigger: start: %d\n" , ret );
435440 goto trace_release ;
436441 }
437442
438- sdev -> dtrace_is_enabled = true ;
443+ sdev -> dtrace_state = SOF_DTRACE_ENABLED ;
439444
440445 return 0 ;
441446
@@ -452,7 +457,7 @@ int snd_sof_init_trace(struct snd_sof_dev *sdev)
452457 return 0 ;
453458
454459 /* set false before start initialization */
455- sdev -> dtrace_is_enabled = false ;
460+ sdev -> dtrace_state = SOF_DTRACE_DISABLED ;
456461
457462 /* allocate trace page table buffer */
458463 ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV , sdev -> dev ,
@@ -490,7 +495,7 @@ int snd_sof_init_trace(struct snd_sof_dev *sdev)
490495
491496 init_waitqueue_head (& sdev -> trace_sleep );
492497
493- ret = snd_sof_init_trace_ipc (sdev );
498+ ret = snd_sof_enable_trace (sdev );
494499 if (ret < 0 )
495500 goto table_err ;
496501
@@ -510,7 +515,8 @@ int snd_sof_trace_update_pos(struct snd_sof_dev *sdev,
510515 if (!sdev -> dtrace_is_supported )
511516 return 0 ;
512517
513- if (sdev -> dtrace_is_enabled && sdev -> host_offset != posn -> host_offset ) {
518+ if (sdev -> dtrace_state == SOF_DTRACE_ENABLED &&
519+ sdev -> host_offset != posn -> host_offset ) {
514520 sdev -> host_offset = posn -> host_offset ;
515521 wake_up (& sdev -> trace_sleep );
516522 }
@@ -529,28 +535,29 @@ void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev)
529535 if (!sdev -> dtrace_is_supported )
530536 return ;
531537
532- if (sdev -> dtrace_is_enabled ) {
538+ if (sdev -> dtrace_state == SOF_DTRACE_ENABLED ) {
533539 sdev -> dtrace_error = true;
534540 wake_up (& sdev -> trace_sleep );
535541 }
536542}
537543EXPORT_SYMBOL (snd_sof_trace_notify_for_error );
538544
539- void snd_sof_release_trace (struct snd_sof_dev * sdev )
545+ static void snd_sof_release_trace (struct snd_sof_dev * sdev , bool only_stop )
540546{
541547 struct sof_ipc_fw_ready * ready = & sdev -> fw_ready ;
542548 struct sof_ipc_fw_version * v = & ready -> version ;
543549 struct sof_ipc_cmd_hdr hdr ;
544550 struct sof_ipc_reply ipc_reply ;
545551 int ret ;
546552
547- if (!sdev -> dtrace_is_supported || ! sdev -> dtrace_is_enabled )
553+ if (!sdev -> dtrace_is_supported || sdev -> dtrace_state == SOF_DTRACE_DISABLED )
548554 return ;
549555
550556 ret = snd_sof_dma_trace_trigger (sdev , SNDRV_PCM_TRIGGER_STOP );
551557 if (ret < 0 )
552558 dev_err (sdev -> dev ,
553559 "error: snd_sof_dma_trace_trigger: stop: %d\n" , ret );
560+ sdev -> dtrace_state = SOF_DTRACE_STOPPED ;
554561
555562 /*
556563 * stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from
@@ -566,23 +573,46 @@ void snd_sof_release_trace(struct snd_sof_dev *sdev)
566573 dev_err (sdev -> dev , "DMA_TRACE_FREE failed with error: %d\n" , ret );
567574 }
568575
576+ if (only_stop )
577+ goto out ;
578+
569579 ret = snd_sof_dma_trace_release (sdev );
570580 if (ret < 0 )
571581 dev_err (sdev -> dev ,
572582 "error: fail in snd_sof_dma_trace_release %d\n" , ret );
573583
574- sdev -> dtrace_is_enabled = false;
584+ sdev -> dtrace_state = SOF_DTRACE_DISABLED ;
585+
586+ out :
575587 sdev -> dtrace_draining = true;
576588 wake_up (& sdev -> trace_sleep );
577589}
578- EXPORT_SYMBOL (snd_sof_release_trace );
590+
591+ int snd_sof_trace_suspend (struct snd_sof_dev * sdev , int pm_state )
592+ {
593+ if (pm_state == SOF_DSP_PM_D0 )
594+ snd_sof_release_trace (sdev , 1 );
595+ else
596+ snd_sof_release_trace (sdev , 0 );
597+
598+ /* always return 0 */
599+ return 0 ;
600+ }
601+ EXPORT_SYMBOL (snd_sof_trace_suspend );
602+
603+ int snd_sof_trace_resume (struct snd_sof_dev * sdev )
604+ {
605+ return snd_sof_enable_trace (sdev );
606+ }
607+ EXPORT_SYMBOL (snd_sof_trace_resume );
579608
580609void snd_sof_free_trace (struct snd_sof_dev * sdev )
581610{
582611 if (!sdev -> dtrace_is_supported )
583612 return ;
584613
585- snd_sof_release_trace (sdev );
614+ /* release trace */
615+ snd_sof_release_trace (sdev , 0 );
586616
587617 if (sdev -> dma_trace_pages ) {
588618 snd_dma_free_pages (& sdev -> dmatb );
0 commit comments