list_for_each_entry_safe(chan, _chan, &fsl_edma->dma_dev.channels, device_node) {
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_dma.h>
#include "fsl-edma-common.h"
static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
struct fsl_edma_engine *fsl_edma = dev_id;
struct edma_regs *regs = &fsl_edma->regs;
struct fsl_edma_chan *fsl_chan;
intr = edma_readl(fsl_edma, regs->intl);
for (ch = 0; ch < fsl_edma->n_chans; ch++) {
if (intr & (0x1 << ch)) {
edma_writeb(fsl_edma, EDMA_CINT_CINT(ch), regs->cint);
fsl_chan = &fsl_edma->chans[ch];
spin_lock(&fsl_chan->vchan.lock);
if (!fsl_chan->edesc->iscyclic) {
list_del(&fsl_chan->edesc->vdesc.node);
vchan_cookie_complete(&fsl_chan->edesc->vdesc);
fsl_chan->status = DMA_COMPLETE;
vchan_cyclic_callback(&fsl_chan->edesc->vdesc);
fsl_edma_xfer_desc(fsl_chan);
spin_unlock(&fsl_chan->vchan.lock);
static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
struct fsl_edma_engine *fsl_edma = dev_id;
struct edma_regs *regs = &fsl_edma->regs;
err = edma_readl(fsl_edma, regs->errl);
for (ch = 0; ch < fsl_edma->n_chans; ch++) {
fsl_edma_disable_request(&fsl_edma->chans[ch]);
edma_writeb(fsl_edma, EDMA_CERR_CERR(ch), regs->cerr);
fsl_edma->chans[ch].status = DMA_ERROR;
fsl_edma->chans[ch].idle = true;
static irqreturn_t fsl_edma_irq_handler(int irq, void *dev_id)
if (fsl_edma_tx_handler(irq, dev_id) == IRQ_HANDLED)
return fsl_edma_err_handler(irq, dev_id);