static void ssi_cleanup_queues()

in controllers/omap_ssi_port.c [666:725]


static void ssi_cleanup_queues(struct hsi_client *cl)
{
	struct hsi_port *port = hsi_get_port(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);
	struct hsi_msg *msg;
	unsigned int i;
	u32 rxbufstate = 0;
	u32 txbufstate = 0;
	u32 status = SSI_ERROROCCURED;
	u32 tmp;

	ssi_flush_queue(&omap_port->brkqueue, cl);
	if (list_empty(&omap_port->brkqueue))
		status |= SSI_BREAKDETECTED;

	for (i = 0; i < omap_port->channels; i++) {
		if (list_empty(&omap_port->txqueue[i]))
			continue;
		msg = list_first_entry(&omap_port->txqueue[i], struct hsi_msg,
									link);
		if ((msg->cl == cl) && (msg->status == HSI_STATUS_PROCEEDING)) {
			txbufstate |= (1 << i);
			status |= SSI_DATAACCEPT(i);
			/* Release the clocks writes, also GDD ones */
			pm_runtime_mark_last_busy(omap_port->pdev);
			pm_runtime_put_autosuspend(omap_port->pdev);
		}
		ssi_flush_queue(&omap_port->txqueue[i], cl);
	}
	for (i = 0; i < omap_port->channels; i++) {
		if (list_empty(&omap_port->rxqueue[i]))
			continue;
		msg = list_first_entry(&omap_port->rxqueue[i], struct hsi_msg,
									link);
		if ((msg->cl == cl) && (msg->status == HSI_STATUS_PROCEEDING)) {
			rxbufstate |= (1 << i);
			status |= SSI_DATAAVAILABLE(i);
		}
		ssi_flush_queue(&omap_port->rxqueue[i], cl);
		/* Check if we keep the error detection interrupt armed */
		if (!list_empty(&omap_port->rxqueue[i]))
			status &= ~SSI_ERROROCCURED;
	}
	/* Cleanup write buffers */
	tmp = readl(omap_port->sst_base + SSI_SST_BUFSTATE_REG);
	tmp &= ~txbufstate;
	writel_relaxed(tmp, omap_port->sst_base + SSI_SST_BUFSTATE_REG);
	/* Cleanup read buffers */
	tmp = readl(omap_port->ssr_base + SSI_SSR_BUFSTATE_REG);
	tmp &= ~rxbufstate;
	writel_relaxed(tmp, omap_port->ssr_base + SSI_SSR_BUFSTATE_REG);
	/* Disarm and ack pending interrupts */
	tmp = readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
	tmp &= ~status;
	writel_relaxed(tmp, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
	writel_relaxed(status, omap_ssi->sys +
		SSI_MPU_STATUS_REG(port->num, 0));
}