1818#include "sof-audio.h"
1919#include "ops.h"
2020
21- static void ipc_trace_message (struct snd_sof_dev * sdev , u32 msg_type );
22- static void ipc_stream_message (struct snd_sof_dev * sdev , u32 msg_cmd );
21+ typedef void (* ipc_rx_callback )(struct snd_sof_dev * sdev , void * full_msg );
22+
23+ static void ipc_trace_message (struct snd_sof_dev * sdev , void * full_msg );
24+ static void ipc_stream_message (struct snd_sof_dev * sdev , void * full_msg );
2325
2426/*
2527 * IPC message Tx/Rx message handling.
@@ -391,44 +393,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
391393}
392394EXPORT_SYMBOL (snd_sof_ipc_reply );
393395
394- static void ipc_comp_notification (struct snd_sof_dev * sdev ,
395- struct sof_ipc_cmd_hdr * hdr )
396+ static void ipc_comp_notification (struct snd_sof_dev * sdev , void * full_msg )
396397{
398+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
397399 u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
398- struct sof_ipc_ctrl_data * cdata ;
399- int ret ;
400400
401401 switch (msg_type ) {
402402 case SOF_IPC_COMP_GET_VALUE :
403403 case SOF_IPC_COMP_GET_DATA :
404- cdata = kmalloc (hdr -> size , GFP_KERNEL );
405- if (!cdata )
406- return ;
407-
408- /* read back full message */
409- ret = snd_sof_ipc_msg_data (sdev , NULL , cdata , hdr -> size );
410- if (ret < 0 ) {
411- dev_err (sdev -> dev ,
412- "error: failed to read component event: %d\n" , ret );
413- goto err ;
414- }
415404 break ;
416405 default :
417406 dev_err (sdev -> dev , "error: unhandled component message %#x\n" , msg_type );
418407 return ;
419408 }
420409
421- snd_sof_control_notify (sdev , cdata );
422-
423- err :
424- kfree (cdata );
410+ snd_sof_control_notify (sdev , full_msg );
425411}
426412
427413/* DSP firmware has sent host a message */
428414void snd_sof_ipc_msgs_rx (struct snd_sof_dev * sdev )
429415{
416+ ipc_rx_callback rx_callback = NULL ;
430417 struct sof_ipc_cmd_hdr hdr ;
431- u32 cmd , type ;
418+ void * full_msg ;
419+ u32 cmd ;
432420 int err ;
433421
434422 /* read back header */
@@ -440,7 +428,6 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
440428 ipc_log_header (sdev -> dev , "ipc rx" , hdr .cmd );
441429
442430 cmd = hdr .cmd & SOF_GLB_TYPE_MASK ;
443- type = hdr .cmd & SOF_CMD_TYPE_MASK ;
444431
445432 /* check message type */
446433 switch (cmd ) {
@@ -465,20 +452,34 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
465452 case SOF_IPC_GLB_PM_MSG :
466453 break ;
467454 case SOF_IPC_GLB_COMP_MSG :
468- ipc_comp_notification ( sdev , & hdr ) ;
455+ rx_callback = ipc_comp_notification ;
469456 break ;
470457 case SOF_IPC_GLB_STREAM_MSG :
471- /* need to pass msg id into the function */
472- ipc_stream_message (sdev , hdr .cmd );
458+ rx_callback = ipc_stream_message ;
473459 break ;
474460 case SOF_IPC_GLB_TRACE_MSG :
475- ipc_trace_message ( sdev , type ) ;
461+ rx_callback = ipc_trace_message ;
476462 break ;
477463 default :
478464 dev_err (sdev -> dev , "error: unknown DSP message 0x%x\n" , cmd );
479465 break ;
480466 }
481467
468+ if (rx_callback ) {
469+ /* read the full message as there we have rx handler for it */
470+ full_msg = kmalloc (hdr .size , GFP_KERNEL );
471+ if (!full_msg )
472+ return ;
473+
474+ err = snd_sof_ipc_msg_data (sdev , NULL , full_msg , hdr .size );
475+ if (err < 0 )
476+ dev_err (sdev -> dev , "failed to read message\n" );
477+ else
478+ rx_callback (sdev , full_msg );
479+
480+ kfree (full_msg );
481+ }
482+
482483 ipc_log_header (sdev -> dev , "ipc rx done" , hdr .cmd );
483484}
484485EXPORT_SYMBOL (snd_sof_ipc_msgs_rx );
@@ -487,19 +488,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
487488 * IPC trace mechanism.
488489 */
489490
490- static void ipc_trace_message (struct snd_sof_dev * sdev , u32 msg_type )
491+ static void ipc_trace_message (struct snd_sof_dev * sdev , void * full_msg )
491492{
492- struct sof_ipc_dma_trace_posn posn ;
493- int ret ;
493+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
494+ u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
494495
495496 switch (msg_type ) {
496497 case SOF_IPC_TRACE_DMA_POSITION :
497- /* read back full message */
498- ret = snd_sof_ipc_msg_data (sdev , NULL , & posn , sizeof (posn ));
499- if (ret < 0 )
500- dev_warn (sdev -> dev , "failed to read trace position: %d\n" , ret );
501- else
502- snd_sof_trace_update_pos (sdev , & posn );
498+ snd_sof_trace_update_pos (sdev , full_msg );
503499 break ;
504500 default :
505501 dev_err (sdev -> dev , "error: unhandled trace message %#x\n" , msg_type );
@@ -580,11 +576,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id)
580576}
581577
582578/* stream notifications from DSP FW */
583- static void ipc_stream_message (struct snd_sof_dev * sdev , u32 msg_cmd )
579+ static void ipc_stream_message (struct snd_sof_dev * sdev , void * full_msg )
584580{
585- /* get msg cmd type and msd id */
586- u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK ;
587- u32 msg_id = SOF_IPC_MESSAGE_ID (msg_cmd );
581+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
582+ u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
583+ u32 msg_id = SOF_IPC_MESSAGE_ID (hdr -> cmd );
588584
589585 switch (msg_type ) {
590586 case SOF_IPC_STREAM_POSITION :
0 commit comments