diff options
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 0e0c28574af8..c3290bc186a0 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -84,17 +84,6 @@ static int irq_bindcount[NR_IRQS]; | |||
84 | /* Xen will never allocate port zero for any purpose. */ | 84 | /* Xen will never allocate port zero for any purpose. */ |
85 | #define VALID_EVTCHN(chn) ((chn) != 0) | 85 | #define VALID_EVTCHN(chn) ((chn) != 0) |
86 | 86 | ||
87 | /* | ||
88 | * Force a proper event-channel callback from Xen after clearing the | ||
89 | * callback mask. We do this in a very simple manner, by making a call | ||
90 | * down into Xen. The pending flag will be checked by Xen on return. | ||
91 | */ | ||
92 | void force_evtchn_callback(void) | ||
93 | { | ||
94 | (void)HYPERVISOR_xen_version(0, NULL); | ||
95 | } | ||
96 | EXPORT_SYMBOL_GPL(force_evtchn_callback); | ||
97 | |||
98 | static struct irq_chip xen_dynamic_chip; | 87 | static struct irq_chip xen_dynamic_chip; |
99 | 88 | ||
100 | /* Constructor for packed IRQ information. */ | 89 | /* Constructor for packed IRQ information. */ |
@@ -175,6 +164,12 @@ static inline void set_evtchn(int port) | |||
175 | sync_set_bit(port, &s->evtchn_pending[0]); | 164 | sync_set_bit(port, &s->evtchn_pending[0]); |
176 | } | 165 | } |
177 | 166 | ||
167 | static inline int test_evtchn(int port) | ||
168 | { | ||
169 | struct shared_info *s = HYPERVISOR_shared_info; | ||
170 | return sync_test_bit(port, &s->evtchn_pending[0]); | ||
171 | } | ||
172 | |||
178 | 173 | ||
179 | /** | 174 | /** |
180 | * notify_remote_via_irq - send event to remote end of event channel via irq | 175 | * notify_remote_via_irq - send event to remote end of event channel via irq |
@@ -365,6 +360,10 @@ static void unbind_from_irq(unsigned int irq) | |||
365 | per_cpu(virq_to_irq, cpu_from_evtchn(evtchn)) | 360 | per_cpu(virq_to_irq, cpu_from_evtchn(evtchn)) |
366 | [index_from_irq(irq)] = -1; | 361 | [index_from_irq(irq)] = -1; |
367 | break; | 362 | break; |
363 | case IRQT_IPI: | ||
364 | per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn)) | ||
365 | [index_from_irq(irq)] = -1; | ||
366 | break; | ||
368 | default: | 367 | default: |
369 | break; | 368 | break; |
370 | } | 369 | } |
@@ -743,6 +742,25 @@ void xen_clear_irq_pending(int irq) | |||
743 | clear_evtchn(evtchn); | 742 | clear_evtchn(evtchn); |
744 | } | 743 | } |
745 | 744 | ||
745 | void xen_set_irq_pending(int irq) | ||
746 | { | ||
747 | int evtchn = evtchn_from_irq(irq); | ||
748 | |||
749 | if (VALID_EVTCHN(evtchn)) | ||
750 | set_evtchn(evtchn); | ||
751 | } | ||
752 | |||
753 | bool xen_test_irq_pending(int irq) | ||
754 | { | ||
755 | int evtchn = evtchn_from_irq(irq); | ||
756 | bool ret = false; | ||
757 | |||
758 | if (VALID_EVTCHN(evtchn)) | ||
759 | ret = test_evtchn(evtchn); | ||
760 | |||
761 | return ret; | ||
762 | } | ||
763 | |||
746 | /* Poll waiting for an irq to become pending. In the usual case, the | 764 | /* Poll waiting for an irq to become pending. In the usual case, the |
747 | irq will be disabled so it won't deliver an interrupt. */ | 765 | irq will be disabled so it won't deliver an interrupt. */ |
748 | void xen_poll_irq(int irq) | 766 | void xen_poll_irq(int irq) |