Skip to content

Commit 9203dbe

Browse files
morimotovinodkoul
authored andcommitted
dmaengine: rcar-dmac: don't use DMAC error interrupt
rcar-dmac has 2 types of interrupt, 1) error IRQ (for all), 2) IRQ for each channels. If error happens on some channels, the error IRQ will be handled by 1), and "all" channels will be restarted. But in this design, error handling itself will be problem for non error channel users. This patch removes 1) handler, and handles error IRQ on 2) Signed-off-by: Magnus Damm <[email protected]> [Kuninori: updated patch to adjust DMACHCR/DMAOR] Signed-off-by: Kuninori Morimoto <[email protected]> Tested-by: Nguyen Viet Dung <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Signed-off-by: Vinod Koul <[email protected]>
1 parent eb9fe60 commit 9203dbe

File tree

1 file changed

+22
-50
lines changed

1 file changed

+22
-50
lines changed

drivers/dma/sh/rcar-dmac.c

Lines changed: 22 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
431431
chcr |= RCAR_DMACHCR_DPM_DISABLED | RCAR_DMACHCR_IE;
432432
}
433433

434-
rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr | RCAR_DMACHCR_DE);
434+
rcar_dmac_chan_write(chan, RCAR_DMACHCR,
435+
chcr | RCAR_DMACHCR_DE | RCAR_DMACHCR_CAIE);
435436
}
436437

437438
static int rcar_dmac_init(struct rcar_dmac *dmac)
@@ -783,7 +784,8 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
783784
u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
784785

785786
chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
786-
RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
787+
RCAR_DMACHCR_TE | RCAR_DMACHCR_DE |
788+
RCAR_DMACHCR_CAE | RCAR_DMACHCR_CAIE);
787789
rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
788790
rcar_dmac_chcr_de_barrier(chan);
789791
}
@@ -812,12 +814,7 @@ static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
812814
}
813815
}
814816

815-
static void rcar_dmac_stop(struct rcar_dmac *dmac)
816-
{
817-
rcar_dmac_write(dmac, RCAR_DMAOR, 0);
818-
}
819-
820-
static void rcar_dmac_abort(struct rcar_dmac *dmac)
817+
static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac)
821818
{
822819
unsigned int i;
823820

@@ -829,11 +826,10 @@ static void rcar_dmac_abort(struct rcar_dmac *dmac)
829826
spin_lock(&chan->lock);
830827
rcar_dmac_chan_halt(chan);
831828
spin_unlock(&chan->lock);
832-
833-
rcar_dmac_chan_reinit(chan);
834829
}
835830
}
836831

832+
837833
/* -----------------------------------------------------------------------------
838834
* Descriptors preparation
839835
*/
@@ -1522,11 +1518,18 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
15221518
u32 mask = RCAR_DMACHCR_DSE | RCAR_DMACHCR_TE;
15231519
struct rcar_dmac_chan *chan = dev;
15241520
irqreturn_t ret = IRQ_NONE;
1521+
bool reinit = false;
15251522
u32 chcr;
15261523

15271524
spin_lock(&chan->lock);
15281525

15291526
chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
1527+
if (chcr & RCAR_DMACHCR_CAE) {
1528+
rcar_dmac_chan_halt(chan);
1529+
reinit = true;
1530+
goto spin_lock_end;
1531+
}
1532+
15301533
if (chcr & RCAR_DMACHCR_TE)
15311534
mask |= RCAR_DMACHCR_DE;
15321535
rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
@@ -1539,8 +1542,16 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
15391542
if (chcr & RCAR_DMACHCR_TE)
15401543
ret |= rcar_dmac_isr_transfer_end(chan);
15411544

1545+
spin_lock_end:
15421546
spin_unlock(&chan->lock);
15431547

1548+
if (reinit) {
1549+
dev_err(chan->chan.device->dev, "Channel Address Error\n");
1550+
1551+
rcar_dmac_chan_reinit(chan);
1552+
ret = IRQ_HANDLED;
1553+
}
1554+
15441555
return ret;
15451556
}
15461557

@@ -1597,24 +1608,6 @@ static irqreturn_t rcar_dmac_isr_channel_thread(int irq, void *dev)
15971608
return IRQ_HANDLED;
15981609
}
15991610

1600-
static irqreturn_t rcar_dmac_isr_error(int irq, void *data)
1601-
{
1602-
struct rcar_dmac *dmac = data;
1603-
1604-
if (!(rcar_dmac_read(dmac, RCAR_DMAOR) & RCAR_DMAOR_AE))
1605-
return IRQ_NONE;
1606-
1607-
/*
1608-
* An unrecoverable error occurred on an unknown channel. Halt the DMAC,
1609-
* abort transfers on all channels, and reinitialize the DMAC.
1610-
*/
1611-
rcar_dmac_stop(dmac);
1612-
rcar_dmac_abort(dmac);
1613-
rcar_dmac_init(dmac);
1614-
1615-
return IRQ_HANDLED;
1616-
}
1617-
16181611
/* -----------------------------------------------------------------------------
16191612
* OF xlate and channel filter
16201613
*/
@@ -1784,8 +1777,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
17841777
struct rcar_dmac *dmac;
17851778
struct resource *mem;
17861779
unsigned int i;
1787-
char *irqname;
1788-
int irq;
17891780
int ret;
17901781

17911782
dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
@@ -1824,17 +1815,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
18241815
if (IS_ERR(dmac->iomem))
18251816
return PTR_ERR(dmac->iomem);
18261817

1827-
irq = platform_get_irq_byname(pdev, "error");
1828-
if (irq < 0) {
1829-
dev_err(&pdev->dev, "no error IRQ specified\n");
1830-
return -ENODEV;
1831-
}
1832-
1833-
irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:error",
1834-
dev_name(dmac->dev));
1835-
if (!irqname)
1836-
return -ENOMEM;
1837-
18381818
/* Enable runtime PM and initialize the device. */
18391819
pm_runtime_enable(&pdev->dev);
18401820
ret = pm_runtime_get_sync(&pdev->dev);
@@ -1885,14 +1865,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
18851865
goto error;
18861866
}
18871867

1888-
ret = devm_request_irq(&pdev->dev, irq, rcar_dmac_isr_error, 0,
1889-
irqname, dmac);
1890-
if (ret) {
1891-
dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
1892-
irq, ret);
1893-
return ret;
1894-
}
1895-
18961868
/* Register the DMAC as a DMA provider for DT. */
18971869
ret = of_dma_controller_register(pdev->dev.of_node, rcar_dmac_of_xlate,
18981870
NULL);
@@ -1932,7 +1904,7 @@ static void rcar_dmac_shutdown(struct platform_device *pdev)
19321904
{
19331905
struct rcar_dmac *dmac = platform_get_drvdata(pdev);
19341906

1935-
rcar_dmac_stop(dmac);
1907+
rcar_dmac_stop_all_chan(dmac);
19361908
}
19371909

19381910
static const struct of_device_id rcar_dmac_of_ids[] = {

0 commit comments

Comments
 (0)