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.
@@ -397,44 +399,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
397399}
398400EXPORT_SYMBOL (snd_sof_ipc_reply );
399401
400- static void ipc_comp_notification (struct snd_sof_dev * sdev ,
401- struct sof_ipc_cmd_hdr * hdr )
402+ static void ipc_comp_notification (struct snd_sof_dev * sdev , void * full_msg )
402403{
404+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
403405 u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
404- struct sof_ipc_ctrl_data * cdata ;
405- int ret ;
406406
407407 switch (msg_type ) {
408408 case SOF_IPC_COMP_GET_VALUE :
409409 case SOF_IPC_COMP_GET_DATA :
410- cdata = kmalloc (hdr -> size , GFP_KERNEL );
411- if (!cdata )
412- return ;
413-
414- /* read back full message */
415- ret = snd_sof_ipc_msg_data (sdev , NULL , cdata , hdr -> size );
416- if (ret < 0 ) {
417- dev_err (sdev -> dev ,
418- "error: failed to read component event: %d\n" , ret );
419- goto err ;
420- }
421410 break ;
422411 default :
423412 dev_err (sdev -> dev , "error: unhandled component message %#x\n" , msg_type );
424413 return ;
425414 }
426415
427- snd_sof_control_notify (sdev , cdata );
428-
429- err :
430- kfree (cdata );
416+ snd_sof_control_notify (sdev , full_msg );
431417}
432418
433419/* DSP firmware has sent host a message */
434420void snd_sof_ipc_msgs_rx (struct snd_sof_dev * sdev )
435421{
422+ ipc_rx_callback rx_callback = NULL ;
436423 struct sof_ipc_cmd_hdr hdr ;
437- u32 cmd , type ;
424+ void * full_msg ;
425+ u32 cmd ;
438426 int err ;
439427
440428 /* read back header */
@@ -446,7 +434,6 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
446434 ipc_log_header (sdev -> dev , "ipc rx" , hdr .cmd );
447435
448436 cmd = hdr .cmd & SOF_GLB_TYPE_MASK ;
449- type = hdr .cmd & SOF_CMD_TYPE_MASK ;
450437
451438 /* check message type */
452439 switch (cmd ) {
@@ -471,20 +458,34 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
471458 case SOF_IPC_GLB_PM_MSG :
472459 break ;
473460 case SOF_IPC_GLB_COMP_MSG :
474- ipc_comp_notification ( sdev , & hdr ) ;
461+ rx_callback = ipc_comp_notification ;
475462 break ;
476463 case SOF_IPC_GLB_STREAM_MSG :
477- /* need to pass msg id into the function */
478- ipc_stream_message (sdev , hdr .cmd );
464+ rx_callback = ipc_stream_message ;
479465 break ;
480466 case SOF_IPC_GLB_TRACE_MSG :
481- ipc_trace_message ( sdev , type ) ;
467+ rx_callback = ipc_trace_message ;
482468 break ;
483469 default :
484470 dev_err (sdev -> dev , "error: unknown DSP message 0x%x\n" , cmd );
485471 break ;
486472 }
487473
474+ if (rx_callback ) {
475+ /* read the full message as there we have rx handler for it */
476+ full_msg = kmalloc (hdr .size , GFP_KERNEL );
477+ if (!full_msg )
478+ return ;
479+
480+ err = snd_sof_ipc_msg_data (sdev , NULL , full_msg , hdr .size );
481+ if (err < 0 )
482+ dev_err (sdev -> dev , "failed to read message\n" );
483+ else
484+ rx_callback (sdev , full_msg );
485+
486+ kfree (full_msg );
487+ }
488+
488489 ipc_log_header (sdev -> dev , "ipc rx done" , hdr .cmd );
489490}
490491EXPORT_SYMBOL (snd_sof_ipc_msgs_rx );
@@ -493,19 +494,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
493494 * IPC trace mechanism.
494495 */
495496
496- static void ipc_trace_message (struct snd_sof_dev * sdev , u32 msg_type )
497+ static void ipc_trace_message (struct snd_sof_dev * sdev , void * full_msg )
497498{
498- struct sof_ipc_dma_trace_posn posn ;
499- int ret ;
499+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
500+ u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
500501
501502 switch (msg_type ) {
502503 case SOF_IPC_TRACE_DMA_POSITION :
503- /* read back full message */
504- ret = snd_sof_ipc_msg_data (sdev , NULL , & posn , sizeof (posn ));
505- if (ret < 0 )
506- dev_warn (sdev -> dev , "failed to read trace position: %d\n" , ret );
507- else
508- snd_sof_trace_update_pos (sdev , & posn );
504+ snd_sof_trace_update_pos (sdev , full_msg );
509505 break ;
510506 default :
511507 dev_err (sdev -> dev , "error: unhandled trace message %#x\n" , msg_type );
@@ -586,11 +582,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id)
586582}
587583
588584/* stream notifications from DSP FW */
589- static void ipc_stream_message (struct snd_sof_dev * sdev , u32 msg_cmd )
585+ static void ipc_stream_message (struct snd_sof_dev * sdev , void * full_msg )
590586{
591- /* get msg cmd type and msd id */
592- u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK ;
593- u32 msg_id = SOF_IPC_MESSAGE_ID (msg_cmd );
587+ struct sof_ipc_cmd_hdr * hdr = full_msg ;
588+ u32 msg_type = hdr -> cmd & SOF_CMD_TYPE_MASK ;
589+ u32 msg_id = SOF_IPC_MESSAGE_ID (hdr -> cmd );
594590
595591 switch (msg_type ) {
596592 case SOF_IPC_STREAM_POSITION :
0 commit comments