@@ -262,24 +262,29 @@ err_out:
__func__, offset);
}
-static void bcm2835_gpio_reset(DeviceState *dev)
+static void bcm2835_gpio_reset_enter(Object *obj, ResetType type)
{
- BCM2835GpioState *s = BCM2835_GPIO(dev);
+ BCM2835GpioState *s = BCM2835_GPIO(obj);
int i;
for (i = 0; i < 6; i++) {
gpfsel_set(s, i, 0);
}
+ s->lev0 = 0;
+ s->lev1 = 0;
+}
+
+static void bcm2835_gpio_reset_hold(Object *obj)
+{
+ BCM2835GpioState *s = BCM2835_GPIO(obj);
/*
* Setup the right sdbus (put 1 in sd_fsel to force reparenting
- * the sd). It will be SDHCI because of the gpfsel_set() above.
+ * the sd). It will be SDHCI because of the gpfsel_set() done
+ * in bcm2835_gpio_reset_enter().
*/
s->sd_fsel = 1;
gpfsel_update_sdbus(s);
-
- s->lev0 = 0;
- s->lev1 = 0;
}
static const MemoryRegionOps bcm2835_gpio_ops = {
@@ -342,10 +347,12 @@ static void bcm2835_gpio_realize(DeviceState *dev, Error **errp)
static void bcm2835_gpio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_bcm2835_gpio;
dc->realize = &bcm2835_gpio_realize;
- dc->reset = &bcm2835_gpio_reset;
+ rc->phases.enter = &bcm2835_gpio_reset_enter;
+ rc->phases.hold = &bcm2835_gpio_reset_hold;
}
static const TypeInfo bcm2835_gpio_info = {
Transition the bcm2835_gpio device class to Resettable. The sdbus reparenting is delayed in hold phase to respect resettable side-effect rules. Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> --- Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Andrew Baumann <Andrew.Baumann@microsoft.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Cc: qemu-arm@nongnu.org --- hw/gpio/bcm2835_gpio.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)