/* * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller * @zqspi: Pointer to the zynq_qspi structure * * This function handles TX empty and Mode Fault interrupts only. * On TX empty interrupt this function reads the received data from RX FIFO and * fills the TX FIFO if there is any data remaining to be transferred. * On Mode Fault interrupt this function indicates that transfer is completed, * the SPI subsystem will identify the error as the remaining bytes to be * transferred is non-zero. * * returns: 0 for poll timeout * 1 transfer operation complete */ static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi) { int max_loop; u32 intr_status; u32 rxindex = 0; u32 rxcount; debug("%s: zqspi: 0x%08x\n", __func__, (u32)zqspi); /* Poll until any of the interrupt status bits are set */ max_loop = 0; do { intr_status = readl(&zynq_qspi_base->isr); max_loop++; } while ((intr_status == 0) && (max_loop < 100000)); if (intr_status == 0) { printf("%s: Timeout\n", __func__); return 0; } writel(intr_status, &zynq_qspi_base->isr); /* Disable all interrupts */ writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->idisr); if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) || (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) { /* * This bit is set when Tx FIFO has < THRESHOLD entries. We have * the THRESHOLD value set to 1, so this bit indicates Tx FIFO * is empty */ rxcount = zqspi->bytes_to_receive - zqspi->bytes_to_transfer; rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4); while ((rxindex < rxcount) && (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) { /* Read out the data from the RX FIFO */ u32 data; data = readl(&zynq_qspi_base->drxr); if ((zqspi->inst_response) && (!((zqspi->curr_inst->opcode == ZYNQ_QSPI_FLASH_OPCODE_RDSR1) || (zqspi->curr_inst->opcode == ZYNQ_QSPI_FLASH_OPCODE_RDSR2)))) { zqspi->inst_response = 0; zynq_qspi_copy_read_data(zqspi, data, zqspi->curr_inst->inst_size); } else if (zqspi->bytes_to_receive < 4) { zynq_qspi_copy_read_data(zqspi, data, zqspi->bytes_to_receive); } else { if (zqspi->rxbuf) { memcpy(zqspi->rxbuf, &data, 4); zqspi->rxbuf += 4; } zqspi->bytes_to_receive -= 4; } rxindex++; } if (zqspi->bytes_to_transfer) { /* There is more data to send */ zynq_qspi_fill_tx_fifo(zqspi, ZYNQ_QSPI_RXFIFO_THRESHOLD); writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier); } else { /* * If transfer and receive is completed then only send * complete signal */ if (!zqspi->bytes_to_receive) { /* return operation complete */ writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->idisr); return 1; } } } return 0; }
/** * zynq_qspi_irq - Interrupt service routine of the QSPI controller * @irq: IRQ number * @dev_id: Pointer to the xqspi structure * * This function handles TX empty only. * On TX empty interrupt this function reads the received data from RX FIFO and * fills the TX FIFO if there is any data remaining to be transferred. * * Return: IRQ_HANDLED when interrupt is handled; IRQ_NONE otherwise. */ static irqreturn_t zynq_qspi_irq(int irq, void *dev_id) { struct spi_master *master = dev_id; struct zynq_qspi *xqspi = spi_master_get_devdata(master); u32 intr_status, rxcount, rxindex = 0; u8 offset[3] = {ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET}; intr_status = zynq_qspi_read(xqspi, ZYNQ_QSPI_STATUS_OFFSET); zynq_qspi_write(xqspi, ZYNQ_QSPI_STATUS_OFFSET , intr_status); if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) || (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) { /* * This bit is set when Tx FIFO has < THRESHOLD entries. * We have the THRESHOLD value set to 1, * so this bit indicates Tx FIFO is empty. */ u32 data; rxcount = xqspi->bytes_to_receive - xqspi->bytes_to_transfer; rxcount = (rxcount % 4) ? ((rxcount/4) + 1) : (rxcount/4); /* Read out the data from the RX FIFO */ while ((rxindex < rxcount) && (rxindex < ZYNQ_QSPI_RX_THRESHOLD)) { if (xqspi->bytes_to_receive >= 4) { if (xqspi->rxbuf) { (*(u32 *)xqspi->rxbuf) = zynq_qspi_read(xqspi, ZYNQ_QSPI_RXD_OFFSET); xqspi->rxbuf += 4; } else { data = zynq_qspi_read(xqspi, ZYNQ_QSPI_RXD_OFFSET); } xqspi->bytes_to_receive -= 4; } else { data = zynq_qspi_read(xqspi, ZYNQ_QSPI_RXD_OFFSET); zynq_qspi_copy_read_data(xqspi, data, xqspi->bytes_to_receive); } rxindex++; } if (xqspi->bytes_to_transfer) { if (xqspi->bytes_to_transfer >= 4) { /* There is more data to send */ zynq_qspi_fill_tx_fifo(xqspi, ZYNQ_QSPI_RX_THRESHOLD); } else if (intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) { int tmp; tmp = xqspi->bytes_to_transfer; zynq_qspi_copy_write_data(xqspi, &data, xqspi->bytes_to_transfer); if (!xqspi->is_dual || xqspi->is_instr) zynq_qspi_write(xqspi, offset[tmp - 1], data); else { zynq_qspi_tx_dual_parallel(xqspi, data, tmp); } } } else { /* * If transfer and receive is completed then only send * complete signal. */ if (!xqspi->bytes_to_receive) { zynq_qspi_write(xqspi, ZYNQ_QSPI_IDIS_OFFSET, ZYNQ_QSPI_IXR_ALL_MASK); spi_finalize_current_transfer(master); xqspi->is_instr = 0; } } return IRQ_HANDLED; } return IRQ_NONE; }
/* * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller * @zqspi: Pointer to the zynq_qspi structure * * This function handles TX empty and Mode Fault interrupts only. * On TX empty interrupt this function reads the received data from RX FIFO and * fills the TX FIFO if there is any data remaining to be transferred. * On Mode Fault interrupt this function indicates that transfer is completed, * the SPI subsystem will identify the error as the remaining bytes to be * transferred is non-zero. * * returns: 0 for poll timeout * 1 transfer operation complete */ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv) { int max_loop; u32 intr_status; u32 rxindex = 0; u32 rxcount; struct zynq_qspi_regs *regs = priv->regs; debug("%s: zqspi: 0x%08x\n", __func__, (u32)priv); /* Poll until any of the interrupt status bits are set */ max_loop = 0; do { intr_status = readl(®s->isr); max_loop++; } while ((intr_status == 0) && (max_loop < 100000)); if (intr_status == 0) { debug("%s: Timeout\n", __func__); return 0; } writel(intr_status, ®s->isr); /* Disable all interrupts */ writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idisr); if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) || (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) { /* * This bit is set when Tx FIFO has < THRESHOLD entries. We have * the THRESHOLD value set to 1, so this bit indicates Tx FIFO * is empty */ rxcount = priv->bytes_to_receive - priv->bytes_to_transfer; rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4); while ((rxindex < rxcount) && (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) { /* Read out the data from the RX FIFO */ u32 data; data = readl(®s->drxr); if (priv->bytes_to_receive >= 4) { if (priv->rxbuf) { memcpy(priv->rxbuf, &data, 4); priv->rxbuf += 4; } priv->bytes_to_receive -= 4; } else { zynq_qspi_copy_read_data(priv, data, priv->bytes_to_receive); } rxindex++; } if (priv->bytes_to_transfer) { /* There is more data to send */ zynq_qspi_fill_tx_fifo(priv, ZYNQ_QSPI_RXFIFO_THRESHOLD); writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->ier); } else { /* * If transfer and receive is completed then only send * complete signal */ if (!priv->bytes_to_receive) { /* return operation complete */ writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idisr); return 1; } } } return 0; }