Commit c90b6544df8afbf9194b3dc7f363e907dcb7300e

Authored by Robin Gong
1 parent 348d476956

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)

Showing 1 changed file with 22 additions and 12 deletions Side-by-side Diff

drivers/dma/fsl-edma-v3.c
... ... @@ -165,7 +165,8 @@
165 165 int is_dfifo;
166 166 struct dma_pool *tcd_pool;
167 167 u32 chn_real_count;
168   - char txirq_name[32];
  168 + char txirq_name[32];
  169 + struct platform_device *pdev;
169 170 };
170 171  
171 172 struct fsl_edma3_desc {
... ... @@ -183,6 +184,7 @@
183 184  
184 185 struct fsl_edma3_engine {
185 186 struct dma_device dma_dev;
  187 + unsigned long irqflag;
186 188 struct mutex fsl_edma3_mutex;
187 189 u32 n_chans;
188 190 int errirq;
189 191  
... ... @@ -791,10 +793,23 @@
791 793 static int fsl_edma3_alloc_chan_resources(struct dma_chan *chan)
792 794 {
793 795 struct fsl_edma3_chan *fsl_chan = to_fsl_edma3_chan(chan);
  796 + struct platform_device *pdev = fsl_chan->pdev;
  797 + int ret;
794 798  
795 799 fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
796 800 sizeof(struct fsl_edma3_hw_tcd),
797 801 32, 0);
  802 + /* clear meaningless pending irq anyway */
  803 + writel(1, fsl_chan->membase + EDMA_CH_INT);
  804 + ret = devm_request_irq(&pdev->dev, fsl_chan->txirq,
  805 + fsl_edma3_tx_handler, fsl_chan->edma3->irqflag,
  806 + fsl_chan->txirq_name, fsl_chan);
  807 + if (ret) {
  808 + dev_err(&pdev->dev, "Can't register %s IRQ.\n",
  809 + fsl_chan->txirq_name);
  810 + return ret;
  811 + }
  812 +
798 813 return 0;
799 814 }
800 815  
... ... @@ -804,6 +819,8 @@
804 819 unsigned long flags;
805 820 LIST_HEAD(head);
806 821  
  822 + devm_free_irq(&fsl_chan->pdev->dev, fsl_chan->txirq, fsl_chan);
  823 +
807 824 spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
808 825 fsl_edma3_disable_request(fsl_chan);
809 826 fsl_chan->edesc = NULL;
... ... @@ -831,7 +848,6 @@
831 848 struct resource *res;
832 849 int len, chans;
833 850 int ret, i;
834   - unsigned long irqflag = 0;
835 851  
836 852 ret = of_property_read_u32(np, "dma-channels", &chans);
837 853 if (ret) {
... ... @@ -846,7 +862,7 @@
846 862  
847 863 /* Audio edma rx/tx channel shared interrupt */
848 864 if (of_property_read_bool(np, "shared-interrupt"))
849   - irqflag = IRQF_SHARED;
  865 + fsl_edma3->irqflag = IRQF_SHARED;
850 866  
851 867 fsl_edma3->swap = false;
852 868 fsl_edma3->n_chans = chans;
853 869  
... ... @@ -866,12 +882,13 @@
866 882 INIT_LIST_HEAD(&fsl_edma3->dma_dev.channels);
867 883 for (i = 0; i < fsl_edma3->n_chans; i++) {
868 884 struct fsl_edma3_chan *fsl_chan = &fsl_edma3->chans[i];
869   - const char *txirq_name = fsl_chan->txirq_name;
  885 + const char *txirq_name;
870 886 char chanid[3], id_len = 0;
871 887 char *p = chanid;
872 888 unsigned long val;
873 889  
874 890 fsl_chan->edma3 = fsl_edma3;
  891 + fsl_chan->pdev = pdev;
875 892 fsl_chan->pm_state = RUNNING;
876 893 fsl_chan->idle = true;
877 894 /* Get per channel membase */
... ... @@ -917,14 +934,7 @@
917 934 return fsl_chan->txirq;
918 935 }
919 936  
920   - ret = devm_request_irq(&pdev->dev, fsl_chan->txirq,
921   - fsl_edma3_tx_handler, irqflag, txirq_name,
922   - fsl_chan);
923   - if (ret) {
924   - dev_err(&pdev->dev, "Can't register %s IRQ.\n",
925   - txirq_name);
926   - return ret;
927   - }
  937 + memcpy(fsl_chan->txirq_name, txirq_name, strlen(txirq_name));
928 938  
929 939 fsl_chan->vchan.desc_free = fsl_edma3_free_desc;
930 940 vchan_init(&fsl_chan->vchan, &fsl_edma3->dma_dev);