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