Hi Andrew,
> Subject: Re: [PATCH 4/5] hw/gpio/aspeed: Add AST2700 support
>
> On Tue, 2024-09-24 at 03:03 +0000, Jamin Lin wrote:
> > Hi Andrew,
> >
> > > Subject: Re: [PATCH 4/5] hw/gpio/aspeed: Add AST2700 support
> > >
> > > Hi Jamin,
> > >
> > > On Mon, 2024-09-23 at 17:42 +0800, Jamin Lin wrote:
> > >
> > > > +
> > > > + /* interrupt status */
> > > > + group_value = set->int_status;
> > > > + group_value = deposit32(group_value, pin_idx, 1,
> > > > + SHARED_FIELD_EX32(data,
> > > > + GPIO_CONTROL_INT_STATUS));
> > >
> > > This makes me a bit wary.
> > >
> > > The interrupt status field is W1C, where a set bit on read indicates
> > > an interrupt is pending. If the bit extracted from data is set it
> > > should clear the corresponding bit in group_value. However, if the
> > > extracted bit is clear then the value of the corresponding bit in
> > > group_value
> should be unchanged.
> > >
> > > SHARED_FIELD_EX32() extracts the interrupt status bit from the write
> (data).
> > > group_value is set to the set's interrupt status, which means that
> > > for any pin with an interrupt pending, the corresponding bit is set.
> > > The deposit32() call updates the bit at pin_idx in the group, using
> > > the value extracted from the write (data).
> > >
> > > However, the result is that if the interrupt was pending and the
> > > write was acknowledging it, then the update has no effect.
> > > Alternatively, if the interrupt was pending but the write was
> > > acknowledging it, then the update will mark the interrupt as
> > > pending. Or, if the interrupt was pending but the write was _not_
> > > acknowledging it, then the interrupt will _no longer_ be marked pending.
> > > If
> this is intentional it feels a bit hard to follow.
> > >
> > > > + cleared = ctpop32(group_value & set->int_status);
> > >
> > > Can this rather be expressed as
> > >
> > > ```
> > > cleared = SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_STATUS); ```
> > >
> > > > + if (s->pending && cleared) {
> > > > + assert(s->pending >= cleared);
> > > > + s->pending -= cleared;
> > >
> > > We're only ever going to be subtracting 1, as each GPIO has its own
> register.
> > > This feels overly abstract.
> > >
> > > > + }
> > > > + set->int_status &= ~group_value;
> > >
> > > This feels like it misbehaves in the face of multiple pending interrupts.
> > >
> > > For example, say we have an interrupt pending for GPIOA0, where the
> > > following statements are true:
> > >
> > > set->int_status == 0b01
> > > s->pending == 1
> > >
> > > Before it is acknowledged, an interrupt becomes pending for GPIOA1:
> > >
> > > set->int_status == 0b11
> > > s->pending == 2
> > >
> > > A write is issued to acknowledge the interrupt for GPIOA0. This
> > > causes the following sequence:
> > >
> > > group_value == 0b11
> > > cleared == 2
> > > s->pending = 0
> > > set->int_status == 0b00
> > >
> > > It seems the pending interrupt for GPIOA1 is lost?
> > >
> > Thanks for review and input.
> > I should check "int_status" bit of write data in write callback function.
> > If 1
> clear status flag(group value), else should not change group value.
> > I am checking and testing this issue and will update to you or directly
> > resend
> the new patch series.
>
> Happy to take a look in a v2 of the series :)
>
> > > > +
> > > > /****************** Setup functions ******************/
> > >
> > > Bit of a nitpick, but I'm not personally a fan of banner comments like
> > > this.
> > >
> > Did you mean change as following?
> >
> > A.
> >
> > /************ Setup functions *****************/
> >
> > 1. /* Setup functions */
> > 2. /*
> > * Setup functions
> > */
>
> Either is fine, but I prefer 1.
>
Thanks for suggestion.
Will update it in V2
Thanks-Jamin
> Cheers,
>
> Andrew