aboutsummaryrefslogtreecommitdiff
path: root/sim/bfin/dv-bfin_gpio.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-03-25 00:13:23 +0000
committerMike Frysinger <vapier@gentoo.org>2011-03-25 00:13:23 +0000
commitb72cc8e145a9df3d9b5fe215f89e8dfc4430f84b (patch)
treeac54a4c30860210259b654ffc307312d15d1ae53 /sim/bfin/dv-bfin_gpio.c
parenteaf863cd1ef55ef8c276e5dd7c277f22522a0436 (diff)
downloadgdb-b72cc8e145a9df3d9b5fe215f89e8dfc4430f84b.zip
gdb-b72cc8e145a9df3d9b5fe215f89e8dfc4430f84b.tar.gz
gdb-b72cc8e145a9df3d9b5fe215f89e8dfc4430f84b.tar.bz2
sim: bfin: fix GPIO logic bugs when processing events
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>
Diffstat (limited to 'sim/bfin/dv-bfin_gpio.c')
-rw-r--r--sim/bfin/dv-bfin_gpio.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sim/bfin/dv-bfin_gpio.c b/sim/bfin/dv-bfin_gpio.c
index 6b18a40..e9b79a8 100644
--- a/sim/bfin/dv-bfin_gpio.c
+++ b/sim/bfin/dv-bfin_gpio.c
@@ -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)