aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2017-10-11 04:44:38 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-10-31 16:33:46 -0400
commitb7636e816adcb52bc96b6fb7bc9d141cbfd17ddb (patch)
tree1ea4fa1ff02a2df79fd46682f7dc46d3eb16fabb
parent139838fffec40296d7235982a1a9b917ba31530f (diff)
misc: pci_endpoint_test: Fix BUG_ON error during pci_disable_msi()
pci_disable_msi() throws a Kernel BUG if the driver has successfully requested an IRQ and not released it. Fix it here by freeing IRQs before invoking pci_disable_msi(). Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/misc/pci_endpoint_test.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index bf64d150ec41..320276f42653 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -92,6 +92,7 @@ struct pci_endpoint_test {
92 void __iomem *bar[6]; 92 void __iomem *bar[6];
93 struct completion irq_raised; 93 struct completion irq_raised;
94 int last_irq; 94 int last_irq;
95 int num_irqs;
95 /* mutex to protect the ioctls */ 96 /* mutex to protect the ioctls */
96 struct mutex mutex; 97 struct mutex mutex;
97 struct miscdevice miscdev; 98 struct miscdevice miscdev;
@@ -513,6 +514,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
513 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); 514 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
514 if (irq < 0) 515 if (irq < 0)
515 dev_err(dev, "failed to get MSI interrupts\n"); 516 dev_err(dev, "failed to get MSI interrupts\n");
517 test->num_irqs = irq;
516 } 518 }
517 519
518 err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler, 520 err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
@@ -587,6 +589,9 @@ err_iounmap:
587 pci_iounmap(pdev, test->bar[bar]); 589 pci_iounmap(pdev, test->bar[bar]);
588 } 590 }
589 591
592 for (i = 0; i < irq; i++)
593 devm_free_irq(dev, pdev->irq + i, test);
594
590err_disable_msi: 595err_disable_msi:
591 pci_disable_msi(pdev); 596 pci_disable_msi(pdev);
592 pci_release_regions(pdev); 597 pci_release_regions(pdev);
@@ -600,6 +605,7 @@ err_disable_pdev:
600static void pci_endpoint_test_remove(struct pci_dev *pdev) 605static void pci_endpoint_test_remove(struct pci_dev *pdev)
601{ 606{
602 int id; 607 int id;
608 int i;
603 enum pci_barno bar; 609 enum pci_barno bar;
604 struct pci_endpoint_test *test = pci_get_drvdata(pdev); 610 struct pci_endpoint_test *test = pci_get_drvdata(pdev);
605 struct miscdevice *misc_device = &test->miscdev; 611 struct miscdevice *misc_device = &test->miscdev;
@@ -616,6 +622,8 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
616 if (test->bar[bar]) 622 if (test->bar[bar])
617 pci_iounmap(pdev, test->bar[bar]); 623 pci_iounmap(pdev, test->bar[bar]);
618 } 624 }
625 for (i = 0; i < test->num_irqs; i++)
626 devm_free_irq(&pdev->dev, pdev->irq + i, test);
619 pci_disable_msi(pdev); 627 pci_disable_msi(pdev);
620 pci_release_regions(pdev); 628 pci_release_regions(pdev);
621 pci_disable_device(pdev); 629 pci_disable_device(pdev);