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