Ejemplo n.º 1
0
/*
 * Handle an interrupt
 */
static irqreturn_t at91_mci_irq(int irq, void *devid)
{
	struct at91mci_host *host = devid;
	int completed = 0;
	unsigned int int_status, int_mask;

	int_status = at91_mci_read(host, AT91_MCI_SR);
	int_mask = at91_mci_read(host, AT91_MCI_IMR);
	
	pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
		int_status & int_mask);
	
	int_status = int_status & int_mask;

	if (int_status & AT91_MCI_ERRORS) {
		completed = 1;
		
		if (int_status & AT91_MCI_UNRE)
			pr_debug("MMC: Underrun error\n");
		if (int_status & AT91_MCI_OVRE)
			pr_debug("MMC: Overrun error\n");
		if (int_status & AT91_MCI_DTOE)
			pr_debug("MMC: Data timeout\n");
		if (int_status & AT91_MCI_DCRCE)
			pr_debug("MMC: CRC error in data\n");
		if (int_status & AT91_MCI_RTOE)
			pr_debug("MMC: Response timeout\n");
		if (int_status & AT91_MCI_RENDE)
			pr_debug("MMC: Response end bit error\n");
		if (int_status & AT91_MCI_RCRCE)
			pr_debug("MMC: Response CRC error\n");
		if (int_status & AT91_MCI_RDIRE)
			pr_debug("MMC: Response direction error\n");
		if (int_status & AT91_MCI_RINDE)
			pr_debug("MMC: Response index error\n");
	} else {
		/* Only continue processing if no errors */

		if (int_status & AT91_MCI_TXBUFE) {
			pr_debug("TX buffer empty\n");
			at91_mci_handle_transmitted(host);
		}

		if (int_status & AT91_MCI_RXBUFF) {
			pr_debug("RX buffer full\n");
			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
		}

		if (int_status & AT91_MCI_ENDTX)
			pr_debug("Transmit has ended\n");

		if (int_status & AT91_MCI_ENDRX) {
			pr_debug("Receive has ended\n");
			at91mci_post_dma_read(host);
		}

		if (int_status & AT91_MCI_NOTBUSY) {
			pr_debug("Card is ready\n");
			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
		}

		if (int_status & AT91_MCI_DTIP)
			pr_debug("Data transfer in progress\n");

		if (int_status & AT91_MCI_BLKE)
			pr_debug("Block transfer has ended\n");

		if (int_status & AT91_MCI_TXRDY)
			pr_debug("Ready to transmit\n");

		if (int_status & AT91_MCI_RXRDY)
			pr_debug("Ready to receive\n");

		if (int_status & AT91_MCI_CMDRDY) {
			pr_debug("Command ready\n");
			completed = 1;
		}
	}

	if (completed) {
		pr_debug("Completed command\n");
		at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
		at91mci_completed_command(host);
	} else
		at91_mci_write(host, AT91_MCI_IDR, int_status);

	return IRQ_HANDLED;
}
Ejemplo n.º 2
0
/*
 * Handle an interrupt
 */
static irqreturn_t at91rm9200_mci_irq(int irq, void* devid, struct pt_regs* regs)
{
	struct at91mci_host* host = devid;
	int completed = 0;

	unsigned int int_status;

	if (host == NULL) {
		return IRQ_HANDLED;
	}

	int_status = controller->MCI_SR;
	DBG("MCI irq: status = %08X, %08X, %08X\n", int_status, controller->MCI_IMR,
		int_status & controller->MCI_IMR);

	if ((int_status & controller->MCI_IMR) & 0xffff0000) {
		completed = 1;
	}
	int_status &= controller->MCI_IMR;

	if (int_status & AT91C_MCI_UNRE) {
		DBG("Underrun error\n");
	}

	if (int_status & AT91C_MCI_OVRE) {
		DBG("Overrun error\n");
	}

	if (int_status & AT91C_MCI_DTOE) {
		DBG("Data timeout\n");
	}

	if (int_status & AT91C_MCI_DCRCE) {
		DBG("CRC error in data\n");
	}

	if (int_status & AT91C_MCI_RTOE) {
		DBG("Response timeout\n");
	}

	if (int_status & AT91C_MCI_RENDE) {
		DBG("Response end bit error\n");
	}

	if (int_status & AT91C_MCI_RCRCE) {
		DBG("Response CRC error\n");
	}

	if (int_status & AT91C_MCI_RINDE) {
		DBG("Response index error\n");
	}

	if (int_status & AT91C_MCI_TXBUFE) {
		DBG("TX buffer empty\n");
		at91rm9200_mci_handle_transmitted(host);
	}

	if (int_status & AT91C_MCI_RXBUFF) {
		DBG("RX buffer full\n");
		controller->MCI_IER = AT91C_MCI_CMDRDY;
	}

	if (int_status & AT91C_MCI_ENDTX) {
		DBG("Transmit has ended\n");
	}

	if (int_status & AT91C_MCI_ENDRX) {
		DBG("Receive has ended\n");
		at91mci_post_dma_read(host);
	}

	if (int_status & AT91C_MCI_NOTBUSY) {
		DBG("Card is ready\n");
		controller->MCI_IER = AT91C_MCI_CMDRDY;
	}

	if (int_status & AT91C_MCI_DTIP) {
		DBG("Data transfer in progress\n");
	}

	if (int_status & AT91C_MCI_BLKE) {
		DBG("Black transfer has ended\n");
	}

	if (int_status & AT91C_MCI_TXRDY) {
		DBG("Ready to transmit\n");
	}

	if (int_status & AT91C_MCI_RXRDY) {
		DBG("Ready to receive\n");
	}

	if (int_status & AT91C_MCI_CMDRDY) {
		DBG("Command ready\n");
		completed = 1;
	}

	controller->MCI_IDR = int_status;

	if (completed) {
		DBG("Completed command\n");
		controller->MCI_IDR = 0xffffffff;
		at91mci_completed_command(host);
	}

	return IRQ_HANDLED;
}