LCOV - code coverage report
Current view: top level - drivers/pci - irq.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 38 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 4 0.0 %
Branches: 0 14 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * PCI IRQ handling code
       4                 :            :  *
       5                 :            :  * Copyright (c) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
       6                 :            :  * Copyright (C) 2017 Christoph Hellwig.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/acpi.h>
      10                 :            : #include <linux/device.h>
      11                 :            : #include <linux/kernel.h>
      12                 :            : #include <linux/export.h>
      13                 :            : #include <linux/pci.h>
      14                 :            : 
      15                 :          0 : static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
      16                 :            : {
      17                 :          0 :         struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
      18                 :            : 
      19         [ #  # ]:          0 :         pci_err(pdev, "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
      20                 :            :                 dev_name(&parent->dev), parent->vendor, parent->device);
      21                 :          0 :         pci_err(pdev, "%s\n", reason);
      22                 :          0 :         pci_err(pdev, "Please report to linux-kernel@vger.kernel.org\n");
      23                 :          0 :         WARN_ON(1);
      24                 :          0 : }
      25                 :            : 
      26                 :            : /**
      27                 :            :  * pci_lost_interrupt - reports a lost PCI interrupt
      28                 :            :  * @pdev:       device whose interrupt is lost
      29                 :            :  *
      30                 :            :  * The primary function of this routine is to report a lost interrupt
      31                 :            :  * in a standard way which users can recognise (instead of blaming the
      32                 :            :  * driver).
      33                 :            :  *
      34                 :            :  * Returns:
      35                 :            :  * a suggestion for fixing it (although the driver is not required to
      36                 :            :  * act on this).
      37                 :            :  */
      38                 :          0 : enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *pdev)
      39                 :            : {
      40         [ #  # ]:          0 :         if (pdev->msi_enabled || pdev->msix_enabled) {
      41                 :          0 :                 enum pci_lost_interrupt_reason ret;
      42                 :            : 
      43         [ #  # ]:          0 :                 if (pdev->msix_enabled) {
      44                 :          0 :                         pci_note_irq_problem(pdev, "MSIX routing failure");
      45                 :          0 :                         ret = PCI_LOST_IRQ_DISABLE_MSIX;
      46                 :            :                 } else {
      47                 :          0 :                         pci_note_irq_problem(pdev, "MSI routing failure");
      48                 :          0 :                         ret = PCI_LOST_IRQ_DISABLE_MSI;
      49                 :            :                 }
      50                 :          0 :                 return ret;
      51                 :            :         }
      52                 :            : #ifdef CONFIG_ACPI
      53   [ #  #  #  # ]:          0 :         if (!(acpi_disabled || acpi_noirq)) {
      54                 :          0 :                 pci_note_irq_problem(pdev, "Potential ACPI misrouting please reboot with acpi=noirq");
      55                 :            :                 /* currently no way to fix acpi on the fly */
      56                 :          0 :                 return PCI_LOST_IRQ_DISABLE_ACPI;
      57                 :            :         }
      58                 :            : #endif
      59                 :          0 :         pci_note_irq_problem(pdev, "unknown cause (not MSI or ACPI)");
      60                 :          0 :         return PCI_LOST_IRQ_NO_INFORMATION;
      61                 :            : }
      62                 :            : EXPORT_SYMBOL(pci_lost_interrupt);
      63                 :            : 
      64                 :            : /**
      65                 :            :  * pci_request_irq - allocate an interrupt line for a PCI device
      66                 :            :  * @dev:        PCI device to operate on
      67                 :            :  * @nr:         device-relative interrupt vector index (0-based).
      68                 :            :  * @handler:    Function to be called when the IRQ occurs.
      69                 :            :  *              Primary handler for threaded interrupts.
      70                 :            :  *              If NULL and thread_fn != NULL the default primary handler is
      71                 :            :  *              installed.
      72                 :            :  * @thread_fn:  Function called from the IRQ handler thread
      73                 :            :  *              If NULL, no IRQ thread is created
      74                 :            :  * @dev_id:     Cookie passed back to the handler function
      75                 :            :  * @fmt:        Printf-like format string naming the handler
      76                 :            :  *
      77                 :            :  * This call allocates interrupt resources and enables the interrupt line and
      78                 :            :  * IRQ handling. From the point this call is made @handler and @thread_fn may
      79                 :            :  * be invoked.  All interrupts requested using this function might be shared.
      80                 :            :  *
      81                 :            :  * @dev_id must not be NULL and must be globally unique.
      82                 :            :  */
      83                 :          0 : int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
      84                 :            :                 irq_handler_t thread_fn, void *dev_id, const char *fmt, ...)
      85                 :            : {
      86                 :          0 :         va_list ap;
      87                 :          0 :         int ret;
      88                 :          0 :         char *devname;
      89                 :          0 :         unsigned long irqflags = IRQF_SHARED;
      90                 :            : 
      91         [ #  # ]:          0 :         if (!handler)
      92                 :          0 :                 irqflags |= IRQF_ONESHOT;
      93                 :            : 
      94                 :          0 :         va_start(ap, fmt);
      95                 :          0 :         devname = kvasprintf(GFP_KERNEL, fmt, ap);
      96                 :          0 :         va_end(ap);
      97                 :            : 
      98                 :          0 :         ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
      99                 :            :                                    irqflags, devname, dev_id);
     100         [ #  # ]:          0 :         if (ret)
     101                 :          0 :                 kfree(devname);
     102                 :          0 :         return ret;
     103                 :            : }
     104                 :            : EXPORT_SYMBOL(pci_request_irq);
     105                 :            : 
     106                 :            : /**
     107                 :            :  * pci_free_irq - free an interrupt allocated with pci_request_irq
     108                 :            :  * @dev:        PCI device to operate on
     109                 :            :  * @nr:         device-relative interrupt vector index (0-based).
     110                 :            :  * @dev_id:     Device identity to free
     111                 :            :  *
     112                 :            :  * Remove an interrupt handler. The handler is removed and if the interrupt
     113                 :            :  * line is no longer in use by any driver it is disabled.  The caller must
     114                 :            :  * ensure the interrupt is disabled on the device before calling this function.
     115                 :            :  * The function does not return until any executing interrupts for this IRQ
     116                 :            :  * have completed.
     117                 :            :  *
     118                 :            :  * This function must not be called from interrupt context.
     119                 :            :  */
     120                 :          0 : void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id)
     121                 :            : {
     122                 :          0 :         kfree(free_irq(pci_irq_vector(dev, nr), dev_id));
     123                 :          0 : }
     124                 :            : EXPORT_SYMBOL(pci_free_irq);

Generated by: LCOV version 1.14