irqreturn_t cvm_mmc_interrupt(int irq, void *dev_id) { struct cvm_mmc_host *host = dev_id; struct mmc_request *req; unsigned long flags = 0; u64 emm_int, rsp_sts; bool host_done; if (host->need_irq_handler_lock) spin_lock_irqsave(&host->irq_handler_lock, flags); else __acquire(&host->irq_handler_lock); /* Clear interrupt bits (write 1 clears ). */ emm_int = readq(host->base + MIO_EMM_INT(host)); writeq(emm_int, host->base + MIO_EMM_INT(host)); if (emm_int & MIO_EMM_INT_SWITCH_ERR) check_switch_errors(host); req = host->current_req; if (!req) goto out; rsp_sts = readq(host->base + MIO_EMM_RSP_STS(host)); /* * dma_val set means DMA is still in progress. Don't touch * the request and wait for the interrupt indicating that * the DMA is finished. */ if ((rsp_sts & MIO_EMM_RSP_STS_DMA_VAL) && host->dma_active) goto out; if (!host->dma_active && req->data && (emm_int & MIO_EMM_INT_BUF_DONE)) { unsigned int type = (rsp_sts >> 7) & 3; if (type == 1) do_read(host, req, rsp_sts & MIO_EMM_RSP_STS_DBUF); else if (type == 2) do_write(req); }
static void thunder_mmc_int_enable(struct cvm_mmc_host *host, u64 val) { writeq(val, host->base + MIO_EMM_INT(host)); writeq(val, host->base + MIO_EMM_INT_EN_SET(host)); }