From be28b88a673293b5d5ae5acb9daa2797dedbcd09 Mon Sep 17 00:00:00 2001 From: Tomasz Lauda Date: Wed, 26 Feb 2020 12:28:55 +0100 Subject: [PATCH] detect_test: add notification to the list if channel busy Adds notification to the beginning of the list if there is some other IPC notification being sent. Signed-off-by: Tomasz Lauda --- src/audio/detect_test.c | 4 +++- src/drivers/imx/ipc.c | 9 +++++++-- src/drivers/intel/baytrail/ipc.c | 9 +++++++-- src/drivers/intel/cavs/ipc.c | 11 ++++++++--- src/drivers/intel/cavs/sue-ipc.c | 4 +++- src/drivers/intel/haswell/ipc.c | 9 +++++++-- src/include/sof/drivers/ipc.h | 2 +- src/platform/library/include/platform/platform.h | 2 +- 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index 08e897b0e0d8..470e515c9325 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -117,7 +117,9 @@ static void notify_host(const struct comp_dev *dev) sizeof(event)); /* Send IPC message right away to wake host up ASAP */ - ipc_platform_send_msg(&cd->msg); + if (ipc_platform_send_msg(&cd->msg) < 0) + /* Other notification in progress, so just add to the list */ + list_item_prepend(&cd->msg.list, &ipc_get()->msg_list); } static void notify_kpb(const struct comp_dev *dev) diff --git a/src/drivers/imx/ipc.c b/src/drivers/imx/ipc.c index 8590bc8a351b..6b5a57d71051 100644 --- a/src/drivers/imx/ipc.c +++ b/src/drivers/imx/ipc.c @@ -106,16 +106,19 @@ void ipc_platform_complete_cmd(void *data) platform_shared_commit(ipc, sizeof(*ipc)); } -void ipc_platform_send_msg(struct ipc_msg *msg) +int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); uint32_t flags; + int ret = 0; spin_lock_irq(&ipc->lock, flags); /* can't send notification when one is in progress */ - if (imx_mu_read(IMX_MU_xCR) & IMX_MU_xCR_GIRn(1)) + if (imx_mu_read(IMX_MU_xCR) & IMX_MU_xCR_GIRn(1)) { + ret = -EBUSY; goto out; + } /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); @@ -133,6 +136,8 @@ void ipc_platform_send_msg(struct ipc_msg *msg) platform_shared_commit(ipc, sizeof(*ipc)); spin_unlock_irq(&ipc->lock, flags); + + return ret; } #if CONFIG_HOST_PTABLE diff --git a/src/drivers/intel/baytrail/ipc.c b/src/drivers/intel/baytrail/ipc.c index 62edd9885117..da9a9c9b71a0 100644 --- a/src/drivers/intel/baytrail/ipc.c +++ b/src/drivers/intel/baytrail/ipc.c @@ -94,16 +94,19 @@ void ipc_platform_complete_cmd(void *data) shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_BUSY); } -void ipc_platform_send_msg(struct ipc_msg *msg) +int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); uint32_t flags; + int ret = 0; spin_lock_irq(&ipc->lock, flags); /* can't send notification when one is in progress */ - if (shim_read(SHIM_IPCDH) & (SHIM_IPCDH_BUSY | SHIM_IPCDH_DONE)) + if (shim_read(SHIM_IPCDH) & (SHIM_IPCDH_BUSY | SHIM_IPCDH_DONE)) { + ret = -EBUSY; goto out; + } /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); @@ -122,6 +125,8 @@ void ipc_platform_send_msg(struct ipc_msg *msg) platform_shared_commit(ipc, sizeof(*ipc)); spin_unlock_irq(&ipc->lock, flags); + + return ret; } struct ipc_data_host_buffer *ipc_platform_get_host_buffer(struct ipc *ipc) diff --git a/src/drivers/intel/cavs/ipc.c b/src/drivers/intel/cavs/ipc.c index ec98f8b7e354..3dc76f268189 100644 --- a/src/drivers/intel/cavs/ipc.c +++ b/src/drivers/intel/cavs/ipc.c @@ -240,20 +240,23 @@ void ipc_platform_complete_cmd(void *data) #endif } -void ipc_platform_send_msg(struct ipc_msg *msg) +int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); uint32_t flags; + int ret = 0; spin_lock_irq(&ipc->lock, flags); #if CAVS_VERSION == CAVS_VERSION_1_5 - if (ipc_read(IPC_DIPCI) & IPC_DIPCI_BUSY) + if (ipc_read(IPC_DIPCI) & IPC_DIPCI_BUSY) { #else if (ipc_read(IPC_DIPCIDR) & IPC_DIPCIDR_BUSY || - ipc_read(IPC_DIPCIDA) & IPC_DIPCIDA_DONE) + ipc_read(IPC_DIPCIDA) & IPC_DIPCIDA_DONE) { #endif + ret = -EBUSY; goto out; + } /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); @@ -277,6 +280,8 @@ void ipc_platform_send_msg(struct ipc_msg *msg) platform_shared_commit(ipc, sizeof(*ipc)); spin_unlock_irq(&ipc->lock, flags); + + return ret; } int platform_ipc_init(struct ipc *ipc) diff --git a/src/drivers/intel/cavs/sue-ipc.c b/src/drivers/intel/cavs/sue-ipc.c index bfd021aa6c44..73663aaf0765 100644 --- a/src/drivers/intel/cavs/sue-ipc.c +++ b/src/drivers/intel/cavs/sue-ipc.c @@ -51,7 +51,7 @@ void ipc_platform_complete_cmd(void *data) { } -void ipc_platform_send_msg(struct ipc_msg *msg) +int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); uint32_t flags; @@ -70,6 +70,8 @@ void ipc_platform_send_msg(struct ipc_msg *msg) platform_shared_commit(ipc, sizeof(*ipc)); spin_unlock_irq(&ipc->lock, flags); + + return 0; } int platform_ipc_init(struct ipc *ipc) diff --git a/src/drivers/intel/haswell/ipc.c b/src/drivers/intel/haswell/ipc.c index ac48338c0b03..07e88538ea29 100644 --- a/src/drivers/intel/haswell/ipc.c +++ b/src/drivers/intel/haswell/ipc.c @@ -96,16 +96,19 @@ void ipc_platform_complete_cmd(void *data) platform_shared_commit(ipc, sizeof(*ipc)); } -void ipc_platform_send_msg(struct ipc_msg *msg) +int ipc_platform_send_msg(struct ipc_msg *msg) { struct ipc *ipc = ipc_get(); uint32_t flags; + int ret = 0; spin_lock_irq(&ipc->lock, flags); /* can't send nofication when one is in progress */ - if (shim_read(SHIM_IPCD) & (SHIM_IPCD_BUSY | SHIM_IPCD_DONE)) + if (shim_read(SHIM_IPCD) & (SHIM_IPCD_BUSY | SHIM_IPCD_DONE)) { + ret = -EBUSY; goto out; + } /* now send the message */ mailbox_dspbox_write(0, msg->tx_data, msg->tx_size); @@ -123,6 +126,8 @@ void ipc_platform_send_msg(struct ipc_msg *msg) platform_shared_commit(ipc, sizeof(*ipc)); spin_unlock_irq(&ipc->lock, flags); + + return ret; } struct ipc_data_host_buffer *ipc_platform_get_host_buffer(struct ipc *ipc) diff --git a/src/include/sof/drivers/ipc.h b/src/include/sof/drivers/ipc.h index fa5ad7935aa9..cf7978cdc666 100644 --- a/src/include/sof/drivers/ipc.h +++ b/src/include/sof/drivers/ipc.h @@ -165,7 +165,7 @@ void ipc_prepare_host_message(struct ipc_msg *msg, uint32_t header, int ipc_queue_host_message(struct ipc *ipc, uint32_t header, void *tx_data, size_t tx_bytes, bool replace); -void ipc_platform_send_msg(struct ipc_msg *msg); +int ipc_platform_send_msg(struct ipc_msg *msg); void ipc_send_queued_msg(void); diff --git a/src/platform/library/include/platform/platform.h b/src/platform/library/include/platform/platform.h index 451bd8b4210f..03b985d0cc63 100644 --- a/src/platform/library/include/platform/platform.h +++ b/src/platform/library/include/platform/platform.h @@ -52,7 +52,7 @@ static inline void platform_wait_for_interrupt(int level) arch_wait_for_interrupt(level); } -static inline void ipc_platform_send_msg(struct ipc_msg *msg) { } +static inline int ipc_platform_send_msg(struct ipc_msg *msg) { return 0; } #endif /* __PLATFORM_PLATFORM_H__ */