]> Git Repo - linux.git/blob - drivers/pci/irq.c
drm/v3d: Use v3d_perfmon_find()
[linux.git] / drivers / pci / irq.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCI IRQ handling code
4  *
5  * Copyright (c) 2008 James Bottomley <[email protected]>
6  * Copyright (C) 2017 Christoph Hellwig.
7  */
8
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/export.h>
13 #include <linux/interrupt.h>
14 #include <linux/pci.h>
15
16 #include "pci.h"
17
18 /**
19  * pci_request_irq - allocate an interrupt line for a PCI device
20  * @dev:        PCI device to operate on
21  * @nr:         device-relative interrupt vector index (0-based).
22  * @handler:    Function to be called when the IRQ occurs.
23  *              Primary handler for threaded interrupts.
24  *              If NULL and thread_fn != NULL the default primary handler is
25  *              installed.
26  * @thread_fn:  Function called from the IRQ handler thread
27  *              If NULL, no IRQ thread is created
28  * @dev_id:     Cookie passed back to the handler function
29  * @fmt:        Printf-like format string naming the handler
30  *
31  * This call allocates interrupt resources and enables the interrupt line and
32  * IRQ handling. From the point this call is made @handler and @thread_fn may
33  * be invoked.  All interrupts requested using this function might be shared.
34  *
35  * @dev_id must not be NULL and must be globally unique.
36  */
37 int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
38                 irq_handler_t thread_fn, void *dev_id, const char *fmt, ...)
39 {
40         va_list ap;
41         int ret;
42         char *devname;
43         unsigned long irqflags = IRQF_SHARED;
44
45         if (!handler)
46                 irqflags |= IRQF_ONESHOT;
47
48         va_start(ap, fmt);
49         devname = kvasprintf(GFP_KERNEL, fmt, ap);
50         va_end(ap);
51         if (!devname)
52                 return -ENOMEM;
53
54         ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
55                                    irqflags, devname, dev_id);
56         if (ret)
57                 kfree(devname);
58         return ret;
59 }
60 EXPORT_SYMBOL(pci_request_irq);
61
62 /**
63  * pci_free_irq - free an interrupt allocated with pci_request_irq
64  * @dev:        PCI device to operate on
65  * @nr:         device-relative interrupt vector index (0-based).
66  * @dev_id:     Device identity to free
67  *
68  * Remove an interrupt handler. The handler is removed and if the interrupt
69  * line is no longer in use by any driver it is disabled.  The caller must
70  * ensure the interrupt is disabled on the device before calling this function.
71  * The function does not return until any executing interrupts for this IRQ
72  * have completed.
73  *
74  * This function must not be called from interrupt context.
75  */
76 void pci_free_irq(struct pci_dev *dev, unsigned int nr, void *dev_id)
77 {
78         kfree(free_irq(pci_irq_vector(dev, nr), dev_id));
79 }
80 EXPORT_SYMBOL(pci_free_irq);
81
82 /**
83  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
84  * @dev: the PCI device
85  * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
86  *
87  * Perform INTx swizzling for a device behind one level of bridge.  This is
88  * required by section 9.1 of the PCI-to-PCI bridge specification for devices
89  * behind bridges on add-in cards.  For devices with ARI enabled, the slot
90  * number is always 0 (see the Implementation Note in section 2.2.8.1 of
91  * the PCI Express Base Specification, Revision 2.1)
92  */
93 u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin)
94 {
95         int slot;
96
97         if (pci_ari_enabled(dev->bus))
98                 slot = 0;
99         else
100                 slot = PCI_SLOT(dev->devfn);
101
102         return (((pin - 1) + slot) % 4) + 1;
103 }
104
105 int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
106 {
107         u8 pin;
108
109         pin = dev->pin;
110         if (!pin)
111                 return -1;
112
113         while (!pci_is_root_bus(dev->bus)) {
114                 pin = pci_swizzle_interrupt_pin(dev, pin);
115                 dev = dev->bus->self;
116         }
117         *bridge = dev;
118         return pin;
119 }
120
121 /**
122  * pci_common_swizzle - swizzle INTx all the way to root bridge
123  * @dev: the PCI device
124  * @pinp: pointer to the INTx pin value (1=INTA, 2=INTB, 3=INTD, 4=INTD)
125  *
126  * Perform INTx swizzling for a device.  This traverses through all PCI-to-PCI
127  * bridges all the way up to a PCI root bus.
128  */
129 u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
130 {
131         u8 pin = *pinp;
132
133         while (!pci_is_root_bus(dev->bus)) {
134                 pin = pci_swizzle_interrupt_pin(dev, pin);
135                 dev = dev->bus->self;
136         }
137         *pinp = pin;
138         return PCI_SLOT(dev->devfn);
139 }
140 EXPORT_SYMBOL_GPL(pci_common_swizzle);
141
142 void pci_assign_irq(struct pci_dev *dev)
143 {
144         u8 pin;
145         u8 slot = -1;
146         int irq = 0;
147         struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus);
148
149         if (!(hbrg->map_irq)) {
150                 pci_dbg(dev, "runtime IRQ mapping not provided by arch\n");
151                 return;
152         }
153
154         /*
155          * If this device is not on the primary bus, we need to figure out
156          * which interrupt pin it will come in on. We know which slot it
157          * will come in on because that slot is where the bridge is. Each
158          * time the interrupt line passes through a PCI-PCI bridge we must
159          * apply the swizzle function.
160          */
161         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
162         /* Cope with illegal. */
163         if (pin > 4)
164                 pin = 1;
165
166         if (pin) {
167                 /* Follow the chain of bridges, swizzling as we go. */
168                 if (hbrg->swizzle_irq)
169                         slot = (*(hbrg->swizzle_irq))(dev, &pin);
170
171                 /*
172                  * If a swizzling function is not used, map_irq() must
173                  * ignore slot.
174                  */
175                 irq = (*(hbrg->map_irq))(dev, slot, pin);
176                 if (irq == -1)
177                         irq = 0;
178         }
179         dev->irq = irq;
180
181         pci_dbg(dev, "assign IRQ: got %d\n", dev->irq);
182
183         /*
184          * Always tell the device, so the driver knows what is the real IRQ
185          * to use; the device does not use it.
186          */
187         pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
188 }
189
190 static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask)
191 {
192         struct pci_bus *bus = dev->bus;
193         bool mask_updated = true;
194         u32 cmd_status_dword;
195         u16 origcmd, newcmd;
196         unsigned long flags;
197         bool irq_pending;
198
199         /*
200          * We do a single dword read to retrieve both command and status.
201          * Document assumptions that make this possible.
202          */
203         BUILD_BUG_ON(PCI_COMMAND % 4);
204         BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
205
206         raw_spin_lock_irqsave(&pci_lock, flags);
207
208         bus->ops->read(bus, dev->devfn, PCI_COMMAND, 4, &cmd_status_dword);
209
210         irq_pending = (cmd_status_dword >> 16) & PCI_STATUS_INTERRUPT;
211
212         /*
213          * Check interrupt status register to see whether our device
214          * triggered the interrupt (when masking) or the next IRQ is
215          * already pending (when unmasking).
216          */
217         if (mask != irq_pending) {
218                 mask_updated = false;
219                 goto done;
220         }
221
222         origcmd = cmd_status_dword;
223         newcmd = origcmd & ~PCI_COMMAND_INTX_DISABLE;
224         if (mask)
225                 newcmd |= PCI_COMMAND_INTX_DISABLE;
226         if (newcmd != origcmd)
227                 bus->ops->write(bus, dev->devfn, PCI_COMMAND, 2, newcmd);
228
229 done:
230         raw_spin_unlock_irqrestore(&pci_lock, flags);
231
232         return mask_updated;
233 }
234
235 /**
236  * pci_check_and_mask_intx - mask INTx on pending interrupt
237  * @dev: the PCI device to operate on
238  *
239  * Check if the device dev has its INTx line asserted, mask it and return
240  * true in that case. False is returned if no interrupt was pending.
241  */
242 bool pci_check_and_mask_intx(struct pci_dev *dev)
243 {
244         return pci_check_and_set_intx_mask(dev, true);
245 }
246 EXPORT_SYMBOL_GPL(pci_check_and_mask_intx);
247
248 /**
249  * pci_check_and_unmask_intx - unmask INTx if no interrupt is pending
250  * @dev: the PCI device to operate on
251  *
252  * Check if the device dev has its INTx line asserted, unmask it if not and
253  * return true. False is returned and the mask remains active if there was
254  * still an interrupt pending.
255  */
256 bool pci_check_and_unmask_intx(struct pci_dev *dev)
257 {
258         return pci_check_and_set_intx_mask(dev, false);
259 }
260 EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx);
261
262 /**
263  * pcibios_penalize_isa_irq - penalize an ISA IRQ
264  * @irq: ISA IRQ to penalize
265  * @active: IRQ active or not
266  *
267  * Permits the platform to provide architecture-specific functionality when
268  * penalizing ISA IRQs. This is the default implementation. Architecture
269  * implementations can override this.
270  */
271 void __weak pcibios_penalize_isa_irq(int irq, int active) {}
272
273 int __weak pcibios_alloc_irq(struct pci_dev *dev)
274 {
275         return 0;
276 }
277
278 void __weak pcibios_free_irq(struct pci_dev *dev)
279 {
280 }
This page took 0.050185 seconds and 4 git commands to generate.