sim: bfin: fix GPIO logic bugs when processing events
authorMike Frysinger <vapier@gentoo.org>
Fri, 25 Mar 2011 00:13:23 +0000 (00:13 +0000)
committerMike Frysinger <vapier@gentoo.org>
Fri, 25 Mar 2011 00:13:23 +0000 (00:13 +0000)
We need the DIR bit cleared, not set, in order for the pin to be treated
as an input.

When looking up the data value, we need to shift the "level" value over by
"my_port" rather than "bit" as the latter has already been shifted over.
We also should normalize the "level" coming in from the outside worlds to
the set of {0,1} since those are the only values that matter to GPIOs.

We need the BOTH bit set, not cleared, in order for the pin to trigger
on both edges.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
sim/bfin/ChangeLog
sim/bfin/dv-bfin_gpio.c

index d4a36ca0eb666540d3006135f908440d9fd2f0ae..953192f2d233091dc10745f05513e32ac5289864 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-24  Mike Frysinger  <vapier@gentoo.org>
+
+       * dv-bfin_gpio.c (bfin_gpio_port_event): Split dir/inen bit checking.
+       Normalize "level" to 0/1 values.  Shift "level" over by "my_port".
+       Invert port->both bit check.
+
 2011-03-24  Mike Frysinger  <vapier@gentoo.org>
 
        * dv-bfin_gpio.c (bfin_gpio_io_write_buffer): Subtract 2 from the
index 6b18a4082c25fd80a7b985e15f2e54598516ce2e..e9b79a80bb9d75d28f94597c678fa0ac64961647 100644 (file)
@@ -198,15 +198,21 @@ bfin_gpio_port_event (struct hw *me, int my_port, struct hw *source,
   bool olvl, nlvl;
   bu32 bit = (1 << my_port);
 
-  /* Only screw with state if this pin is set as an input.  */
-  if (!(port->dir & port->inen & bit))
+  /* Normalize the level value.  A simulated device can send any value
+     it likes to us, but in reality we only care about 0 and 1.  This
+     lets us assume only those two values below.  */
+  level = !!level;
+
+  /* Only screw with state if this pin is set as an input, and the
+     input is actually enabled.  */
+  if ((port->dir & bit) || !(port->inen & bit))
     return;
 
   /* Get the old pin state for calculating an interrupt.  */
   olvl = !!(port->data & bit);
 
   /* Update the new pin state.  */
-  port->data = (port->data & ~bit) | (level << bit);
+  port->data = (port->data & ~bit) | (level << my_port);
 
   /* See if this state transition will generate an interrupt.  */
   nlvl = !!(port->data & bit);
@@ -214,7 +220,7 @@ bfin_gpio_port_event (struct hw *me, int my_port, struct hw *source,
   if (port->edge & bit)
     {
       /* Pin is edge triggered.  */
-      if (!(port->both & bit))
+      if (port->both & bit)
        {
          /* Both edges.  */
          if (olvl == nlvl)
This page took 0.027531 seconds and 4 git commands to generate.