dmaengine: shdma: Fix SH_DMAC_MAX_CHANNELS handling
Fix the shdma.c handing of SH_DMAC_MAX_CHANNELS to avoid overwriting the chan_irq[] and chan_flag[] arrays in the case of pdata->channel_num is larger than SH_DMAC_MAX_CHANNELS. With this patch applied up to SH_DMAC_MAX_CHANNELS will be used by the shdma.c driver. If more channels are available in the platform data the user will be notified on the console. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
26fc02ab55
commit
300e5f97d2
1 changed files with 23 additions and 8 deletions
|
@ -1083,7 +1083,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|||
unsigned long irqflags = IRQF_DISABLED,
|
||||
chan_flag[SH_DMAC_MAX_CHANNELS] = {};
|
||||
int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
|
||||
int err, i, irq_cnt = 0, irqres = 0;
|
||||
int err, i, irq_cnt = 0, irqres = 0, irq_cap = 0;
|
||||
struct sh_dmae_device *shdev;
|
||||
struct resource *chan, *dmars, *errirq_res, *chanirq_res;
|
||||
|
||||
|
@ -1208,8 +1208,13 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|||
!platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
|
||||
/* Special case - all multiplexed */
|
||||
for (; irq_cnt < pdata->channel_num; irq_cnt++) {
|
||||
chan_irq[irq_cnt] = chanirq_res->start;
|
||||
chan_flag[irq_cnt] = IRQF_SHARED;
|
||||
if (irq_cnt < SH_DMAC_MAX_CHANNELS) {
|
||||
chan_irq[irq_cnt] = chanirq_res->start;
|
||||
chan_flag[irq_cnt] = IRQF_SHARED;
|
||||
} else {
|
||||
irq_cap = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
|
@ -1223,22 +1228,32 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|||
"Found IRQ %d for channel %d\n",
|
||||
i, irq_cnt);
|
||||
chan_irq[irq_cnt++] = i;
|
||||
|
||||
if (irq_cnt >= SH_DMAC_MAX_CHANNELS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (irq_cnt >= SH_DMAC_MAX_CHANNELS) {
|
||||
irq_cap = 1;
|
||||
break;
|
||||
}
|
||||
chanirq_res = platform_get_resource(pdev,
|
||||
IORESOURCE_IRQ, ++irqres);
|
||||
} while (irq_cnt < pdata->channel_num && chanirq_res);
|
||||
}
|
||||
|
||||
if (irq_cnt < pdata->channel_num)
|
||||
goto eirqres;
|
||||
|
||||
/* Create DMA Channel */
|
||||
for (i = 0; i < pdata->channel_num; i++) {
|
||||
for (i = 0; i < irq_cnt; i++) {
|
||||
err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
|
||||
if (err)
|
||||
goto chan_probe_err;
|
||||
}
|
||||
|
||||
if (irq_cap)
|
||||
dev_notice(&pdev->dev, "Attempting to register %d DMA "
|
||||
"channels when a maximum of %d are supported.\n",
|
||||
pdata->channel_num, SH_DMAC_MAX_CHANNELS);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
platform_set_drvdata(pdev, shdev);
|
||||
|
@ -1248,7 +1263,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|||
|
||||
chan_probe_err:
|
||||
sh_dmae_chan_remove(shdev);
|
||||
eirqres:
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
|
||||
free_irq(errirq, shdev);
|
||||
eirq_err:
|
||||
|
|
Loading…
Reference in a new issue