aboutsummaryrefslogtreecommitdiff
path: root/hw/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/gpio')
-rw-r--r--hw/gpio/pl061.c29
-rw-r--r--hw/gpio/trace-events1
2 files changed, 26 insertions, 4 deletions
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index 5ba398f..4002ab5 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -446,13 +446,14 @@ static void pl061_write(void *opaque, hwaddr offset,
return;
}
-static void pl061_reset(DeviceState *dev)
+static void pl061_enter_reset(Object *obj, ResetType type)
{
- PL061State *s = PL061(dev);
+ PL061State *s = PL061(obj);
+
+ trace_pl061_reset(DEVICE(s)->canonical_path);
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
s->data = 0;
- s->old_out_data = 0;
s->old_in_data = 0;
s->dir = 0;
s->isense = 0;
@@ -474,6 +475,24 @@ static void pl061_reset(DeviceState *dev)
s->amsel = 0;
}
+static void pl061_hold_reset(Object *obj)
+{
+ PL061State *s = PL061(obj);
+ int i, level;
+ uint8_t floating = pl061_floating(s);
+ uint8_t pullups = pl061_pullups(s);
+
+ for (i = 0; i < N_GPIOS; i++) {
+ if (extract32(floating, i, 1)) {
+ continue;
+ }
+ level = extract32(pullups, i, 1);
+ trace_pl061_set_output(DEVICE(s)->canonical_path, i, level);
+ qemu_set_irq(s->out[i], level);
+ }
+ s->old_out_data = pullups;
+}
+
static void pl061_set_irq(void * opaque, int irq, int level)
{
PL061State *s = (PL061State *)opaque;
@@ -543,11 +562,13 @@ static Property pl061_props[] = {
static void pl061_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_pl061;
- dc->reset = &pl061_reset;
dc->realize = pl061_realize;
device_class_set_props(dc, pl061_props);
+ rc->phases.enter = pl061_enter_reset;
+ rc->phases.hold = pl061_hold_reset;
}
static const TypeInfo pl061_info = {
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
index eb5fb47..1dab99c 100644
--- a/hw/gpio/trace-events
+++ b/hw/gpio/trace-events
@@ -20,6 +20,7 @@ pl061_input_change(const char *id, int gpio, int level) "%s input %d changed to
pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level) "%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
pl061_read(const char *id, uint64_t offset, uint64_t r) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
pl061_write(const char *id, uint64_t offset, uint64_t value) "%s offset 0x%" PRIx64 " value 0x%" PRIx64
+pl061_reset(const char *id) "%s reset"
# sifive_gpio.c
sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64