Commit d2ddb8ac authored by Federico Vaga's avatar Federico Vaga

sw:drv: DMA has only one interrupt line now to be acked

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent ababe289
......@@ -43,7 +43,6 @@ enum spec_fpga_irq_lines {
SPEC_FPGA_IRQ_FMC_I2C = 0,
SPEC_FPGA_IRQ_SPI,
SPEC_FPGA_IRQ_DMA_DONE,
SPEC_FPGA_IRQ_DMA_ERROR,
};
enum spec_fpga_csr_offsets {
......@@ -269,11 +268,6 @@ static struct resource spec_fpga_dma_res[] = {
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
.start = 0,
.end = 0,
}, {
.name = "spec-gn412x-dma-irq-err",
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
.start = 0,
.end = 0,
},
};
......@@ -308,7 +302,6 @@ static int spec_fpga_dma_init(struct spec_fpga *spec_fpga)
res[0].start += pci_start;
res[0].end += pci_start;
res[1].start = irq_find_mapping(vic_domain, SPEC_FPGA_IRQ_DMA_DONE);
res[2].start = irq_find_mapping(vic_domain, SPEC_FPGA_IRQ_DMA_ERROR);
pdev = platform_device_register_resndata(&spec_fpga->dev,
"spec-gn412x-dma",
PLATFORM_DEVID_AUTO,
......
......@@ -143,12 +143,11 @@ enum gn412x_dma_id_enum {
enum gn412x_dma_state {
GN412X_DMA_STAT_IDLE = 0,
GN412X_DMA_STAT_DONE,
GN412X_DMA_STAT_BUSY,
GN412X_DMA_STAT_ERROR,
GN412X_DMA_STAT_ABORTED,
};
#define GN412X_DMA_STAT_ACK BIT(2)
/**
......@@ -304,13 +303,9 @@ static void gn412x_dma_ctrl_swapping(struct gn412x_dma_device *gn412x_dma,
iowrite32(ctrl, gn412x_dma->addr + GN412X_DMA_CTRL);
}
static bool gn412x_dma_is_done(struct gn412x_dma_device *gn412x_dma)
static enum gn412x_dma_state gn412x_dma_state(struct gn412x_dma_device *gn412x_dma)
{
uint32_t status;
status = ioread32(gn412x_dma->addr + GN412X_DMA_STAT);
return status & GN412X_DMA_STAT_DONE;
return ioread32(gn412x_dma->addr + GN412X_DMA_STAT);
}
static bool gn412x_dma_is_busy(struct gn412x_dma_device *gn412x_dma)
......@@ -322,22 +317,18 @@ static bool gn412x_dma_is_busy(struct gn412x_dma_device *gn412x_dma)
return status & GN412X_DMA_STAT_BUSY;
}
static bool gn412x_dma_is_error(struct gn412x_dma_device *gn412x_dma)
static bool gn412x_dma_is_abort(struct gn412x_dma_device *gn412x_dma)
{
uint32_t status;
status = ioread32(gn412x_dma->addr + GN412X_DMA_STAT);
return status & GN412X_DMA_STAT_ERROR;
return status & GN412X_DMA_STAT_ABORTED;
}
static bool gn412x_dma_is_abort(struct gn412x_dma_device *gn412x_dma)
static void gn412x_dma_irq_ack(struct gn412x_dma_device *gn412x_dma)
{
uint32_t status;
status = ioread32(gn412x_dma->addr + GN412X_DMA_STAT);
return status & GN412X_DMA_STAT_ABORTED;
iowrite32(GN412X_DMA_STAT_ACK, gn412x_dma->addr + GN412X_DMA_STAT);
}
static void gn412x_dma_config(struct gn412x_dma_device *gn412x_dma,
......@@ -572,39 +563,39 @@ static int gn412x_dma_device_control(struct dma_chan *chan,
}
static irqreturn_t gn412x_dma_irq_handler_err(int irq, void *arg)
{
struct gn412x_dma_device *gn412x_dma = arg;
struct gn412x_dma_chan *chan = &gn412x_dma->chan;
if (unlikely(!gn412x_dma_is_error(gn412x_dma)))
return IRQ_NONE;
/* FIXM check also done?*/
chan->error++;
return IRQ_HANDLED;
}
static irqreturn_t gn412x_dma_irq_handler_done(int irq, void *arg)
static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg)
{
struct gn412x_dma_device *gn412x_dma = arg;
struct gn412x_dma_chan *chan = &gn412x_dma->chan;
struct gn412x_dma_tx *tx;
unsigned long flags;
unsigned int i;
uint32_t state;
if (unlikely(!gn412x_dma_is_done(gn412x_dma)))
return IRQ_NONE;
/* FIXM check also error?*/
/* FIXME check for spurious - need HDL fix */
gn412x_dma_irq_ack(gn412x_dma);
spin_lock_irqsave(&chan->lock, flags);
tx = chan->tx_curr;
chan->tx_curr = NULL;
spin_unlock_irqrestore(&chan->lock, flags);
dma_cookie_complete(&tx->tx);
tx->tx.callback(tx->tx.callback_param);
state = gn412x_dma_state(gn412x_dma);
switch (state) {
case GN412X_DMA_STAT_IDLE:
dma_cookie_complete(&tx->tx);
tx->tx.callback(tx->tx.callback_param);
break;
case GN412X_DMA_STAT_ERROR:
dev_err(&gn412x_dma->pdev->dev,
"DMA transfer failed: error\n");
break;
default:
dev_err(&gn412x_dma->pdev->dev,
"DMA transfer failed: inconsitent state %d\n",
state);
break;
}
/* Clean up memory */
for (i = 0; i < tx->sg_len; ++i)
......@@ -749,15 +740,10 @@ static int gn412x_dma_probe(struct platform_device *pdev)
}
err = request_any_context_irq(platform_get_irq(pdev, 0),
gn412x_dma_irq_handler_done, 0,
dev_name(&pdev->dev), gn412x_dma);
if (err < 0)
goto err_irq_done;
err = request_any_context_irq(platform_get_irq(pdev, 1),
gn412x_dma_irq_handler_err, 0,
gn412x_dma_irq_handler, 0,
dev_name(&pdev->dev), gn412x_dma);
if (err < 0)
goto err_irq_err;
goto err_irq;
/* Get the pci_dev device because it is the one configured for DMA */
err = gn412x_dma_engine_init(gn412x_dma, pdev->dev.parent->parent);
......@@ -776,10 +762,8 @@ static int gn412x_dma_probe(struct platform_device *pdev)
err_reg:
gn412x_dma_engine_exit(gn412x_dma);
err_dma_init:
free_irq(platform_get_irq(pdev, 1), gn412x_dma);
err_irq_err:
free_irq(platform_get_irq(pdev, 0), gn412x_dma);
err_irq_done:
err_irq:
iounmap(gn412x_dma->addr);
err_map:
err_res_mem:
......@@ -804,7 +788,6 @@ static int gn412x_dma_remove(struct platform_device *pdev)
dmaengine_terminate_all(&gn412x_dma->chan.chan);
dma_async_device_unregister(&gn412x_dma->dma);
gn412x_dma_engine_exit(gn412x_dma);
free_irq(platform_get_irq(pdev, 1), gn412x_dma);
free_irq(platform_get_irq(pdev, 0), gn412x_dma);
iounmap(gn412x_dma->addr);
kfree(gn412x_dma);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment