Commit | Line | Data |
---|---|---|
e360adbe PZ |
1 | /* |
2 | * x86 specific code for irq_work | |
3 | * | |
4 | * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> | |
5 | */ | |
6 | ||
7 | #include <linux/kernel.h> | |
8 | #include <linux/irq_work.h> | |
9 | #include <linux/hardirq.h> | |
10 | #include <asm/apic.h> | |
cf910e83 | 11 | #include <asm/trace/irq_vectors.h> |
e360adbe | 12 | |
eddc0e92 | 13 | static inline void irq_work_entering_irq(void) |
e360adbe PZ |
14 | { |
15 | irq_enter(); | |
16 | ack_APIC_irq(); | |
eddc0e92 SA |
17 | } |
18 | ||
19 | static inline void __smp_irq_work_interrupt(void) | |
20 | { | |
e360adbe PZ |
21 | inc_irq_stat(apic_irq_work_irqs); |
22 | irq_work_run(); | |
eddc0e92 SA |
23 | } |
24 | ||
1d9090e2 | 25 | __visible void smp_irq_work_interrupt(struct pt_regs *regs) |
eddc0e92 SA |
26 | { |
27 | irq_work_entering_irq(); | |
28 | __smp_irq_work_interrupt(); | |
29 | exiting_irq(); | |
e360adbe PZ |
30 | } |
31 | ||
1d9090e2 | 32 | __visible void smp_trace_irq_work_interrupt(struct pt_regs *regs) |
cf910e83 SA |
33 | { |
34 | irq_work_entering_irq(); | |
35 | trace_irq_work_entry(IRQ_WORK_VECTOR); | |
36 | __smp_irq_work_interrupt(); | |
37 | trace_irq_work_exit(IRQ_WORK_VECTOR); | |
38 | exiting_irq(); | |
39 | } | |
40 | ||
e360adbe PZ |
41 | void arch_irq_work_raise(void) |
42 | { | |
43 | #ifdef CONFIG_X86_LOCAL_APIC | |
3010279f | 44 | if (!arch_irq_work_has_interrupt()) |
e360adbe PZ |
45 | return; |
46 | ||
47 | apic->send_IPI_self(IRQ_WORK_VECTOR); | |
48 | apic_wait_icr_idle(); | |
49 | #endif | |
50 | } |