[PATCH 2/4] hw/arm/stellaris: Convert I2C controller to Resettable interface

Philippe Mathieu-Daudé posted 4 patches 10 months ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>
There is a newer version of this series
[PATCH 2/4] hw/arm/stellaris: Convert I2C controller to Resettable interface
Posted by Philippe Mathieu-Daudé 10 months ago
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 hw/arm/stellaris.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index afbc83f1e6..284b95005f 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -607,8 +607,11 @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
     stellaris_i2c_update(s);
 }
 
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
+static void stellaris_i2c_reset_exit(Object *obj)
 {
+    stellaris_i2c_state *s = STELLARIS_I2C(obj);
+
+    /* ??? For now we only implement the master interface.  */
     if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
         i2c_end_transfer(s->bus);
 
@@ -658,8 +661,6 @@ static void stellaris_i2c_init(Object *obj)
     memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
                           "i2c", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
-    /* ??? For now we only implement the master interface.  */
-    stellaris_i2c_reset(s);
 }
 
 /* Analogue to Digital Converter.  This is only partially implemented,
@@ -1382,7 +1383,9 @@ type_init(stellaris_machine_init)
 static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
 
+    rc->phases.exit = stellaris_i2c_reset_exit;
     dc->vmsd = &vmstate_stellaris_i2c;
 }
 
-- 
2.41.0


Re: [PATCH 2/4] hw/arm/stellaris: Convert I2C controller to Resettable interface
Posted by Peter Maydell 9 months, 4 weeks ago
On Tue, 30 Jan 2024 at 19:03, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  hw/arm/stellaris.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index afbc83f1e6..284b95005f 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -607,8 +607,11 @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
>      stellaris_i2c_update(s);
>  }
>
> -static void stellaris_i2c_reset(stellaris_i2c_state *s)
> +static void stellaris_i2c_reset_exit(Object *obj)
>  {
> +    stellaris_i2c_state *s = STELLARIS_I2C(obj);
> +
> +    /* ??? For now we only implement the master interface.  */
>      if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
>          i2c_end_transfer(s->bus);
>
> @@ -658,8 +661,6 @@ static void stellaris_i2c_init(Object *obj)
>      memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
>                            "i2c", 0x1000);
>      sysbus_init_mmio(sbd, &s->iomem);
> -    /* ??? For now we only implement the master interface.  */

I'm not 100%, but I think this comment is a general one,
not reset specific, so it should stay in the init function.

> -    stellaris_i2c_reset(s);
>  }

I think that the i2c_end_transfer() should be in the
"enter" phase, and the clearing of the state fields in
"hold", and then the stellaris_i2c_update() call in "exit".
Though usually we don't bother to do an update in reset
if it's just "device has reset and now its outbound IRQ
line is not set", so we could alternatively just delete that.

>  /* Analogue to Digital Converter.  This is only partially implemented,
> @@ -1382,7 +1383,9 @@ type_init(stellaris_machine_init)
>  static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> +    ResettableClass *rc = RESETTABLE_CLASS(klass);
>
> +    rc->phases.exit = stellaris_i2c_reset_exit;
>      dc->vmsd = &vmstate_stellaris_i2c;
>  }

Also on the subject of resetting i2c controllers and buses:
https://patchew.org/QEMU/20240126005541.1839038-1-komlodi@google.com/
That patchset proposes that the bus should basically drop
any pending transactions on the floor at reset; it would
also be possible for the bus to do the "end any transfer
in progress", so the individual controller model doesn't
have to. No idea what the overall Right Thing is, so
let's not block this tidyup on figuring out general i2c reset
cleanups.

thanks
-- PMM
Re: [PATCH 2/4] hw/arm/stellaris: Convert I2C controller to Resettable interface
Posted by Philippe Mathieu-Daudé 9 months, 2 weeks ago
On 1/2/24 17:24, Peter Maydell wrote:
> On Tue, 30 Jan 2024 at 19:03, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> ---
>>   hw/arm/stellaris.c | 9 ++++++---
>>   1 file changed, 6 insertions(+), 3 deletions(-)


>> @@ -658,8 +661,6 @@ static void stellaris_i2c_init(Object *obj)
>>       memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
>>                             "i2c", 0x1000);
>>       sysbus_init_mmio(sbd, &s->iomem);
>> -    /* ??? For now we only implement the master interface.  */
> 
> I'm not 100%, but I think this comment is a general one,
> not reset specific, so it should stay in the init function.
> 
>> -    stellaris_i2c_reset(s);
>>   }
> 
> I think that the i2c_end_transfer() should be in the
> "enter" phase, and the clearing of the state fields in
> "hold", and then the stellaris_i2c_update() call in "exit".

Indeed.

> Though usually we don't bother to do an update in reset
> if it's just "device has reset and now its outbound IRQ
> line is not set", so we could alternatively just delete that.

I'll let that as an possible cleanup on top.

Thanks for the review,

Phil.