diff options
Diffstat (limited to 'drivers/dma/idma64.c')
| -rw-r--r-- | drivers/dma/idma64.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index f4c07ad3be15..d147353d47ab 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -137,8 +137,11 @@ static void idma64_chan_irq(struct idma64 *idma64, unsigned short c, u32 status_err, u32 status_xfer) { struct idma64_chan *idma64c = &idma64->chan[c]; + struct dma_chan_percpu *stat; struct idma64_desc *desc; + stat = this_cpu_ptr(idma64c->vchan.chan.local); + spin_lock(&idma64c->vchan.lock); desc = idma64c->desc; if (desc) { @@ -149,6 +152,7 @@ static void idma64_chan_irq(struct idma64 *idma64, unsigned short c, dma_writel(idma64, CLEAR(XFER), idma64c->mask); desc->status = DMA_COMPLETE; vchan_cookie_complete(&desc->vdesc); + stat->bytes_transferred += desc->length; idma64_start_transfer(idma64c); } @@ -167,6 +171,10 @@ static irqreturn_t idma64_irq(int irq, void *dev) u32 status_err; unsigned short i; + /* Since IRQ may be shared, check if DMA controller is powered on */ + if (status == GENMASK(31, 0)) + return IRQ_NONE; + dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status); /* Check if we have any interrupt from the DMA controller */ @@ -282,7 +290,7 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, desc->length += hw->len; } while (i); - /* Trigger an interrupt after the last block is transfered */ + /* Trigger an interrupt after the last block is transferred */ lli->ctllo |= IDMA64C_CTLL_INT_EN; /* Disable LLP transfer in the last block */ @@ -356,7 +364,7 @@ static size_t idma64_active_desc_size(struct idma64_chan *idma64c) if (!i) return bytes; - /* The current chunk is not fully transfered yet */ + /* The current chunk is not fully transferred yet */ bytes += desc->hw[--i].len; return bytes - IDMA64C_CTLH_BLOCK_TS(ctlhi); @@ -600,7 +608,7 @@ static int idma64_probe(struct idma64_chip *chip) return 0; } -static int idma64_remove(struct idma64_chip *chip) +static void idma64_remove(struct idma64_chip *chip) { struct idma64 *idma64 = chip->idma64; unsigned short i; @@ -618,8 +626,6 @@ static int idma64_remove(struct idma64_chip *chip) tasklet_kill(&idma64c->vchan.task); } - - return 0; } /* ---------------------------------------------------------------------- */ @@ -629,7 +635,6 @@ static int idma64_platform_probe(struct platform_device *pdev) struct idma64_chip *chip; struct device *dev = &pdev->dev; struct device *sysdev = dev->parent; - struct resource *mem; int ret; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); @@ -640,8 +645,7 @@ static int idma64_platform_probe(struct platform_device *pdev) if (chip->irq < 0) return chip->irq; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - chip->regs = devm_ioremap_resource(dev, mem); + chip->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->regs)) return PTR_ERR(chip->regs); @@ -660,11 +664,11 @@ static int idma64_platform_probe(struct platform_device *pdev) return 0; } -static int idma64_platform_remove(struct platform_device *pdev) +static void idma64_platform_remove(struct platform_device *pdev) { struct idma64_chip *chip = platform_get_drvdata(pdev); - return idma64_remove(chip); + idma64_remove(chip); } static int __maybe_unused idma64_pm_suspend(struct device *dev) |
