diff mbox series

[v2] gpio: pcf857x: Make the irqchip immutable

Message ID 53a48d4c26252160f090371e24352975a7ea7add.1653042025.git.geert+renesas@glider.be
State New
Headers show
Series [v2] gpio: pcf857x: Make the irqchip immutable | expand

Commit Message

Geert Uytterhoeven May 20, 2022, 10:20 a.m. UTC
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>
---
Against gpio/for-next.
Tested with pcf8575 and gpio-keys (including wake-up) on the
sh73a0/kzm9g development board.

v2:
  - Factor out hwirq using preferred helper.
---
 drivers/gpio/gpio-pcf857x.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index e3a53dd5df1ec472..59cc27e4de511b18 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -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;