]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
gpio: sifive: use new generic GPIO chip API
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 10 Sep 2025 07:12:47 +0000 (09:12 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Fri, 12 Sep 2025 07:22:44 +0000 (09:22 +0200)
Convert the driver to using the new generic GPIO chip interfaces from
linux/gpio/generic.h.

Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20250910-gpio-mmio-gpio-conv-part4-v2-11-f3d1a4c57124@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpio-sifive.c

index 98ef975c44d9a6c9238605cfd1d5820fd70a66ca..2ced87ffd3bbf219c11857391eb4ea808adc0527 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/gpio/driver.h>
+#include <linux/gpio/generic.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
@@ -32,7 +33,7 @@
 
 struct sifive_gpio {
        void __iomem            *base;
-       struct gpio_chip        gc;
+       struct gpio_generic_chip gen_gc;
        struct regmap           *regs;
        unsigned long           irq_state;
        unsigned int            trigger[SIFIVE_GPIO_MAX];
@@ -41,10 +42,10 @@ struct sifive_gpio {
 
 static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
 {
-       unsigned long flags;
        unsigned int trigger;
 
-       raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
+       guard(gpio_generic_lock_irqsave)(&chip->gen_gc);
+
        trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
        regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
                           (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
@@ -54,7 +55,6 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
                           (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
        regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
                           (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
-       raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
 }
 
 static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
@@ -72,13 +72,12 @@ static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
 }
 
 static void sifive_gpio_irq_enable(struct irq_data *d)
-{
+       {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct sifive_gpio *chip = gpiochip_get_data(gc);
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
        int offset = hwirq % SIFIVE_GPIO_MAX;
        u32 bit = BIT(offset);
-       unsigned long flags;
 
        gpiochip_enable_irq(gc, hwirq);
        irq_chip_enable_parent(d);
@@ -86,13 +85,13 @@ static void sifive_gpio_irq_enable(struct irq_data *d)
        /* Switch to input */
        gc->direction_input(gc, offset);
 
-       raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
-       /* Clear any sticky pending interrupts */
-       regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
-       raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+       scoped_guard(gpio_generic_lock_irqsave, &chip->gen_gc) {
+               /* Clear any sticky pending interrupts */
+               regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+       }
 
        /* Enable interrupts */
        assign_bit(offset, &chip->irq_state, 1);
@@ -118,15 +117,14 @@ static void sifive_gpio_irq_eoi(struct irq_data *d)
        struct sifive_gpio *chip = gpiochip_get_data(gc);
        int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
        u32 bit = BIT(offset);
-       unsigned long flags;
 
-       raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
-       /* Clear all pending interrupts */
-       regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
-       regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
-       raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+       scoped_guard(gpio_generic_lock_irqsave, &chip->gen_gc) {
+               /* Clear all pending interrupts */
+               regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+               regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+       }
 
        irq_chip_eoi_parent(d);
 }
@@ -179,6 +177,7 @@ static const struct regmap_config sifive_gpio_regmap_config = {
 
 static int sifive_gpio_probe(struct platform_device *pdev)
 {
+       struct gpio_generic_chip_config config;
        struct device *dev = &pdev->dev;
        struct irq_domain *parent;
        struct gpio_irq_chip *girq;
@@ -217,13 +216,17 @@ static int sifive_gpio_probe(struct platform_device *pdev)
         */
        parent = irq_get_irq_data(chip->irq_number[0])->domain;
 
-       ret = bgpio_init(&chip->gc, dev, 4,
-                        chip->base + SIFIVE_GPIO_INPUT_VAL,
-                        chip->base + SIFIVE_GPIO_OUTPUT_VAL,
-                        NULL,
-                        chip->base + SIFIVE_GPIO_OUTPUT_EN,
-                        chip->base + SIFIVE_GPIO_INPUT_EN,
-                        BGPIOF_READ_OUTPUT_REG_SET);
+       config = (struct gpio_generic_chip_config) {
+               .dev = dev,
+               .sz = 4,
+               .dat = chip->base + SIFIVE_GPIO_INPUT_VAL,
+               .set = chip->base + SIFIVE_GPIO_OUTPUT_VAL,
+               .dirout = chip->base + SIFIVE_GPIO_OUTPUT_EN,
+               .dirin = chip->base + SIFIVE_GPIO_INPUT_EN,
+               .flags = BGPIOF_READ_OUTPUT_REG_SET,
+       };
+
+       ret = gpio_generic_chip_init(&chip->gen_gc, &config);
        if (ret) {
                dev_err(dev, "unable to init generic GPIO\n");
                return ret;
@@ -236,12 +239,12 @@ static int sifive_gpio_probe(struct platform_device *pdev)
        regmap_write(chip->regs, SIFIVE_GPIO_LOW_IE, 0);
        chip->irq_state = 0;
 
-       chip->gc.base = -1;
-       chip->gc.ngpio = ngpio;
-       chip->gc.label = dev_name(dev);
-       chip->gc.parent = dev;
-       chip->gc.owner = THIS_MODULE;
-       girq = &chip->gc.irq;
+       chip->gen_gc.gc.base = -1;
+       chip->gen_gc.gc.ngpio = ngpio;
+       chip->gen_gc.gc.label = dev_name(dev);
+       chip->gen_gc.gc.parent = dev;
+       chip->gen_gc.gc.owner = THIS_MODULE;
+       girq = &chip->gen_gc.gc.irq;
        gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);
        girq->fwnode = dev_fwnode(dev);
        girq->parent_domain = parent;
@@ -249,7 +252,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
        girq->handler = handle_bad_irq;
        girq->default_type = IRQ_TYPE_NONE;
 
-       return gpiochip_add_data(&chip->gc, chip);
+       return gpiochip_add_data(&chip->gen_gc.gc, chip);
 }
 
 static const struct of_device_id sifive_gpio_match[] = {