/* No private data for IPC */ void ipc_platform_do_cmd(struct ipc *ipc) { struct sof_ipc_reply reply; int32_t err; /* perform command and return any error */ err = ipc_cmd(); if (err > 0) { mailbox_hostbox_read(&reply, SOF_IPC_MSG_MAX_SIZE, 0, sizeof(reply)); goto done; /* reply created and copied by cmd() */ } else if (err < 0) { /* send std error reply */ reply.error = err; } else if (err == 0) { /* send std reply */ reply.error = 0; } /* send std error/ok reply */ reply.hdr.cmd = SOF_IPC_GLB_REPLY; reply.hdr.size = sizeof(reply); done: spi_push(spi_get(SOF_SPI_INTEL_SLAVE), &reply, sizeof(reply)); ipc->host_pending = 0; // TODO: signal audio work to enter D3 in normal context /* are we about to enter D3 ? */ if (ipc->pm_prepare_D3) { while (1) wait_for_interrupt(0); } }
/* * IPC main loop. * Just wait for data on the fds provided, then trigger ipc_cmd(). */ static void * ipc_loop(void *data) { struct ipc_t *ipc = (struct ipc_t *)data; struct pollfd fds[MAX_LISTENERS+1]; int i; int ret; for (i=0; i < ipc->nlisteners; i ++) { fds[i].fd = ipc->listeners[i]; fds[i].events = POLLIN; } while (1) { ret = poll(fds, ipc->nlisteners, -1); if (ret == -1 && errno == EINTR) continue; assert(ret > 0); for (i=0; i < ipc->nlisteners; i++) { if (fds[i].revents & POLLIN) { ipc_cmd(fds[i].fd, ipc); } } } return NULL; }