|
@@ -1083,7 +1083,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|
unsigned long irqflags = IRQF_DISABLED,
|
|
unsigned long irqflags = IRQF_DISABLED,
|
|
chan_flag[SH_DMAC_MAX_CHANNELS] = {};
|
|
chan_flag[SH_DMAC_MAX_CHANNELS] = {};
|
|
int errirq, chan_irq[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 sh_dmae_device *shdev;
|
|
struct resource *chan, *dmars, *errirq_res, *chanirq_res;
|
|
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)) {
|
|
!platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
|
|
/* Special case - all multiplexed */
|
|
/* Special case - all multiplexed */
|
|
for (; irq_cnt < pdata->channel_num; irq_cnt++) {
|
|
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 {
|
|
} else {
|
|
do {
|
|
do {
|
|
@@ -1223,22 +1228,32 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|
"Found IRQ %d for channel %d\n",
|
|
"Found IRQ %d for channel %d\n",
|
|
i, irq_cnt);
|
|
i, irq_cnt);
|
|
chan_irq[irq_cnt++] = i;
|
|
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,
|
|
chanirq_res = platform_get_resource(pdev,
|
|
IORESOURCE_IRQ, ++irqres);
|
|
IORESOURCE_IRQ, ++irqres);
|
|
} while (irq_cnt < pdata->channel_num && chanirq_res);
|
|
} while (irq_cnt < pdata->channel_num && chanirq_res);
|
|
}
|
|
}
|
|
|
|
|
|
- if (irq_cnt < pdata->channel_num)
|
|
|
|
- goto eirqres;
|
|
|
|
-
|
|
|
|
/* Create DMA Channel */
|
|
/* 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]);
|
|
err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
|
|
if (err)
|
|
if (err)
|
|
goto chan_probe_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);
|
|
pm_runtime_put(&pdev->dev);
|
|
|
|
|
|
platform_set_drvdata(pdev, shdev);
|
|
platform_set_drvdata(pdev, shdev);
|
|
@@ -1248,7 +1263,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
|
|
|
|
|
chan_probe_err:
|
|
chan_probe_err:
|
|
sh_dmae_chan_remove(shdev);
|
|
sh_dmae_chan_remove(shdev);
|
|
-eirqres:
|
|
|
|
|
|
+
|
|
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
|
|
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
|
|
free_irq(errirq, shdev);
|
|
free_irq(errirq, shdev);
|
|
eirq_err:
|
|
eirq_err:
|