On Tue, 2024-09-24 at 06:48 +0000, Jamin Lin wrote: > Hi Andrew, > > > Subject: RE: [PATCH 4/5] hw/gpio/aspeed: Add AST2700 support > > > > Hi Andrew, > > > > > Subject: Re: [PATCH 4/5] hw/gpio/aspeed: Add AST2700 support > > > > > > Hi Jamin, > > > > > > > > > > + } > > > > + 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. > > I appreciate your review and finding this issue. > My changes as following. > If you agree, I will add them in v2 patch. > Thanks-Jamin > > static void aspeed_gpio_2700_write_control_reg(AspeedGPIOState *s, > uint32_t pin, uint32_t type, uint64_t data) > { > --- > /* interrupt status */ > if (SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_STATUS)) { > cleared = extract32(set->int_status, pin_idx, 1); > if (cleared) { > if (s->pending) { > assert(s->pending >= cleared); > s->pending -= cleared; > } > set->int_status = deposit32(set->int_status, pin_idx, 1, 0); > } > } > ---- > }
The logic is easier to follow. Not sure about calling the value extracted from set->int_status 'cleared' though, seems confusing on first pass. It would feel more appropriate if it were called 'pending'. I think 'cleared' is derived from `SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_STATUS)`. Anyway, that's just some quibbling over names. > > By the way, I found the same issue in "aspeed_gpio_write_index_mode" and my > changes as following. > If you agree this change, I will create a new patch in v2 patch series. > > static void aspeed_gpio_write_index_mode(void *opaque, hwaddr offset, > uint64_t data, uint32_t size) > { > --- > case gpio_reg_idx_interrupt: > if (FIELD_EX32(data, GPIO_INDEX_REG, INT_STATUS)) { > cleared = extract32(set->int_status, pin_idx, 1); > if (cleared) { > if (s->pending) { > assert(s->pending >= cleared); > s->pending -= cleared; > } > set->int_status = deposit32(set->int_status, pin_idx, 1, 0); > } > } > break; > --- > } I'll take a look in v2. Cheers, Andrew