irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) { u32 irq_status; void __iomem *reg = drv_data->ioaddr; irq_status = read_SSSR(reg) & drv_data->mask_sr; if (irq_status & SSSR_ROR) { pxa2xx_spi_dma_error_stop(drv_data, "dma_transfer: fifo overrun"); return IRQ_HANDLED; } /* Check for false positive timeout */ if ((irq_status & SSSR_TINT) && (DCSR(drv_data->tx_channel) & DCSR_RUN)) { write_SSSR(SSSR_TINT, reg); return IRQ_HANDLED; } if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) { /* Clear and disable timeout interrupt, do the rest in * dma_transfer_complete */ if (!pxa25x_ssp_comp(drv_data)) write_SSTO(0, reg); /* finish this transfer, start the next */ pxa2xx_spi_dma_transfer_complete(drv_data); return IRQ_HANDLED; } /* Opps problem detected */ return IRQ_NONE; }
void pxa2xx_spi_dma_handler(int channel, void *data) { struct driver_data *drv_data = data; u32 irq_status = DCSR(channel) & DMA_INT_MASK; if (irq_status & DCSR_BUSERR) { if (channel == drv_data->tx_channel) pxa2xx_spi_dma_error_stop(drv_data, "dma_handler: bad bus address on tx channel"); else pxa2xx_spi_dma_error_stop(drv_data, "dma_handler: bad bus address on rx channel"); return; } /* PXA255x_SSP has no timeout interrupt, wait for tailing bytes */ if ((channel == drv_data->tx_channel) && (irq_status & DCSR_ENDINTR) && (drv_data->ssp_type == PXA25x_SSP)) { /* Wait for rx to stall */ if (wait_ssp_rx_stall(drv_data->ioaddr) == 0) dev_err(&drv_data->pdev->dev, "dma_handler: ssp rx stall failed\n"); /* finish this transfer, start the next */ pxa2xx_spi_dma_transfer_complete(drv_data); } }
irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) { u32 status; status = pxa2xx_spi_read(drv_data, SSSR) & drv_data->mask_sr; if (status & SSSR_ROR) { dev_err(&drv_data->pdev->dev, "FIFO overrun\n"); dmaengine_terminate_async(drv_data->master->dma_rx); dmaengine_terminate_async(drv_data->master->dma_tx); pxa2xx_spi_dma_transfer_complete(drv_data, true); return IRQ_HANDLED; } return IRQ_NONE; }
static void pxa2xx_spi_dma_callback(void *data) { pxa2xx_spi_dma_transfer_complete(data, false); }