static int ssi_async_break()

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;
}