in controllers/omap_ssi_port.c [338:375]
static int ssi_async_break(struct hsi_msg *msg)
{
struct hsi_port *port = hsi_get_port(msg->cl);
struct omap_ssi_port *omap_port = hsi_port_drvdata(port);
struct hsi_controller *ssi = to_hsi_controller(port->device.parent);
struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi);
int err = 0;
u32 tmp;
pm_runtime_get_sync(omap_port->pdev);
if (msg->ttype == HSI_MSG_WRITE) {
if (omap_port->sst.mode != SSI_MODE_FRAME) {
err = -EINVAL;
goto out;
}
writel(1, omap_port->sst_base + SSI_SST_BREAK_REG);
msg->status = HSI_STATUS_COMPLETED;
msg->complete(msg);
} else {
if (omap_port->ssr.mode != SSI_MODE_FRAME) {
err = -EINVAL;
goto out;
}
spin_lock_bh(&omap_port->lock);
tmp = readl(omap_ssi->sys +
SSI_MPU_ENABLE_REG(port->num, 0));
writel(tmp | SSI_BREAKDETECTED,
omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
msg->status = HSI_STATUS_PROCEEDING;
list_add_tail(&msg->link, &omap_port->brkqueue);
spin_unlock_bh(&omap_port->lock);
}
out:
pm_runtime_mark_last_busy(omap_port->pdev);
pm_runtime_put_autosuspend(omap_port->pdev);
return err;
}