From 37580559f314bfba0c8bdae002bc5c10088ac457 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:07 +0200 Subject: [PATCH 1/4] dmaengine: idma64: drop IRQ enable / disable in handler There is no need to disable interrupts in the IRQ handler. The driver guarantess that at one time only one descriptor is active, besides the fact that each call to the same channel will be serialized in idma64_chan_irq() handler anyway. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 7d56b47e4fcf..6bba0907c263 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -178,20 +178,12 @@ static irqreturn_t idma64_irq(int irq, void *dev) if (!status) return IRQ_NONE; - /* Disable interrupts */ - channel_clear_bit(idma64, MASK(XFER), idma64->all_chan_mask); - channel_clear_bit(idma64, MASK(ERROR), idma64->all_chan_mask); - status_xfer = dma_readl(idma64, RAW(XFER)); status_err = dma_readl(idma64, RAW(ERROR)); for (i = 0; i < idma64->dma.chancnt; i++) idma64_chan_irq(idma64, i, status_err, status_xfer); - /* Re-enable interrupts */ - channel_set_bit(idma64, MASK(XFER), idma64->all_chan_mask); - channel_set_bit(idma64, MASK(ERROR), idma64->all_chan_mask); - return IRQ_HANDLED; } From e3fdb1894cfac6dd4a5bb24d3232fd97ddf74c93 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:08 +0200 Subject: [PATCH 2/4] dmaengine: idma64: set maximum allowed segment size for DMA This tells, for example, IOMMU what the maximum size of a segment the DMA controller can send. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 2 ++ drivers/dma/idma64.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 6bba0907c263..97802be31588 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -588,6 +588,8 @@ static int idma64_probe(struct idma64_chip *chip) idma64->dma.dev = chip->dev; + dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + ret = dma_async_device_register(&idma64->dma); if (ret) return ret; diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h index f6aeff0af8a5..8423f13ed0da 100644 --- a/drivers/dma/idma64.h +++ b/drivers/dma/idma64.h @@ -54,7 +54,8 @@ #define IDMA64C_CTLL_LLP_S_EN (1 << 28) /* src block chain */ /* Bitfields in CTL_HI */ -#define IDMA64C_CTLH_BLOCK_TS(x) ((x) & ((1 << 17) - 1)) +#define IDMA64C_CTLH_BLOCK_TS_MASK ((1 << 17) - 1) +#define IDMA64C_CTLH_BLOCK_TS(x) ((x) & IDMA64C_CTLH_BLOCK_TS_MASK) #define IDMA64C_CTLH_DONE (1 << 17) /* Bitfields in CFG_LO */ From ac02979413e0310f85bbcc2945d65da7071c08fe Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:09 +0200 Subject: [PATCH 3/4] dmaengine: idma64: convert idma64_hw_desc_fill() to return void Explicitly show in idma64_desc_fill() how we link the hardware descriptors. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 97802be31588..b6c13f9fffb6 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -231,7 +231,7 @@ static void idma64_vdesc_free(struct virt_dma_desc *vdesc) idma64_desc_free(idma64c, to_idma64_desc(vdesc)); } -static u64 idma64_hw_desc_fill(struct idma64_hw_desc *hw, +static void idma64_hw_desc_fill(struct idma64_hw_desc *hw, struct dma_slave_config *config, enum dma_transfer_direction direction, u64 llp) { @@ -268,7 +268,6 @@ static u64 idma64_hw_desc_fill(struct idma64_hw_desc *hw, IDMA64C_CTLL_SRC_WIDTH(src_width); lli->llp = llp; - return hw->llp; } static void idma64_desc_fill(struct idma64_chan *idma64c, @@ -283,7 +282,8 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, /* Fill the hardware descriptors and link them to a list */ do { hw = &desc->hw[--i]; - llp = idma64_hw_desc_fill(hw, config, desc->direction, llp); + idma64_hw_desc_fill(hw, config, desc->direction, llp); + llp = hw->llp; desc->length += hw->len; } while (i); From 390c49f7174a85d88ec080058d8b5c2e301d3f6b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Nov 2015 13:37:10 +0200 Subject: [PATCH 4/4] dmaengine: idma64: use local variable to index descriptor Since a local variable contains the number of hardware desriptors at the beginning of idma64_desc_fill() we may use it to index the last descriptor as well. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/idma64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index b6c13f9fffb6..3cb7b2c78197 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -274,10 +274,10 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, struct idma64_desc *desc) { struct dma_slave_config *config = &idma64c->config; - struct idma64_hw_desc *hw = &desc->hw[desc->ndesc - 1]; + unsigned int i = desc->ndesc; + struct idma64_hw_desc *hw = &desc->hw[i - 1]; struct idma64_lli *lli = hw->lli; u64 llp = 0; - unsigned int i = desc->ndesc; /* Fill the hardware descriptors and link them to a list */ do { @@ -287,7 +287,7 @@ static void idma64_desc_fill(struct idma64_chan *idma64c, desc->length += hw->len; } while (i); - /* Trigger interrupt after last block */ + /* Trigger an interrupt after the last block is transfered */ lli->ctllo |= IDMA64C_CTLL_INT_EN; }