The kernel has been warning about non-immutable irq_chips for quite some
time, printing messages such as the following one during initialization:

  gpio gpiochip6: (virtio2): not an immutable chip, please consider fixing it!

Convert the gpio-virtio irq_chip to immutable and add the relevant
helpers. The exposed name is kept the same as before through the
.irq_print_chip callback.

Signed-off-by: Francesco Valla <[email protected]>
---
 drivers/gpio/gpio-virtio.c | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c
index ed6e0e90fa8a..d443b8c0e813 100644
--- a/drivers/gpio/gpio-virtio.c
+++ b/drivers/gpio/gpio-virtio.c
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/virtio_config.h>
 #include <uapi/linux/virtio_gpio.h>
@@ -243,6 +244,8 @@ static void virtio_gpio_irq_enable(struct irq_data *d)
        struct virtio_gpio *vgpio = gpiochip_get_data(gc);
        struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq];
 
+       gpiochip_enable_irq(gc, d->hwirq);
+
        raw_spin_lock(&vgpio->eventq_lock);
        irq_line->disabled = false;
        irq_line->masked = false;
@@ -265,6 +268,8 @@ static void virtio_gpio_irq_disable(struct irq_data *d)
        raw_spin_unlock(&vgpio->eventq_lock);
 
        irq_line->update_pending = true;
+
+       gpiochip_disable_irq(gc, d->hwirq);
 }
 
 static void virtio_gpio_irq_mask(struct irq_data *d)
@@ -532,11 +537,30 @@ static const char **virtio_gpio_get_names(struct 
virtio_gpio *vgpio,
        return names;
 }
 
+static void virtio_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+       seq_puts(p, dev_name(gc->parent));
+}
+
+static const struct irq_chip virtio_gpio_irqchip = {
+       .irq_enable = virtio_gpio_irq_enable,
+       .irq_disable = virtio_gpio_irq_disable,
+       .irq_mask = virtio_gpio_irq_mask,
+       .irq_unmask = virtio_gpio_irq_unmask,
+       .irq_set_type = virtio_gpio_irq_set_type,
+       .irq_bus_lock = virtio_gpio_irq_bus_lock,
+       .irq_bus_sync_unlock = virtio_gpio_irq_bus_sync_unlock,
+       .irq_print_chip = virtio_gpio_irq_print_chip,
+       .flags = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
 static int virtio_gpio_probe(struct virtio_device *vdev)
 {
        struct device *dev = &vdev->dev;
        struct virtio_gpio *vgpio;
-       struct irq_chip *gpio_irq_chip;
        u32 gpio_names_size;
        u16 ngpio;
        int ret, i;
@@ -588,26 +612,13 @@ static int virtio_gpio_probe(struct virtio_device *vdev)
                if (!vgpio->irq_lines)
                        return -ENOMEM;
 
-               gpio_irq_chip = devm_kzalloc(dev, sizeof(*gpio_irq_chip), 
GFP_KERNEL);
-               if (!gpio_irq_chip)
-                       return -ENOMEM;
-
-               gpio_irq_chip->name = dev_name(dev);
-               gpio_irq_chip->irq_enable = virtio_gpio_irq_enable;
-               gpio_irq_chip->irq_disable = virtio_gpio_irq_disable;
-               gpio_irq_chip->irq_mask = virtio_gpio_irq_mask;
-               gpio_irq_chip->irq_unmask = virtio_gpio_irq_unmask;
-               gpio_irq_chip->irq_set_type = virtio_gpio_irq_set_type;
-               gpio_irq_chip->irq_bus_lock = virtio_gpio_irq_bus_lock;
-               gpio_irq_chip->irq_bus_sync_unlock = 
virtio_gpio_irq_bus_sync_unlock;
-
                /* The event comes from the outside so no parent handler */
                vgpio->gc.irq.parent_handler    = NULL;
                vgpio->gc.irq.num_parents       = 0;
                vgpio->gc.irq.parents           = NULL;
                vgpio->gc.irq.default_type      = IRQ_TYPE_NONE;
                vgpio->gc.irq.handler           = handle_level_irq;
-               vgpio->gc.irq.chip              = gpio_irq_chip;
+               gpio_irq_chip_set_chip(&vgpio->gc.irq, &virtio_gpio_irqchip);
 
                for (i = 0; i < ngpio; i++) {
                        vgpio->irq_lines[i].type = VIRTIO_GPIO_IRQ_TYPE_NONE;

---
base-commit: d135ab453a7400a34930bdda1ef4bdc8acfac80e
change-id: 20261018-virtio-gpio-irqchip-immutable-9b69717cba4c

Best regards,
--  
Francesco Valla <[email protected]>


Reply via email to