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]>
