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/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 : */ 33 0 : int 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 0 : unsigned long irqflags = IRQF_SHARED; 40 : 41 0 : if (!handler) 42 0 : irqflags |= IRQF_ONESHOT; 43 : 44 0 : va_start(ap, fmt); 45 0 : devname = kvasprintf(GFP_KERNEL, fmt, ap); 46 0 : va_end(ap); 47 0 : if (!devname) 48 : return -ENOMEM; 49 : 50 0 : ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn, 51 : irqflags, devname, dev_id); 52 0 : if (ret) 53 0 : kfree(devname); 54 : return ret; 55 : } 56 : EXPORT_SYMBOL(pci_request_irq); 57 : 58 : /** 59 : * pci_free_irq - free an interrupt allocated with pci_request_irq 60 : * @dev: PCI device to operate on 61 : * @nr: device-relative interrupt vector index (0-based). 62 : * @dev_id: Device identity to free 63 : * 64 : * Remove an interrupt handler. The handler is removed and if the interrupt 65 : * line is no longer in use by any driver it is disabled. The caller must 66 : * ensure the interrupt is disabled on the device before calling this function. 67 : * The function does not return until any executing interrupts for this IRQ 68 : * have completed. 69 : * 70 : * This function must not be called from interrupt context. 71 : */ 72 0 : void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id) 73 : { 74 0 : kfree(free_irq(pci_irq_vector(dev, nr), dev_id)); 75 0 : } 76 : EXPORT_SYMBOL(pci_free_irq);