Commit 44eb8272 authored by Frank Li's avatar Frank Li Committed by Vinod Koul

dmaengine: fsl-edma: request per-channel IRQ only when channel is allocated

The edma feature individual IRQs for each DMA channel at some devices.
Given the presence of numerous eDMA instances, each with multiple channels,
IRQ request during probe results in an extensive list at /proc/interrupts.
However, a significant portion of these channels remains unused by the
system.

Request irq only when a DMA client driver requests a DMA channel.
Signed-off-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240603152317.69917-1-Frank.Li@nxp.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 49b1c21f
...@@ -805,6 +805,7 @@ void fsl_edma_issue_pending(struct dma_chan *chan) ...@@ -805,6 +805,7 @@ void fsl_edma_issue_pending(struct dma_chan *chan)
int fsl_edma_alloc_chan_resources(struct dma_chan *chan) int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
{ {
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
int ret;
if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK) if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
clk_prepare_enable(fsl_chan->clk); clk_prepare_enable(fsl_chan->clk);
...@@ -813,6 +814,17 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan) ...@@ -813,6 +814,17 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ? fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd), sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
32, 0); 32, 0);
if (fsl_chan->txirq) {
ret = request_irq(fsl_chan->txirq, fsl_chan->irq_handler, IRQF_SHARED,
fsl_chan->chan_name, fsl_chan);
if (ret) {
dma_pool_destroy(fsl_chan->tcd_pool);
return ret;
}
}
return 0; return 0;
} }
...@@ -832,6 +844,9 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan) ...@@ -832,6 +844,9 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
fsl_edma_unprep_slave_dma(fsl_chan); fsl_edma_unprep_slave_dma(fsl_chan);
spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
if (fsl_chan->txirq)
free_irq(fsl_chan->txirq, fsl_chan);
vchan_dma_desc_free_list(&fsl_chan->vchan, &head); vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
dma_pool_destroy(fsl_chan->tcd_pool); dma_pool_destroy(fsl_chan->tcd_pool);
fsl_chan->tcd_pool = NULL; fsl_chan->tcd_pool = NULL;
......
...@@ -172,6 +172,7 @@ struct fsl_edma_chan { ...@@ -172,6 +172,7 @@ struct fsl_edma_chan {
int priority; int priority;
int hw_chanid; int hw_chanid;
int txirq; int txirq;
irqreturn_t (*irq_handler)(int irq, void *dev_id);
bool is_rxchan; bool is_rxchan;
bool is_remote; bool is_remote;
bool is_multi_fifo; bool is_multi_fifo;
......
...@@ -65,6 +65,13 @@ static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id) ...@@ -65,6 +65,13 @@ static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t fsl_edma2_tx_handler(int irq, void *devi_id)
{
struct fsl_edma_chan *fsl_chan = devi_id;
return fsl_edma_tx_handler(irq, fsl_chan->edma);
}
static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id) static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
{ {
struct fsl_edma_engine *fsl_edma = dev_id; struct fsl_edma_engine *fsl_edma = dev_id;
...@@ -228,7 +235,6 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma ...@@ -228,7 +235,6 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma
static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma) static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
{ {
int ret;
int i; int i;
for (i = 0; i < fsl_edma->n_chans; i++) { for (i = 0; i < fsl_edma->n_chans; i++) {
...@@ -243,13 +249,7 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi ...@@ -243,13 +249,7 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
if (fsl_chan->txirq < 0) if (fsl_chan->txirq < 0)
return -EINVAL; return -EINVAL;
ret = devm_request_irq(&pdev->dev, fsl_chan->txirq, fsl_chan->irq_handler = fsl_edma3_tx_handler;
fsl_edma3_tx_handler, IRQF_SHARED,
fsl_chan->chan_name, fsl_chan);
if (ret) {
dev_err(&pdev->dev, "Can't register chan%d's IRQ.\n", i);
return -EINVAL;
}
} }
return 0; return 0;
...@@ -278,19 +278,20 @@ fsl_edma2_irq_init(struct platform_device *pdev, ...@@ -278,19 +278,20 @@ fsl_edma2_irq_init(struct platform_device *pdev,
*/ */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
irq = platform_get_irq(pdev, i); irq = platform_get_irq(pdev, i);
ret = 0;
if (irq < 0) if (irq < 0)
return -ENXIO; return -ENXIO;
/* The last IRQ is for eDMA err */ /* The last IRQ is for eDMA err */
if (i == count - 1) if (i == count - 1) {
ret = devm_request_irq(&pdev->dev, irq, ret = devm_request_irq(&pdev->dev, irq,
fsl_edma_err_handler, fsl_edma_err_handler,
0, "eDMA2-ERR", fsl_edma); 0, "eDMA2-ERR", fsl_edma);
else } else {
ret = devm_request_irq(&pdev->dev, irq, fsl_edma->chans[i].txirq = irq;
fsl_edma_tx_handler, 0, fsl_edma->chans[i].irq_handler = fsl_edma2_tx_handler;
fsl_edma->chans[i].chan_name, }
fsl_edma);
if (ret) if (ret)
return ret; return ret;
} }
......
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