[PATCH] dmaengine: rcar: Fix release resources after interrupt process

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@xxxxxxxxxxx>

This patch fixes the problem that occasionally released resources
before the end of interrupt processing.

[   58.156412] Unable to handle kernel NULL pointer dereference at virtual
 address 00000000
[   58.166155] pgd = ffff8006f78b0000
[   58.169822] [00000000] *pgd=000000073773b003 , *pud=0000000737c70003 ,
 *pmd=0000000000000000
[   58.179738]
[   58.181548] Internal error: Oops: 96000046 [#1] PREEMPT SMP
[   58.187484] Modules linked in:
[   58.190919] CPU: 0 PID: 2898 Comm: dma_ioctl Not tainted 4.9.0-00002-g501
07f2-dirty #147
[   58.199438] Hardware name: Renesas Salvator-X board based on r8a7795 (DT)
[   58.206680] task: ffff8006f77b1900 task.stack: ffff8006f7bd4000
[   58.213090] PC is at rcar_dmac_chan_prep_sg+0xa4/0x3f0
[   58.218725] LR is at rcar_dmac_chan_prep_sg+0x6c/0x3f0

Signed-off-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@xxxxxxxxxxx>
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx>
---
 drivers/dma/sh/rcar-dmac.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 2e441d0..2e0a0d4 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -986,8 +986,11 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan)
 {
 	struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
 	struct rcar_dmac *dmac = to_rcar_dmac(chan->device);
+	struct platform_device *pdev = to_platform_device(dmac->dev);
 	struct rcar_dmac_desc_page *page, *_page;
 	struct rcar_dmac_desc *desc;
+	int irq;
+	char pdev_irqname[5];
 	LIST_HEAD(list);
 
 	/* Protect against ISR */
@@ -995,6 +998,14 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan)
 	rcar_dmac_chan_halt(rchan);
 	spin_unlock_irq(&rchan->lock);
 
+	sprintf(pdev_irqname, "ch%u", rchan->index);
+	irq = platform_get_irq_byname(pdev, pdev_irqname);
+	if (irq < 0) {
+		dev_err(dmac->dev, "no IRQ specified for channel %u\n",
+			rchan->index);
+		return;
+	}
+	synchronize_irq(irq);
 	/* Now no new interrupts will occur */
 
 	if (rchan->mid_rid >= 0) {
-- 
1.9.1




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux