Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Viresh Kumar
On 21-10-21, 13:02, Geert Uytterhoeven wrote:
> Exactly.  And on CRIS (no longer supported by Linux), there won't
> be any padding.
> 
> So I recommend to always add explicit padding, to make sure all
> members are aligned naturally on all systems.

Right.

-- 
viresh
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Geert Uytterhoeven
Hi Viresh,

On Thu, Oct 21, 2021 at 12:49 PM Viresh Kumar  wrote:
> On 21-10-21, 12:07, Geert Uytterhoeven wrote:
> > On Thu, Oct 21, 2021 at 11:52 AM Viresh Kumar  
> > wrote:
> > > The structure will get aligned to the size of largest element and each
> > > element will be aligned to itself. I don't see how this will break
> > > even in case of 32/64 bit communication.
> >
> > Structures are not aligned to the size of the largest element, but
> > to the largest alignment needed for each member.
>
> Right, I was talking in terms of the structures we have here for GPIO.
> The biggest member here (for any structure) is 32bits long, and
> compiler shouldn't add extra padding here.
>
> > This can be smaller than the size of the largest element.
> > E.g. alignof(long long) might be 4, not 8.
>
> Right.
>
> > And m68k aligns to two bytes at most.
>
> Interesting, I assumed that it will be 4bytes for 32 bit systems. So
> in case of m68k, we will see something like this ?
>
> struct foo {
> u8 a;   // aligned to 2 bytes
>
> // padding of 1 byte
>
> u32 b;  // aligned to 2 bytes
> }

Exactly.  And on CRIS (no longer supported by Linux), there won't
be any padding.

So I recommend to always add explicit padding, to make sure all
members are aligned naturally on all systems.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Viresh Kumar
On 21-10-21, 12:07, Geert Uytterhoeven wrote:
> On Thu, Oct 21, 2021 at 11:52 AM Viresh Kumar  wrote:
> > The structure will get aligned to the size of largest element and each
> > element will be aligned to itself. I don't see how this will break
> > even in case of 32/64 bit communication.
> 
> Structures are not aligned to the size of the largest element, but
> to the largest alignment needed for each member.

Right, I was talking in terms of the structures we have here for GPIO.
The biggest member here (for any structure) is 32bits long, and
compiler shouldn't add extra padding here.

> This can be smaller than the size of the largest element.
> E.g. alignof(long long) might be 4, not 8. 

Right.

> And m68k aligns to two bytes at most.

Interesting, I assumed that it will be 4bytes for 32 bit systems. So
in case of m68k, we will see something like this ?

struct foo {
u8 a;   // aligned to 2 bytes

// padding of 1 byte

u32 b;  // aligned to 2 bytes
}

-- 
viresh
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Geert Uytterhoeven
Hi Viresh,

On Thu, Oct 21, 2021 at 11:52 AM Viresh Kumar  wrote:
> The structure will get aligned to the size of largest element and each
> element will be aligned to itself. I don't see how this will break
> even in case of 32/64 bit communication.

Structures are not aligned to the size of the largest element, but
to the largest alignment needed for each member.
This can be smaller than the size of the largest element.
E.g. alignof(long long) might be 4, not 8.  And m68k aligns to
two bytes at most.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Viresh Kumar
On 21-10-21, 12:58, Andy Shevchenko wrote:
> I admit I haven't looked into the specification, but in the past we
> had had quite an issue exactly in GPIO on kernel side because of this
> kind of design mistake.

> The problem here if in the future one wants to
> supply more than one item at a time, it will be not possible with this
> interface.

Why ?

> Yes, I understand that in current design it's rather missed
> scalability, but hey, I believe in the future we may need
> performance-wise calls.

-- 
viresh
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Andy Shevchenko
On Thu, Oct 21, 2021 at 12:52 PM Viresh Kumar  wrote:
> On 21-10-21, 12:42, Andy Shevchenko wrote:
> > On Thu, Oct 21, 2021 at 7:34 AM Viresh Kumar  
> > wrote:
> > > On 20-10-21, 18:10, Andy Shevchenko wrote:

...

