diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 14:22:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 14:22:57 -0400 |
commit | 683b6c6f82a60fabf47012581c2cfbf1b037ab95 (patch) | |
tree | 6a3fdf26b98aebf4b0b9eca8d242ba89e0565d8b /arch/x86/kernel | |
parent | 1ead65812486cda65093683a99b8907a7242fa93 (diff) | |
parent | 1b422ecd27866985b9f35d0d2b5ae6e9122dd4c0 (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq code updates from Thomas Gleixner:
"The irq department proudly presents:
- Another tree wide sweep of irq infrastructure abuse. Clear winner
of the trainwreck engineering contest was:
#include "../../../kernel/irq/settings.h"
- Tree wide update of irq_set_affinity() callbacks which miss a cpu
online check when picking a single cpu out of the affinity mask.
- Tree wide consolidation of interrupt statistics.
- Updates to the threaded interrupt infrastructure to allow explicit
wakeup of the interrupt thread and a variant of synchronize_irq()
which synchronizes only the hard interrupt handler. Both are
needed to replace the homebrewn thread handling in the mmc/sdhci
code.
- New irq chip callbacks to allow proper support for GPIO based irqs.
The GPIO based interrupts need to request/release GPIO resources
from request/free_irq.
- A few new ARM interrupt chips. No revolutionary new hardware, just
differently wreckaged variations of the scheme.
- Small improvments, cleanups and updates all over the place"
I was hoping that that trainwreck engineering contest was a April Fools'
joke. But no.
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (68 commits)
irqchip: sun7i/sun6i: Disable NMI before registering the handler
ARM: sun7i/sun6i: dts: Fix IRQ number for sun6i NMI controller
ARM: sun7i/sun6i: irqchip: Update the documentation
ARM: sun7i/sun6i: dts: Add NMI irqchip support
ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller
genirq: Export symbol no_action()
arm: omap: Fix typo in ams-delta-fiq.c
m68k: atari: Fix the last kernel_stat.h fallout
irqchip: sun4i: Simplify sun4i_irq_ack
irqchip: sun4i: Use handle_fasteoi_irq for all interrupts
genirq: procfs: Make smp_affinity values go+r
softirq: Add linux/irq.h to make it compile again
m68k: amiga: Add linux/irq.h to make it compile again
irqchip: sun4i: Don't ack IRQs > 0, fix acking of IRQ 0
irqchip: sun4i: Fix a comment about mask register initialization
irqchip: sun4i: Fix irq 0 not working
genirq: Add a new IRQCHIP_EOI_THREADED flag
genirq: Document IRQCHIP_ONESHOT_SAFE flag
ARM: sunxi: dt: Convert to the new irq controller compatibles
irqchip: sunxi: Change compatibles
...
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 78 | ||||
-rw-r--r-- | arch/x86/kernel/hpet.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/irq.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/time.c | 2 |
4 files changed, 48 insertions, 40 deletions
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 832d05a914ba..76f98fe5b35c 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/hardirq.h> | 17 | #include <linux/hardirq.h> |
18 | #include <linux/efi.h> | 18 | #include <linux/efi.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/irq.h> | ||
20 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
21 | #include <asm/hypervisor.h> | 22 | #include <asm/hypervisor.h> |
22 | #include <asm/hyperv.h> | 23 | #include <asm/hyperv.h> |
@@ -31,6 +32,45 @@ | |||
31 | struct ms_hyperv_info ms_hyperv; | 32 | struct ms_hyperv_info ms_hyperv; |
32 | EXPORT_SYMBOL_GPL(ms_hyperv); | 33 | EXPORT_SYMBOL_GPL(ms_hyperv); |
33 | 34 | ||
35 | #if IS_ENABLED(CONFIG_HYPERV) | ||
36 | static void (*vmbus_handler)(void); | ||
37 | |||
38 | void hyperv_vector_handler(struct pt_regs *regs) | ||
39 | { | ||
40 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
41 | |||
42 | irq_enter(); | ||
43 | exit_idle(); | ||
44 | |||
45 | inc_irq_stat(irq_hv_callback_count); | ||
46 | if (vmbus_handler) | ||
47 | vmbus_handler(); | ||
48 | |||
49 | irq_exit(); | ||
50 | set_irq_regs(old_regs); | ||
51 | } | ||
52 | |||
53 | void hv_setup_vmbus_irq(void (*handler)(void)) | ||
54 | { | ||
55 | vmbus_handler = handler; | ||
56 | /* | ||
57 | * Setup the IDT for hypervisor callback. Prevent reallocation | ||
58 | * at module reload. | ||
59 | */ | ||
60 | if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) | ||
61 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, | ||
62 | hyperv_callback_vector); | ||
63 | } | ||
64 | |||
65 | void hv_remove_vmbus_irq(void) | ||
66 | { | ||
67 | /* We have no way to deallocate the interrupt gate */ | ||
68 | vmbus_handler = NULL; | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq); | ||
71 | EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq); | ||
72 | #endif | ||
73 | |||
34 | static uint32_t __init ms_hyperv_platform(void) | 74 | static uint32_t __init ms_hyperv_platform(void) |
35 | { | 75 | { |
36 | u32 eax; | 76 | u32 eax; |
@@ -119,41 +159,3 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { | |||
119 | .init_platform = ms_hyperv_init_platform, | 159 | .init_platform = ms_hyperv_init_platform, |
120 | }; | 160 | }; |
121 | EXPORT_SYMBOL(x86_hyper_ms_hyperv); | 161 | EXPORT_SYMBOL(x86_hyper_ms_hyperv); |
122 | |||
123 | #if IS_ENABLED(CONFIG_HYPERV) | ||
124 | static int vmbus_irq = -1; | ||
125 | static irq_handler_t vmbus_isr; | ||
126 | |||
127 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) | ||
128 | { | ||
129 | /* | ||
130 | * Setup the IDT for hypervisor callback. | ||
131 | */ | ||
132 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); | ||
133 | |||
134 | vmbus_irq = irq; | ||
135 | vmbus_isr = handler; | ||
136 | } | ||
137 | |||
138 | void hyperv_vector_handler(struct pt_regs *regs) | ||
139 | { | ||
140 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
141 | struct irq_desc *desc; | ||
142 | |||
143 | irq_enter(); | ||
144 | exit_idle(); | ||
145 | |||
146 | desc = irq_to_desc(vmbus_irq); | ||
147 | |||
148 | if (desc) | ||
149 | generic_handle_irq_desc(vmbus_irq, desc); | ||
150 | |||
151 | irq_exit(); | ||
152 | set_irq_regs(old_regs); | ||
153 | } | ||
154 | #else | ||
155 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) | ||
156 | { | ||
157 | } | ||
158 | #endif | ||
159 | EXPORT_SYMBOL_GPL(hv_register_vmbus_handler); | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index b91abfdd4931..014618dbaa7b 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -521,7 +521,7 @@ static int hpet_setup_irq(struct hpet_dev *dev) | |||
521 | { | 521 | { |
522 | 522 | ||
523 | if (request_irq(dev->irq, hpet_interrupt_handler, | 523 | if (request_irq(dev->irq, hpet_interrupt_handler, |
524 | IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING, | 524 | IRQF_TIMER | IRQF_NOBALANCING, |
525 | dev->name, dev)) | 525 | dev->name, dev)) |
526 | return -1; | 526 | return -1; |
527 | 527 | ||
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index d99f31d9a750..42805fac0092 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -125,6 +125,12 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
125 | seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); | 125 | seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); |
126 | seq_printf(p, " Machine check polls\n"); | 126 | seq_printf(p, " Machine check polls\n"); |
127 | #endif | 127 | #endif |
128 | #if defined(CONFIG_HYPERV) || defined(CONFIG_XEN) | ||
129 | seq_printf(p, "%*s: ", prec, "THR"); | ||
130 | for_each_online_cpu(j) | ||
131 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); | ||
132 | seq_printf(p, " Hypervisor callback interrupts\n"); | ||
133 | #endif | ||
128 | seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); | 134 | seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); |
129 | #if defined(CONFIG_X86_IO_APIC) | 135 | #if defined(CONFIG_X86_IO_APIC) |
130 | seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); | 136 | seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); |
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index 6ec91c00d84d..bf7ef5ce29df 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c | |||
@@ -62,7 +62,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
62 | 62 | ||
63 | static struct irqaction irq0 = { | 63 | static struct irqaction irq0 = { |
64 | .handler = timer_interrupt, | 64 | .handler = timer_interrupt, |
65 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, | 65 | .flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, |
66 | .name = "timer" | 66 | .name = "timer" |
67 | }; | 67 | }; |
68 | 68 | ||