in controllers/omap_ssi_port.c [893:955]
static void ssi_pio_complete(struct hsi_port *port, struct list_head *queue)
{
struct hsi_controller *ssi = to_hsi_controller(port->device.parent);
struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi);
struct omap_ssi_port *omap_port = hsi_port_drvdata(port);
struct hsi_msg *msg;
u32 *buf;
u32 reg;
u32 val;
spin_lock_bh(&omap_port->lock);
msg = list_first_entry(queue, struct hsi_msg, link);
if ((!msg->sgt.nents) || (!msg->sgt.sgl->length)) {
msg->actual_len = 0;
msg->status = HSI_STATUS_PENDING;
}
if (msg->ttype == HSI_MSG_WRITE)
val = SSI_DATAACCEPT(msg->channel);
else
val = SSI_DATAAVAILABLE(msg->channel);
if (msg->status == HSI_STATUS_PROCEEDING) {
buf = sg_virt(msg->sgt.sgl) + msg->actual_len;
if (msg->ttype == HSI_MSG_WRITE)
writel(*buf, omap_port->sst_base +
SSI_SST_BUFFER_CH_REG(msg->channel));
else
*buf = readl(omap_port->ssr_base +
SSI_SSR_BUFFER_CH_REG(msg->channel));
dev_dbg(&port->device, "ch %d ttype %d 0x%08x\n", msg->channel,
msg->ttype, *buf);
msg->actual_len += sizeof(*buf);
if (msg->actual_len >= msg->sgt.sgl->length)
msg->status = HSI_STATUS_COMPLETED;
/*
* Wait for the last written frame to be really sent before
* we call the complete callback
*/
if ((msg->status == HSI_STATUS_PROCEEDING) ||
((msg->status == HSI_STATUS_COMPLETED) &&
(msg->ttype == HSI_MSG_WRITE))) {
writel(val, omap_ssi->sys +
SSI_MPU_STATUS_REG(port->num, 0));
spin_unlock_bh(&omap_port->lock);
return;
}
}
/* Transfer completed at this point */
reg = readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
if (msg->ttype == HSI_MSG_WRITE) {
/* Release clocks for write transfer */
pm_runtime_mark_last_busy(omap_port->pdev);
pm_runtime_put_autosuspend(omap_port->pdev);
}
reg &= ~val;
writel_relaxed(reg, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
writel_relaxed(val, omap_ssi->sys + SSI_MPU_STATUS_REG(port->num, 0));
list_del(&msg->link);
spin_unlock_bh(&omap_port->lock);
msg->complete(msg);
ssi_transfer(omap_port, queue);
}