in controllers/omap_ssi_port.c [957:994]
static irqreturn_t ssi_pio_thread(int irq, void *ssi_port)
{
struct hsi_port *port = (struct hsi_port *)ssi_port;
struct hsi_controller *ssi = to_hsi_controller(port->device.parent);
struct omap_ssi_port *omap_port = hsi_port_drvdata(port);
struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi);
void __iomem *sys = omap_ssi->sys;
unsigned int ch;
u32 status_reg;
pm_runtime_get_sync(omap_port->pdev);
do {
status_reg = readl(sys + SSI_MPU_STATUS_REG(port->num, 0));
status_reg &= readl(sys + SSI_MPU_ENABLE_REG(port->num, 0));
for (ch = 0; ch < omap_port->channels; ch++) {
if (status_reg & SSI_DATAACCEPT(ch))
ssi_pio_complete(port, &omap_port->txqueue[ch]);
if (status_reg & SSI_DATAAVAILABLE(ch))
ssi_pio_complete(port, &omap_port->rxqueue[ch]);
}
if (status_reg & SSI_BREAKDETECTED)
ssi_break_complete(port);
if (status_reg & SSI_ERROROCCURED)
ssi_error(port);
status_reg = readl(sys + SSI_MPU_STATUS_REG(port->num, 0));
status_reg &= readl(sys + SSI_MPU_ENABLE_REG(port->num, 0));
/* TODO: sleep if we retry? */
} while (status_reg);
pm_runtime_mark_last_busy(omap_port->pdev);
pm_runtime_put_autosuspend(omap_port->pdev);
return IRQ_HANDLED;
}