static void ssi_error()

in controllers/omap_ssi_port.c [805:861]


static void ssi_error(struct hsi_port *port)
{
	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 err;
	u32 val;
	u32 tmp;

	/* ACK error */
	err = readl(omap_port->ssr_base + SSI_SSR_ERROR_REG);
	dev_err(&port->device, "SSI error: 0x%02x\n", err);
	if (!err) {
		dev_dbg(&port->device, "spurious SSI error ignored!\n");
		return;
	}
	spin_lock(&omap_ssi->lock);
	/* Cancel all GDD read transfers */
	for (i = 0, val = 0; i < SSI_MAX_GDD_LCH; i++) {
		msg = omap_ssi->gdd_trn[i].msg;
		if ((msg) && (msg->ttype == HSI_MSG_READ)) {
			writew_relaxed(0, omap_ssi->gdd + SSI_GDD_CCR_REG(i));
			val |= (1 << i);
			omap_ssi->gdd_trn[i].msg = NULL;
		}
	}
	tmp = readl(omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG);
	tmp &= ~val;
	writel_relaxed(tmp, omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG);
	spin_unlock(&omap_ssi->lock);
	/* Cancel all PIO read transfers */
	spin_lock(&omap_port->lock);
	tmp = readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
	tmp &= 0xfeff00ff; /* Disable error & all dataavailable interrupts */
	writel_relaxed(tmp, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0));
	/* ACK error */
	writel_relaxed(err, omap_port->ssr_base + SSI_SSR_ERRORACK_REG);
	writel_relaxed(SSI_ERROROCCURED,
			omap_ssi->sys + SSI_MPU_STATUS_REG(port->num, 0));
	/* Signal the error all current pending read requests */
	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);
		list_del(&msg->link);
		msg->status = HSI_STATUS_ERROR;
		spin_unlock(&omap_port->lock);
		msg->complete(msg);
		/* Now restart queued reads if any */
		ssi_transfer(omap_port, &omap_port->rxqueue[i]);
		spin_lock(&omap_port->lock);
	}
	spin_unlock(&omap_port->lock);
}