No change in functionality.

Clarify that the only difference between level triggered and
edge triggered interrupts is on the leading edge.

Signed-off-by: Matthew Ogilvie <mmogilvi_q...@miniinfo.net>
---
 arch/x86/kvm/i8259.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 76d8dc1..63f731b 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -95,26 +95,20 @@ static inline int pic_set_irq1(struct kvm_kpic_state *s, 
int irq, int level)
 {
        int mask, ret = 1;
        mask = 1 << irq;
-       if (s->elcr & mask)     /* level triggered */
-               if (level) {
+       if (level) {
+               if ((s->last_irr & mask) == 0 ||  /* edge for edge-triggered */
+                   (s->elcr & mask)) {           /* or level triggered */
                        ret = !(s->irr & mask);
                        s->irr |= mask;
-                       s->last_irr |= mask;
-               } else {
-                       s->irr &= ~mask;
-                       s->last_irr &= ~mask;
-               }
-       else    /* edge triggered */
-               if (level) {
-                       if ((s->last_irr & mask) == 0) {
-                               ret = !(s->irr & mask);
-                               s->irr |= mask;
-                       }
-                       s->last_irr |= mask;
-               } else {
-                       s->irr &= ~mask;
-                       s->last_irr &= ~mask;
                }
+               s->last_irr |= mask;
+       } else {
+               /* Dropping level clears the interrupt regardless of edge
+                * trigger vs level trigger.
+                */
+               s->irr &= ~mask;
+               s->last_irr &= ~mask;
+       }
 
        return (s->imr & mask) ? -1 : ret;
 }
-- 
1.7.10.2.484.gcd07cc5


Reply via email to