aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:22:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:22:57 -0400
commit683b6c6f82a60fabf47012581c2cfbf1b037ab95 (patch)
tree6a3fdf26b98aebf4b0b9eca8d242ba89e0565d8b /arch/x86
parent1ead65812486cda65093683a99b8907a7242fa93 (diff)
parent1b422ecd27866985b9f35d0d2b5ae6e9122dd4c0 (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')
-rw-r--r--arch/x86/include/asm/floppy.h4
-rw-r--r--arch/x86/include/asm/hardirq.h3
-rw-r--r--arch/x86/include/asm/mshyperv.h4
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c78
-rw-r--r--arch/x86/kernel/hpet.c2
-rw-r--r--arch/x86/kernel/irq.c6
-rw-r--r--arch/x86/kernel/time.c2
-rw-r--r--arch/x86/xen/spinlock.c2
8 files changed, 57 insertions, 44 deletions
diff --git a/arch/x86/include/asm/floppy.h b/arch/x86/include/asm/floppy.h
index d3d74698dce9..1c7eefe32502 100644
--- a/arch/x86/include/asm/floppy.h
+++ b/arch/x86/include/asm/floppy.h
@@ -145,10 +145,10 @@ static int fd_request_irq(void)
145{ 145{
146 if (can_use_virtual_dma) 146 if (can_use_virtual_dma)
147 return request_irq(FLOPPY_IRQ, floppy_hardint, 147 return request_irq(FLOPPY_IRQ, floppy_hardint,
148 IRQF_DISABLED, "floppy", NULL); 148 0, "floppy", NULL);
149 else 149 else
150 return request_irq(FLOPPY_IRQ, floppy_interrupt, 150 return request_irq(FLOPPY_IRQ, floppy_interrupt,
151 IRQF_DISABLED, "floppy", NULL); 151 0, "floppy", NULL);
152} 152}
153 153
154static unsigned long dma_mem_alloc(unsigned long size) 154static unsigned long dma_mem_alloc(unsigned long size)
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index ab0ae1aa6d0a..230853da4ec0 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -33,6 +33,9 @@ typedef struct {
33#ifdef CONFIG_X86_MCE_THRESHOLD 33#ifdef CONFIG_X86_MCE_THRESHOLD
34 unsigned int irq_threshold_count; 34 unsigned int irq_threshold_count;
35#endif 35#endif
36#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
37 unsigned int irq_hv_callback_count;
38#endif
36} ____cacheline_aligned irq_cpustat_t; 39} ____cacheline_aligned irq_cpustat_t;
37 40
38DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); 41DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index cd9c41938b8a..c163215abb9a 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -2,6 +2,7 @@
2#define _ASM_X86_MSHYPER_H 2#define _ASM_X86_MSHYPER_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/interrupt.h>
5#include <asm/hyperv.h> 6#include <asm/hyperv.h>
6 7
7struct ms_hyperv_info { 8struct ms_hyperv_info {
@@ -16,6 +17,7 @@ void hyperv_callback_vector(void);
16#define trace_hyperv_callback_vector hyperv_callback_vector 17#define trace_hyperv_callback_vector hyperv_callback_vector
17#endif 18#endif
18void hyperv_vector_handler(struct pt_regs *regs); 19void hyperv_vector_handler(struct pt_regs *regs);
19void hv_register_vmbus_handler(int irq, irq_handler_t handler); 20void hv_setup_vmbus_irq(void (*handler)(void));
21void hv_remove_vmbus_irq(void);
20 22
21#endif 23#endif
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 @@
31struct ms_hyperv_info ms_hyperv; 32struct ms_hyperv_info ms_hyperv;
32EXPORT_SYMBOL_GPL(ms_hyperv); 33EXPORT_SYMBOL_GPL(ms_hyperv);
33 34
35#if IS_ENABLED(CONFIG_HYPERV)
36static void (*vmbus_handler)(void);
37
38void 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
53void 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
65void hv_remove_vmbus_irq(void)
66{
67 /* We have no way to deallocate the interrupt gate */
68 vmbus_handler = NULL;
69}
70EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
71EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
72#endif
73
34static uint32_t __init ms_hyperv_platform(void) 74static 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};
121EXPORT_SYMBOL(x86_hyper_ms_hyperv); 161EXPORT_SYMBOL(x86_hyper_ms_hyperv);
122
123#if IS_ENABLED(CONFIG_HYPERV)
124static int vmbus_irq = -1;
125static irq_handler_t vmbus_isr;
126
127void 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
138void 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
155void hv_register_vmbus_handler(int irq, irq_handler_t handler)
156{
157}
158#endif
159EXPORT_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
63static struct irqaction irq0 = { 63static 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
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 581521c843a5..4d3acc34a998 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -183,7 +183,7 @@ __visible void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
183 183
184 local_irq_save(flags); 184 local_irq_save(flags);
185 185
186 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); 186 kstat_incr_irq_this_cpu(irq);
187out: 187out:
188 cpumask_clear_cpu(cpu, &waiting_cpus); 188 cpumask_clear_cpu(cpu, &waiting_cpus);
189 w->lock = NULL; 189 w->lock = NULL;