On Thu, Aug 5, 2021 at 2:49 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote: > > On 05-08-21, 14:03, Arnd Bergmann wrote: > > On Thu, Aug 5, 2021 at 1:26 PM Viresh Kumar via Stratos-dev > > > Based on discussion we had today (offline), I changed the design a bit > > > and used handle_level_irq() instead, as it provides consistent calls > > > to mask/unmask(), which simplified the whole thing a bit. > > > > The new flow looks much nicer to me, without the workqueue, and > > doing the requeue directly in the unmask() operation. > > > > I don't quite understand the purpose of the type_pending and > > mask_pending flags yet, can you explain what they actually > > do? > > They are required to make sure we don't send unnecessary > VIRTIO_GPIO_MSG_IRQ_TYPE events to the device, every time bus_unlock() > is called. > > mask_pending tracks if the masked state has changed since the time > last bus_unlock() was called. So on an interrupt, both mask() and > unmask() will get called by the irq-core now and mask_pending will > change to true (in mask()} and then false (in unmask()). And > eventually in bus_unlock() we won't send an extra > VIRTIO_GPIO_MSG_IRQ_TYPE message. I hope this can still be simplified by working out better which state transitions are needed exactly. In particular, I would expect that we can get away with not sending a VIRTIO_GPIO_MSG_IRQ_TYPE for 'mask' state changes at all, but use that only for forcing 'enabled' state changes. One part that I think is missing though is remembering the case when an eventq message came in after an interrupt got masked when the message was already armed. In this case, the virtio_gpio_event_vq() function would not call the irq handler, but the subsequent "unmask" callback would need to arrange having it called. Arnd