> > > > >  struct virtio_gpio_config {
> > > > > __le16 ngpio;
> > > > > __u8 padding[2];
> > > > > @@ -44,4 +56,17 @@ struct virtio_gpio_response_get_names {
> > > > > __u8 value[];
> > > > >  };
> > > > >
> > > > > +/* Virtio GPIO IRQ Request / Response */
> > > > > +struct virtio_gpio_irq_request {
> > > > > +   __le16 gpio;
> > > > > +};
> > > > > +
> > > > > +struct virtio_gpio_irq_response {
> > > > > +   __u8 status;
> > > > > +};
> > > > >
> > > > I’m wondering if those above should be packed.
> > >
> > > You are talking about the newly added ones or the ones before ?
> > >
> > > In any case, they are all already packed (i.e. they have explicit
> > > padding wherever required) and properly aligned. Compiler won't add
> > > any other padding to them.
> >
> > Is it only for 64-bit to 64-bit communications?
>
> That's what I have been looking at.
>
> > If there is a possibility to have 32-bit to 64-bit or vice versa
> > communication you have a problem.
>
> This should work as well.
>
> The structure will get aligned to the size of largest element and each
> element will be aligned to itself. I don't see how this will break
> even in case of 32/64 bit communication.

I admit I haven't looked into the specification, but in the past we
had had quite an issue exactly in GPIO on kernel side because of this
kind of design mistake. The problem here if in the future one wants to
supply more than one item at a time, it will be not possible with this
interface. Yes, I understand that in current design it's rather missed
scalability, but hey, I believe in the future we may need
performance-wise calls.

-- 
With Best Regards,
Andy Shevchenko
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Viresh Kumar
On 21-10-21, 12:42, Andy Shevchenko wrote:
> On Thu, Oct 21, 2021 at 7:34 AM Viresh Kumar  wrote:
> > On 20-10-21, 18:10, Andy Shevchenko wrote:
> > > IIRC you add dead code. IRQ framework never calls this if type is not set.
> >
> > Yes, but it is allowed to call
> >
> > irq_set_irq_type(irq, IRQ_TYPE_NONE);
> >
> > and the irq framework won't disallow it AFAICT.
> 
> That's true, but how you may end up in this callback with a such?
> What the meaning of that call to the user?
 
I can see few calls like this in the kernel (mostly from irq-providers
only), but yeah sure I can drop it. We will error out if it ever gets
called and so can get it back later if required.
 
> > > >  struct virtio_gpio_config {
> > > > __le16 ngpio;
> > > > __u8 padding[2];
> > > > @@ -44,4 +56,17 @@ struct virtio_gpio_response_get_names {
> > > > __u8 value[];
> > > >  };
> > > >
> > > > +/* Virtio GPIO IRQ Request / Response */
> > > > +struct virtio_gpio_irq_request {
> > > > +   __le16 gpio;
> > > > +};
> > > > +
> > > > +struct virtio_gpio_irq_response {
> > > > +   __u8 status;
> > > > +};
> > > >
> > > I’m wondering if those above should be packed.
> >
> > You are talking about the newly added ones or the ones before ?
> >
> > In any case, they are all already packed (i.e. they have explicit
> > padding wherever required) and properly aligned. Compiler won't add
> > any other padding to them.
> 
> Is it only for 64-bit to 64-bit communications?

That's what I have been looking at.

> If there is a possibility to have 32-bit to 64-bit or vice versa
> communication you have a problem.

This should work as well.

The structure will get aligned to the size of largest element and each
element will be aligned to itself. I don't see how this will break
even in case of 32/64 bit communication.

-- 
viresh
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-21 Thread Andy Shevchenko
On Thu, Oct 21, 2021 at 7:34 AM Viresh Kumar  wrote:
> On 20-10-21, 18:10, Andy Shevchenko wrote:
> > On Wednesday, October 20, 2021, Viresh Kumar 
> > wrote:

...

> > > +   case IRQ_TYPE_NONE:
> > > +   type = VIRTIO_GPIO_IRQ_TYPE_NONE;
> > > +   break;
> >
> > IIRC you add dead code. IRQ framework never calls this if type is not set.
>
> Yes, but it is allowed to call
>
> irq_set_irq_type(irq, IRQ_TYPE_NONE);
>
> and the irq framework won't disallow it AFAICT.

That's true, but how you may end up in this callback with a such?
What the meaning of that call to the user?

...

> > >  struct virtio_gpio_config {
> > > __le16 ngpio;
> > > __u8 padding[2];
> > > @@ -44,4 +56,17 @@ struct virtio_gpio_response_get_names {
> > > __u8 value[];
> > >  };
> > >
> > > +/* Virtio GPIO IRQ Request / Response */
> > > +struct virtio_gpio_irq_request {
> > > +   __le16 gpio;
> > > +};
> > > +
> > > +struct virtio_gpio_irq_response {
> > > +   __u8 status;
> > > +};
> > >
> > I’m wondering if those above should be packed.
>
> You are talking about the newly added ones or the ones before ?
>
> In any case, they are all already packed (i.e. they have explicit
> padding wherever required) and properly aligned. Compiler won't add
> any other padding to them.

Is it only for 64-bit to 64-bit communications?
If there is a possibility to have 32-bit to 64-bit or vice versa
communication you have a problem.

-- 
With Best Regards,
Andy Shevchenko
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-20 Thread Viresh Kumar
On 20-10-21, 18:10, Andy Shevchenko wrote:
> On Wednesday, October 20, 2021, Viresh Kumar 
> wrote:
> > +static int virtio_gpio_irq_set_type(struct irq_data *d, unsigned int
> > type)
> > +{
> > +   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> > +   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
> > +   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
> > +
> > +   switch (type) {
> > +   case IRQ_TYPE_NONE:
> > +   type = VIRTIO_GPIO_IRQ_TYPE_NONE;
> > +   break;
> 
> 
> IIRC you add dead code. IRQ framework never calls this if type is not set.

Yes, but it is allowed to call

irq_set_irq_type(irq, IRQ_TYPE_NONE);

and the irq framework won't disallow it AFAICT.

> > +static void virtio_gpio_event_vq(struct virtqueue *vq)
> > +{

> > +   irq = irq_find_mapping(vgpio->gc.irq.domain, gpio);
> > +   WARN_ON(!irq);
> > +
> > +   ret = generic_handle_irq(irq);
> 
> 
> IIRC there is a new API that basically combines the two above.

generic_handle_domain_irq(), thanks.

> >  struct virtio_gpio_config {
> > __le16 ngpio;
> > __u8 padding[2];
> > @@ -44,4 +56,17 @@ struct virtio_gpio_response_get_names {
> > __u8 value[];
> >  };
> >
> > +/* Virtio GPIO IRQ Request / Response */
> > +struct virtio_gpio_irq_request {
> > +   __le16 gpio;
> > +};
> > +
> > +struct virtio_gpio_irq_response {
> > +   __u8 status;
> > +};
> >
> >
> I’m wondering if those above should be packed.

You are talking about the newly added ones or the ones before ?

In any case, they are all already packed (i.e. they have explicit
padding wherever required) and properly aligned. Compiler won't add
any other padding to them.
 
-- 
viresh
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH V6] gpio: virtio: Add IRQ support

2021-10-20 Thread Andy Shevchenko
On Wednesday, October 20, 2021, Viresh Kumar 
wrote:

> This patch adds IRQ support for the virtio GPIO driver. Note that this
> uses the irq_bus_lock/unlock() callbacks, since those operations over
> virtio may sleep.
>
> Reviewed-by: Linus Walleij 
> Signed-off-by: Viresh Kumar 
> ---
> Bartosz,
>
> The spec changes are close to merging now, I will let you know once the
> ballot
> is closed and the spec changes are merged. You can then pick this patch for
> 5.16.
>
> V5->V6:
> - Sent it separately as the other patches are already merged.
> - Queue the buffers only after enabling the irq (as per latest spec).
> - Migrate to raw_spinlock_t.
>
>  drivers/gpio/Kconfig |   1 +
>  drivers/gpio/gpio-virtio.c   | 310 ++-
>  include/uapi/linux/virtio_gpio.h |  25 +++
>  3 files changed, 332 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index fae5141251e5..bfa723ff8e7c 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1674,6 +1674,7 @@ config GPIO_MOCKUP
>  config GPIO_VIRTIO
> tristate "VirtIO GPIO support"
> depends on VIRTIO
> +   select GPIOLIB_IRQCHIP
> help
>   Say Y here to enable guest support for virtio-based GPIO
> controllers.
>
> diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c
> index d24f1c9264bc..73fbe2eda4b9 100644
> --- a/drivers/gpio/gpio-virtio.c
> +++ b/drivers/gpio/gpio-virtio.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -28,12 +29,30 @@ struct virtio_gpio_line {
> unsigned int rxlen;
>  };
>
> +struct vgpio_irq_line {
> +   u8 type;
> +   bool disabled;
> +   bool masked;
> +   bool queued;
> +   bool update_pending;
> +   bool queue_pending;
> +
> +   struct virtio_gpio_irq_request ireq cacheline_aligned;
> +   struct virtio_gpio_irq_response ires cacheline_aligned;
> +};
> +
>  struct virtio_gpio {
> struct virtio_device *vdev;
> struct mutex lock; /* Protects virtqueue operation */
> struct gpio_chip gc;
> struct virtio_gpio_line *lines;
> struct virtqueue *request_vq;
> +
> +   /* irq support */
> +   struct virtqueue *event_vq;
> +   struct mutex irq_lock; /* Protects irq operation */
> +   raw_spinlock_t eventq_lock; /* Protects queuing of the buffer */
> +   struct vgpio_irq_line *irq_lines;
>  };
>
>  static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio,
> @@ -186,6 +205,244 @@ static void virtio_gpio_set(struct gpio_chip *gc,
> unsigned int gpio, int value)
> virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_VALUE, gpio, value,
> NULL);
>  }
>
> +/* Interrupt handling */
> +static void virtio_gpio_irq_prepare(struct virtio_gpio *vgpio, u16 gpio)
> +{
> +   struct vgpio_irq_line *irq_line = >irq_lines[gpio];
> +   struct virtio_gpio_irq_request *ireq = _line->ireq;
> +   struct virtio_gpio_irq_response *ires = _line->ires;
> +   struct scatterlist *sgs[2], req_sg, res_sg;
> +   int ret;
> +
> +   if (WARN_ON(irq_line->queued || irq_line->masked ||
> irq_line->disabled))
> +   return;
> +
> +   ireq->gpio = cpu_to_le16(gpio);
> +   sg_init_one(_sg, ireq, sizeof(*ireq));
> +   sg_init_one(_sg, ires, sizeof(*ires));
> +   sgs[0] = _sg;
> +   sgs[1] = _sg;
> +
> +   ret = virtqueue_add_sgs(vgpio->event_vq, sgs, 1, 1, irq_line,
> GFP_ATOMIC);
> +   if (ret) {
> +   dev_err(>vdev->dev, "failed to add request to
> eventq\n");
> +   return;
> +   }
> +
> +   irq_line->queued = true;
> +   virtqueue_kick(vgpio->event_vq);
> +}
> +
> +static void virtio_gpio_irq_enable(struct irq_data *d)
> +{
> +   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
> +   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
> +
> +   raw_spin_lock(>eventq_lock);
> +   irq_line->disabled = false;
> +   irq_line->masked = false;
> +   irq_line->queue_pending = true;
> +   raw_spin_unlock(>eventq_lock);
> +
> +   irq_line->update_pending = true;
> +}
> +
> +static void virtio_gpio_irq_disable(struct irq_data *d)
> +{
> +   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
> +   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
> +
> +   raw_spin_lock(>eventq_lock);
> +   irq_line->disabled = true;
> +   irq_line->masked = true;
> +   irq_line->queue_pending = false;
> +   raw_spin_unlock(>eventq_lock);
> +
> +   irq_line->update_pending = true;
> +}
> +
> +static void virtio_gpio_irq_mask(struct irq_data *d)
> +{
> +   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
> +   struct 

[PATCH V6] gpio: virtio: Add IRQ support

2021-10-20 Thread Viresh Kumar
This patch adds IRQ support for the virtio GPIO driver. Note that this
uses the irq_bus_lock/unlock() callbacks, since those operations over
virtio may sleep.

Reviewed-by: Linus Walleij 
Signed-off-by: Viresh Kumar 
---
Bartosz,

The spec changes are close to merging now, I will let you know once the ballot
is closed and the spec changes are merged. You can then pick this patch for
5.16.

V5->V6:
- Sent it separately as the other patches are already merged.
- Queue the buffers only after enabling the irq (as per latest spec).
- Migrate to raw_spinlock_t.

 drivers/gpio/Kconfig |   1 +
 drivers/gpio/gpio-virtio.c   | 310 ++-
 include/uapi/linux/virtio_gpio.h |  25 +++
 3 files changed, 332 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fae5141251e5..bfa723ff8e7c 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1674,6 +1674,7 @@ config GPIO_MOCKUP
 config GPIO_VIRTIO
tristate "VirtIO GPIO support"
depends on VIRTIO
+   select GPIOLIB_IRQCHIP
help
  Say Y here to enable guest support for virtio-based GPIO controllers.
 
diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c
index d24f1c9264bc..73fbe2eda4b9 100644
--- a/drivers/gpio/gpio-virtio.c
+++ b/drivers/gpio/gpio-virtio.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,12 +29,30 @@ struct virtio_gpio_line {
unsigned int rxlen;
 };
 
+struct vgpio_irq_line {
+   u8 type;
+   bool disabled;
+   bool masked;
+   bool queued;
+   bool update_pending;
+   bool queue_pending;
+
+   struct virtio_gpio_irq_request ireq cacheline_aligned;
+   struct virtio_gpio_irq_response ires cacheline_aligned;
+};
+
 struct virtio_gpio {
struct virtio_device *vdev;
struct mutex lock; /* Protects virtqueue operation */
struct gpio_chip gc;
struct virtio_gpio_line *lines;
struct virtqueue *request_vq;
+
+   /* irq support */
+   struct virtqueue *event_vq;
+   struct mutex irq_lock; /* Protects irq operation */
+   raw_spinlock_t eventq_lock; /* Protects queuing of the buffer */
+   struct vgpio_irq_line *irq_lines;
 };
 
 static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio,
@@ -186,6 +205,244 @@ static void virtio_gpio_set(struct gpio_chip *gc, 
unsigned int gpio, int value)
virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_VALUE, gpio, value, NULL);
 }
 
+/* Interrupt handling */
+static void virtio_gpio_irq_prepare(struct virtio_gpio *vgpio, u16 gpio)
+{
+   struct vgpio_irq_line *irq_line = >irq_lines[gpio];
+   struct virtio_gpio_irq_request *ireq = _line->ireq;
+   struct virtio_gpio_irq_response *ires = _line->ires;
+   struct scatterlist *sgs[2], req_sg, res_sg;
+   int ret;
+
+   if (WARN_ON(irq_line->queued || irq_line->masked || irq_line->disabled))
+   return;
+
+   ireq->gpio = cpu_to_le16(gpio);
+   sg_init_one(_sg, ireq, sizeof(*ireq));
+   sg_init_one(_sg, ires, sizeof(*ires));
+   sgs[0] = _sg;
+   sgs[1] = _sg;
+
+   ret = virtqueue_add_sgs(vgpio->event_vq, sgs, 1, 1, irq_line, 
GFP_ATOMIC);
+   if (ret) {
+   dev_err(>vdev->dev, "failed to add request to eventq\n");
+   return;
+   }
+
+   irq_line->queued = true;
+   virtqueue_kick(vgpio->event_vq);
+}
+
+static void virtio_gpio_irq_enable(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
+   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
+
+   raw_spin_lock(>eventq_lock);
+   irq_line->disabled = false;
+   irq_line->masked = false;
+   irq_line->queue_pending = true;
+   raw_spin_unlock(>eventq_lock);
+
+   irq_line->update_pending = true;
+}
+
+static void virtio_gpio_irq_disable(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
+   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
+
+   raw_spin_lock(>eventq_lock);
+   irq_line->disabled = true;
+   irq_line->masked = true;
+   irq_line->queue_pending = false;
+   raw_spin_unlock(>eventq_lock);
+
+   irq_line->update_pending = true;
+}
+
+static void virtio_gpio_irq_mask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct virtio_gpio *vgpio = gpiochip_get_data(gc);
+   struct vgpio_irq_line *irq_line = >irq_lines[d->hwirq];
+
+   raw_spin_lock(>eventq_lock);
+   irq_line->masked = true;
+   raw_spin_unlock(>eventq_lock);
+}
+
+static void virtio_gpio_irq_unmask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct virtio_gpio *vgpio =