openwrt/target/linux/layerscape/patches-5.4/806-dma-0021-MLK-21443-dmaengine-fsl-edma-v3-clear-pending-irq-be.patch
Yangbo Lu cddd459140 layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release
which was tagged LSDK-20.04-V5.4.
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/

For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in
LSDK, port the dts patches from 4.14.

The patches are sorted into the following categories:
  301-arch-xxxx
  302-dts-xxxx
  303-core-xxxx
  701-net-xxxx
  801-audio-xxxx
  802-can-xxxx
  803-clock-xxxx
  804-crypto-xxxx
  805-display-xxxx
  806-dma-xxxx
  807-gpio-xxxx
  808-i2c-xxxx
  809-jailhouse-xxxx
  810-keys-xxxx
  811-kvm-xxxx
  812-pcie-xxxx
  813-pm-xxxx
  814-qe-xxxx
  815-sata-xxxx
  816-sdhc-xxxx
  817-spi-xxxx
  818-thermal-xxxx
  819-uart-xxxx
  820-usb-xxxx
  821-vfio-xxxx

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
2020-05-07 12:53:06 +02:00

125 lines
4.1 KiB
Diff

From 63c3fd953a620873c722494355a345643607c0a2 Mon Sep 17 00:00:00 2001
From: Robin Gong <yibin.gong@nxp.com>
Date: Thu, 11 Apr 2019 14:36:37 +0800
Subject: [PATCH] MLK-21443: dmaengine: fsl-edma-v3: clear pending irq before
request irq
edma interrupt maybe happened during reboot or watchdog reset, meanwhile
gic never power down on i.mx8QM/QXP, thus the unexpect irq will come in
once edma driver request irq at probe phase. Unfortunately, at that time
that edma channel's power domain which power-up by customer driver such
as audio/uart driver may not be ready, so kernel panic triggered once
touch such edma registers which still not power up in interrupt handler.
Move request irq from probe to alloc dma channel so that edma channel's
power domain has already been powered, besides, clear meaningless
interrupt before request irq.
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
(cherry picked from commit 0a0d8f8b944094342fda18f23f3ac13b8a73871d)
---
drivers/dma/fsl-edma-v3.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
--- a/drivers/dma/fsl-edma-v3.c
+++ b/drivers/dma/fsl-edma-v3.c
@@ -162,7 +162,8 @@ struct fsl_edma3_chan {
int is_dfifo;
struct dma_pool *tcd_pool;
u32 chn_real_count;
- char txirq_name[32];
+ char txirq_name[32];
+ struct platform_device *pdev;
};
struct fsl_edma3_desc {
@@ -180,6 +181,7 @@ struct fsl_edma3_reg_save {
struct fsl_edma3_engine {
struct dma_device dma_dev;
+ unsigned long irqflag;
struct mutex fsl_edma3_mutex;
u32 n_chans;
int errirq;
@@ -790,10 +792,23 @@ static struct dma_chan *fsl_edma3_xlate(
static int fsl_edma3_alloc_chan_resources(struct dma_chan *chan)
{
struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
+ struct platform_device *pdev = fsl_chan->pdev;
+ int ret;
fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
sizeof(struct fsl_edma3_hw_tcd),
32, 0);
+ /* clear meaningless pending irq anyway */
+ writel(1, fsl_chan->membase + EDMA_CH_INT);
+ ret = devm_request_irq(&pdev->dev, fsl_chan->txirq,
+ fsl_edma3_tx_handler, fsl_chan->edma3->irqflag,
+ fsl_chan->txirq_name, fsl_chan);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register %s IRQ.\n",
+ fsl_chan->txirq_name);
+ return ret;
+ }
+
return 0;
}
@@ -803,6 +818,8 @@ static void fsl_edma3_free_chan_resource
unsigned long flags;
LIST_HEAD(head);
+ devm_free_irq(&fsl_chan->pdev->dev, fsl_chan->txirq, fsl_chan);
+
spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
fsl_edma3_disable_request(fsl_chan);
fsl_chan->edesc = NULL;
@@ -830,7 +847,6 @@ static int fsl_edma3_probe(struct platfo
struct resource *res;
int len, chans;
int ret, i;
- unsigned long irqflag = 0;
ret = of_property_read_u32(np, "dma-channels", &chans);
if (ret) {
@@ -845,7 +861,7 @@ static int fsl_edma3_probe(struct platfo
/* Audio edma rx/tx channel shared interrupt */
if (of_property_read_bool(np, "shared-interrupt"))
- irqflag = IRQF_SHARED;
+ fsl_edma3->irqflag = IRQF_SHARED;
fsl_edma3->swap = of_device_is_compatible(np, "fsl,imx8qm-adma");
fsl_edma3->n_chans = chans;
@@ -853,12 +869,13 @@ static int fsl_edma3_probe(struct platfo
INIT_LIST_HEAD(&fsl_edma3->dma_dev.channels);
for (i = 0; i < fsl_edma3->n_chans; i++) {
struct fsl_edma3_chan *fsl_chan = &fsl_edma3->chans[i];
- const char *txirq_name = fsl_chan->txirq_name;
+ const char *txirq_name;
char chanid[3], id_len = 0;
char *p = chanid;
unsigned long val;
fsl_chan->edma3 = fsl_edma3;
+ fsl_chan->pdev = pdev;
fsl_chan->pm_state = RUNNING;
fsl_chan->idle = true;
/* Get per channel membase */
@@ -904,14 +921,7 @@ static int fsl_edma3_probe(struct platfo
return fsl_chan->txirq;
}
- ret = devm_request_irq(&pdev->dev, fsl_chan->txirq,
- fsl_edma3_tx_handler, irqflag, txirq_name,
- fsl_chan);
- if (ret) {
- dev_err(&pdev->dev, "Can't register %s IRQ.\n",
- txirq_name);
- return ret;
- }
+ memcpy(fsl_chan->txirq_name, txirq_name, strlen(txirq_name));
fsl_chan->vchan.desc_free = fsl_edma3_free_desc;
vchan_init(&fsl_chan->vchan, &fsl_edma3->dma_dev);