Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/audio/detect_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prepending should be in the IPC core. i.e. we should have a new IPC API

int ipc_platform_send_msg_queue(msg, priority, remove_duplicates);

Where priority HIGH would mean we insert new message at list head, otherwise it's list tail. The remove duplicates bool means to remove any older messages from this sender and use this message. Handy if we are sending any high frequency updates and want to remove stale or older updates.

This should be called directly instead of existing method (and will acquire any locks etc)..

}

static void notify_kpb(const struct comp_dev *dev)
Expand Down
9 changes: 7 additions & 2 deletions src/drivers/imx/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down
9 changes: 7 additions & 2 deletions src/drivers/intel/baytrail/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
11 changes: 8 additions & 3 deletions src/drivers/intel/cavs/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion src/drivers/intel/cavs/sue-ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions src/drivers/intel/haswell/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/include/sof/drivers/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/platform/library/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

Expand Down