gpio: pcf857x: Make the irqchip immutable
authorGeert Uytterhoeven <geert+renesas@glider.be>
Fri, 20 May 2022 10:20:57 +0000 (12:20 +0200)
committerBartosz Golaszewski <brgl@bgdev.pl>
Tue, 24 May 2022 14:35:42 +0000 (16:35 +0200)
Commit 6c846d026d49 ("gpio: Don't fiddle with irqchips marked as
immutable") added a warning to indicate if the gpiolib is altering the
internals of irqchips.  Following this change the following warning is
now observed for the pcf857x driver:

    gpio gpiochip1: (pcf8575): not an immutable chip, please consider fixing it!

Fix this by making the irqchip in the pcf857x driver immutable.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
drivers/gpio/gpio-pcf857x.c

index e3a53dd..59cc27e 100644 (file)
@@ -71,7 +71,6 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);
  */
 struct pcf857x {
        struct gpio_chip        chip;
-       struct irq_chip         irqchip;
        struct i2c_client       *client;
        struct mutex            lock;           /* protect 'out' */
        unsigned                out;            /* software latch */
@@ -203,15 +202,19 @@ static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)
 static void pcf857x_irq_enable(struct irq_data *data)
 {
        struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
-       gpio->irq_enabled |= (1 << data->hwirq);
+       gpiochip_enable_irq(&gpio->chip, hwirq);
+       gpio->irq_enabled |= (1 << hwirq);
 }
 
 static void pcf857x_irq_disable(struct irq_data *data)
 {
        struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+       irq_hw_number_t hwirq = irqd_to_hwirq(data);
 
-       gpio->irq_enabled &= ~(1 << data->hwirq);
+       gpio->irq_enabled &= ~(1 << hwirq);
+       gpiochip_disable_irq(&gpio->chip, hwirq);
 }
 
 static void pcf857x_irq_bus_lock(struct irq_data *data)
@@ -228,6 +231,20 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
        mutex_unlock(&gpio->lock);
 }
 
+static const struct irq_chip pcf857x_irq_chip = {
+       .name                   = "pcf857x",
+       .irq_enable             = pcf857x_irq_enable,
+       .irq_disable            = pcf857x_irq_disable,
+       .irq_ack                = noop,
+       .irq_mask               = noop,
+       .irq_unmask             = noop,
+       .irq_set_wake           = pcf857x_irq_set_wake,
+       .irq_bus_lock           = pcf857x_irq_bus_lock,
+       .irq_bus_sync_unlock    = pcf857x_irq_bus_sync_unlock,
+       .flags                  = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
 /*-------------------------------------------------------------------------*/
 
 static int pcf857x_probe(struct i2c_client *client,
@@ -338,16 +355,6 @@ static int pcf857x_probe(struct i2c_client *client,
        if (client->irq) {
                struct gpio_irq_chip *girq;
 
-               gpio->irqchip.name = "pcf857x";
-               gpio->irqchip.irq_enable = pcf857x_irq_enable;
-               gpio->irqchip.irq_disable = pcf857x_irq_disable;
-               gpio->irqchip.irq_ack = noop;
-               gpio->irqchip.irq_mask = noop;
-               gpio->irqchip.irq_unmask = noop;
-               gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake;
-               gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock;
-               gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock;
-
                status = devm_request_threaded_irq(&client->dev, client->irq,
                                        NULL, pcf857x_irq, IRQF_ONESHOT |
                                        IRQF_TRIGGER_FALLING | IRQF_SHARED,
@@ -356,7 +363,7 @@ static int pcf857x_probe(struct i2c_client *client,
                        goto fail;
 
                girq = &gpio->chip.irq;
-               girq->chip = &gpio->irqchip;
+               gpio_irq_chip_set_chip(girq, &pcf857x_irq_chip);
                /* This will let us handle the parent IRQ in the driver */
                girq->parent_handler = NULL;
                girq->num_parents = 0;