qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] TSC2005 interrupt handling fix


From: Riihimaki Juha (Nokia-D-MSW/Helsinki)
Subject: [Qemu-devel] [PATCH] TSC2005 interrupt handling fix
Date: Fri, 19 Dec 2008 13:23:12 +0200

Fixing couple of timing related issues in the TSC2005 emulation.

Problems:
1) Setting DAV bits while previous conversion results are being read results in PINTDAV interrupt line never being released. 2) Altering PINTDAV state during SPI data transfer can result in an inconsistent interrupt state.

Solution proposal:
Moved PINTDAV altering code from tsc2005_pin_update to tsc2005_timer_tick and prohibited setting of DAV bits unless PINTDAV is to be set.


Index: hw/tsc2005.c
===================================================================
--- hw/tsc2005.c        (revision 6098)
+++ hw/tsc2005.c        (working copy)
@@ -230,26 +230,7 @@
 static void tsc2005_pin_update(struct tsc2005_state_s *s)
 {
     int64_t expires;
-    int pin_state;

-    switch (s->pin_func) {
-    case 0:
-        pin_state = !s->pressure && !!s->dav;
-        break;
-    case 1:
-    case 3:
-    default:
-        pin_state = !s->dav;
-        break;
-    case 2:
-        pin_state = !s->pressure;
-    }
-
-    if (pin_state != s->irq) {
-        s->irq = pin_state;
-        qemu_set_irq(s->pint, s->irq);
-    }
-
     switch (s->nextfunction) {
     case TSC_MODE_XYZ_SCAN:
     case TSC_MODE_XY_SCAN:
@@ -401,16 +382,35 @@
 static void tsc2005_timer_tick(void *opaque)
 {
     struct tsc2005_state_s *s = opaque;
+       int pin_state;

     /* Timer ticked -- a set of conversions has been finished.  */

     if (!s->busy)
         return;

-    s->busy = 0;
-    s->dav |= mode_regs[s->function];
-    s->function = -1;
-    tsc2005_pin_update(s);
+       switch (s->pin_func) {
+               case 0:
+                       pin_state = !s->pressure && !!s->dav;
+                       break;
+               case 1:
+               case 3:
+               default:
+                       pin_state = !s->dav;
+                       break;
+               case 2:
+                       pin_state = !s->pressure;
+    }
+       
+       s->busy = 0;
+       if (pin_state && !s->irq) s->dav |= mode_regs[s->function];
+       s->function = -1;
+       tsc2005_pin_update(s);
+
+    if (pin_state != s->irq) {
+        s->irq = pin_state;
+        qemu_set_irq(s->pint, s->irq);
+    }
 }

 static void tsc2005_touchscreen_event(void *opaque,





reply via email to

[Prev in Thread] Current Thread [Next in Thread]