linux/drivers/pci/irq.c
<<
>>
Prefs
   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/device.h>
  10#include <linux/kernel.h>
  11#include <linux/export.h>
  12#include <linux/pci.h>
  13
  14/**
  15 * pci_request_irq - allocate an interrupt line for a PCI device
  16 * @dev:        PCI device to operate on
  17 * @nr:         device-relative interrupt vector index (0-based).
  18 * @handler:    Function to be called when the IRQ occurs.
  19 *              Primary handler for threaded interrupts.
  20 *              If NULL and thread_fn != NULL the default primary handler is
  21 *              installed.
  22 * @thread_fn:  Function called from the IRQ handler thread
  23 *              If NULL, no IRQ thread is created
  24 * @dev_id:     Cookie passed back to the handler function
  25 * @fmt:        Printf-like format string naming the handler
  26 *
  27 * This call allocates interrupt resources and enables the interrupt line and
  28 * IRQ handling. From the point this call is made @handler and @thread_fn may
  29 * be invoked.  All interrupts requested using this function might be shared.
  30 *
  31 * @dev_id must not be NULL and must be globally unique.
  32 */
  33int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
  34                irq_handler_t thread_fn, void *dev_id, const char *fmt, ...)
  35{
  36        va_list ap;
  37        int ret;
  38        char *devname;
  39        unsigned long irqflags = IRQF_SHARED;
  40
  41        if (!handler)
  42                irqflags |= IRQF_ONESHOT;
  43
  44        va_start(ap, fmt);
  45        devname = kvasprintf(GFP_KERNEL, fmt, ap);
  46        va_end(ap);
  47
  48        ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
  49                                   irqflags, devname, dev_id);
  50        if (ret)
  51                kfree(devname);
  52        return ret;
  53}
  54EXPORT_SYMBOL(pci_request_irq);
  55
  56/**
  57 * pci_free_irq - free an interrupt allocated with pci_request_irq
  58 * @dev:        PCI device to operate on
  59 * @nr:         device-relative interrupt vector index (0-based).
  60 * @dev_id:     Device identity to free
  61 *
  62 * Remove an interrupt handler. The handler is removed and if the interrupt
  63 * line is no longer in use by any driver it is disabled.  The caller must
  64 * ensure the interrupt is disabled on the device before calling this function.
  65 * The function does not return until any executing interrupts for this IRQ
  66 * have completed.
  67 *
  68 * This function must not be called from interrupt context.
  69 */
  70void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id)
  71{
  72        kfree(free_irq(pci_irq_vector(dev, nr), dev_id));
  73}
  74EXPORT_SYMBOL(pci_free_irq);
  75