summaryrefslogtreecommitdiffstats
path: root/kernel/irq/msi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:33:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:33:11 -0500
commit670310dfbae0eefe7318ff6a61e29e67a7a7bbce (patch)
treeeb3ce3aa3e6786a64fec93d410bb6f0b9a56be77 /kernel/irq/msi.c
parent43ff2f4db9d0f76452b77cfa645f02b471143b24 (diff)
parentffc661c99f621152d5fdcf53f9df0d48c326318b (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner: "A rather large update for the interrupt core code and the irq chip drivers: - Add a new bitmap matrix allocator and supporting changes, which is used to replace the x86 vector allocator which comes with separate pull request. This allows to replace the convoluted nested loop allocation function in x86 with a facility which supports the recently added property of managed interrupts proper and allows to switch to a best effort vector reservation scheme, which addresses problems with vector exhaustion. - A large update to the ARM GIC-V3-ITS driver adding support for range selectors. - New interrupt controllers: - Meson and Meson8 GPIO - BCM7271 L2 - Socionext EXIU If you expected that this will stop at some point, I have to disappoint you. There are new ones posted already. Sigh! - STM32 interrupt controller support for new platforms. - A pile of fixes, cleanups and updates to the MIPS GIC driver - The usual small fixes, cleanups and updates all over the place. Most visible one is to move the irq chip drivers Kconfig switches into a separate Kconfig menu" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) genirq: Fix type of shifting literal 1 in __setup_irq() irqdomain: Drop pointless NULL check in virq_debug_show_one genirq/proc: Return proper error code when irq_set_affinity() fails irq/work: Use llist_for_each_entry_safe irqchip: mips-gic: Print warning if inherited GIC base is used irqchip/mips-gic: Add pr_fmt and reword pr_* messages irqchip/stm32: Move the wakeup on interrupt mask irqchip/stm32: Fix initial values irqchip/stm32: Add stm32h7 support dt-bindings/interrupt-controllers: Add compatible string for stm32h7 irqchip/stm32: Add multi-bank management irqchip/stm32: Select GENERIC_IRQ_CHIP irqchip/exiu: Add support for Socionext Synquacer EXIU controller dt-bindings: Add description of Socionext EXIU interrupt controller irqchip/gic-v3-its: Fix VPE activate callback return value irqchip: mips-gic: Make IPI bitmaps static irqchip: mips-gic: Share register writes in gic_set_type() irqchip: mips-gic: Remove gic_vpes variable irqchip: mips-gic: Use num_possible_cpus() to reserve IPIs irqchip: mips-gic: Configure EIC when CPUs come online ...
Diffstat (limited to 'kernel/irq/msi.c')
-rw-r--r--kernel/irq/msi.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 3fa4bd59f569..edb987b2c58d 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -16,6 +16,8 @@
16#include <linux/msi.h> 16#include <linux/msi.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18 18
19#include "internals.h"
20
19/** 21/**
20 * alloc_msi_entry - Allocate an initialize msi_entry 22 * alloc_msi_entry - Allocate an initialize msi_entry
21 * @dev: Pointer to the device for which this is allocated 23 * @dev: Pointer to the device for which this is allocated
@@ -100,13 +102,14 @@ int msi_domain_set_affinity(struct irq_data *irq_data,
100 return ret; 102 return ret;
101} 103}
102 104
103static void msi_domain_activate(struct irq_domain *domain, 105static int msi_domain_activate(struct irq_domain *domain,
104 struct irq_data *irq_data) 106 struct irq_data *irq_data, bool early)
105{ 107{
106 struct msi_msg msg; 108 struct msi_msg msg;
107 109
108 BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg)); 110 BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg));
109 irq_chip_write_msi_msg(irq_data, &msg); 111 irq_chip_write_msi_msg(irq_data, &msg);
112 return 0;
110} 113}
111 114
112static void msi_domain_deactivate(struct irq_domain *domain, 115static void msi_domain_deactivate(struct irq_domain *domain,
@@ -373,8 +376,10 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
373 return ret; 376 return ret;
374 } 377 }
375 378
376 for (i = 0; i < desc->nvec_used; i++) 379 for (i = 0; i < desc->nvec_used; i++) {
377 irq_set_msi_desc_off(virq, i, desc); 380 irq_set_msi_desc_off(virq, i, desc);
381 irq_debugfs_copy_devname(virq + i, dev);
382 }
378 } 383 }
379 384
380 if (ops->msi_finish) 385 if (ops->msi_finish)
@@ -396,11 +401,28 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
396 struct irq_data *irq_data; 401 struct irq_data *irq_data;
397 402
398 irq_data = irq_domain_get_irq_data(domain, desc->irq); 403 irq_data = irq_domain_get_irq_data(domain, desc->irq);
399 irq_domain_activate_irq(irq_data); 404 ret = irq_domain_activate_irq(irq_data, true);
405 if (ret)
406 goto cleanup;
407 if (info->flags & MSI_FLAG_MUST_REACTIVATE)
408 irqd_clr_activated(irq_data);
400 } 409 }
401 } 410 }
402
403 return 0; 411 return 0;
412
413cleanup:
414 for_each_msi_entry(desc, dev) {
415 struct irq_data *irqd;
416
417 if (desc->irq == virq)
418 break;
419
420 irqd = irq_domain_get_irq_data(domain, desc->irq);
421 if (irqd_is_activated(irqd))
422 irq_domain_deactivate_irq(irqd);
423 }
424 msi_domain_free_irqs(domain, dev);
425 return ret;
404} 426}
405 427
406/** 428/**