]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: netup_unidvb: fix irq init by register it at the end of probe
authorWei Chen <harperchen1110@gmail.com>
Wed, 15 Mar 2023 13:45:18 +0000 (13:45 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Jun 2023 08:22:50 +0000 (10:22 +0200)
[ Upstream commit e6ad6233592593079db5c8fa592c298e51bc1356 ]

IRQ handler netup_spi_interrupt() takes spinlock spi->lock. The lock
is initialized in netup_spi_init(). However, irq handler is registered
before initializing the lock.

Spinlock dma->lock and i2c->lock suffer from the same problem.

Fix this by registering the irq at the end of probe.

Link: https://lore.kernel.org/linux-media/20230315134518.1074497-1-harperchen1110@gmail.com
Signed-off-by: Wei Chen <harperchen1110@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/media/pci/netup_unidvb/netup_unidvb_core.c

index 4f2ea0f035ae57e3c82095754805a27933fa21b9..0a9086f8c759d55d7c2fb2195aa6dc563cd6d53f 100644 (file)
@@ -897,12 +897,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
                ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0),
                ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1),
                pci_dev->irq);
-       if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
-                       "netup_unidvb", pci_dev) < 0) {
-               dev_err(&pci_dev->dev,
-                       "%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
-               goto irq_request_err;
-       }
+
        ndev->dma_size = 2 * 188 *
                NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT;
        ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev,
@@ -943,6 +938,14 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
                dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n");
                goto dma_setup_err;
        }
+
+       if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
+                       "netup_unidvb", pci_dev) < 0) {
+               dev_err(&pci_dev->dev,
+                       "%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
+               goto dma_setup_err;
+       }
+
        dev_info(&pci_dev->dev,
                "netup_unidvb: device has been initialized\n");
        return 0;
@@ -961,8 +964,6 @@ spi_setup_err:
        dma_free_coherent(&pci_dev->dev, ndev->dma_size,
                        ndev->dma_virt, ndev->dma_phys);
 dma_alloc_err:
-       free_irq(pci_dev->irq, pci_dev);
-irq_request_err:
        iounmap(ndev->lmmio1);
 pci_bar1_error:
        iounmap(ndev->lmmio0);