Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gpio: sifive: use new generic GPIO chip API

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>

+38 -35
+38 -35
drivers/gpio/gpio-sifive.c
··· 7 7 #include <linux/device.h> 8 8 #include <linux/errno.h> 9 9 #include <linux/gpio/driver.h> 10 + #include <linux/gpio/generic.h> 10 11 #include <linux/init.h> 11 12 #include <linux/platform_device.h> 12 13 #include <linux/property.h> ··· 33 32 34 33 struct sifive_gpio { 35 34 void __iomem *base; 36 - struct gpio_chip gc; 35 + struct gpio_generic_chip gen_gc; 37 36 struct regmap *regs; 38 37 unsigned long irq_state; 39 38 unsigned int trigger[SIFIVE_GPIO_MAX]; ··· 42 41 43 42 static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset) 44 43 { 45 - unsigned long flags; 46 44 unsigned int trigger; 47 45 48 - raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags); 46 + guard(gpio_generic_lock_irqsave)(&chip->gen_gc); 47 + 49 48 trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0; 50 49 regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset), 51 50 (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0); ··· 55 54 (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0); 56 55 regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset), 57 56 (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0); 58 - raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags); 59 57 } 60 58 61 59 static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger) ··· 72 72 } 73 73 74 74 static void sifive_gpio_irq_enable(struct irq_data *d) 75 - { 75 + { 76 76 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 77 77 struct sifive_gpio *chip = gpiochip_get_data(gc); 78 78 irq_hw_number_t hwirq = irqd_to_hwirq(d); 79 79 int offset = hwirq % SIFIVE_GPIO_MAX; 80 80 u32 bit = BIT(offset); 81 - unsigned long flags; 82 81 83 82 gpiochip_enable_irq(gc, hwirq); 84 83 irq_chip_enable_parent(d); ··· 85 86 /* Switch to input */ 86 87 gc->direction_input(gc, offset); 87 88 88 - raw_spin_lock_irqsave(&gc->bgpio_lock, flags); 89 - /* Clear any sticky pending interrupts */ 90 - regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit); 91 - regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit); 92 - regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit); 93 - regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); 94 - raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); 89 + scoped_guard(gpio_generic_lock_irqsave, &chip->gen_gc) { 90 + /* Clear any sticky pending interrupts */ 91 + regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit); 92 + regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit); 93 + regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit); 94 + regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); 95 + } 95 96 96 97 /* Enable interrupts */ 97 98 assign_bit(offset, &chip->irq_state, 1); ··· 117 118 struct sifive_gpio *chip = gpiochip_get_data(gc); 118 119 int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX; 119 120 u32 bit = BIT(offset); 120 - unsigned long flags; 121 121 122 - raw_spin_lock_irqsave(&gc->bgpio_lock, flags); 123 - /* Clear all pending interrupts */ 124 - regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit); 125 - regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit); 126 - regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit); 127 - regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); 128 - raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); 122 + scoped_guard(gpio_generic_lock_irqsave, &chip->gen_gc) { 123 + /* Clear all pending interrupts */ 124 + regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit); 125 + regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit); 126 + regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit); 127 + regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit); 128 + } 129 129 130 130 irq_chip_eoi_parent(d); 131 131 } ··· 177 179 178 180 static int sifive_gpio_probe(struct platform_device *pdev) 179 181 { 182 + struct gpio_generic_chip_config config; 180 183 struct device *dev = &pdev->dev; 181 184 struct irq_domain *parent; 182 185 struct gpio_irq_chip *girq; ··· 216 217 */ 217 218 parent = irq_get_irq_data(chip->irq_number[0])->domain; 218 219 219 - ret = bgpio_init(&chip->gc, dev, 4, 220 - chip->base + SIFIVE_GPIO_INPUT_VAL, 221 - chip->base + SIFIVE_GPIO_OUTPUT_VAL, 222 - NULL, 223 - chip->base + SIFIVE_GPIO_OUTPUT_EN, 224 - chip->base + SIFIVE_GPIO_INPUT_EN, 225 - BGPIOF_READ_OUTPUT_REG_SET); 220 + config = (struct gpio_generic_chip_config) { 221 + .dev = dev, 222 + .sz = 4, 223 + .dat = chip->base + SIFIVE_GPIO_INPUT_VAL, 224 + .set = chip->base + SIFIVE_GPIO_OUTPUT_VAL, 225 + .dirout = chip->base + SIFIVE_GPIO_OUTPUT_EN, 226 + .dirin = chip->base + SIFIVE_GPIO_INPUT_EN, 227 + .flags = BGPIOF_READ_OUTPUT_REG_SET, 228 + }; 229 + 230 + ret = gpio_generic_chip_init(&chip->gen_gc, &config); 226 231 if (ret) { 227 232 dev_err(dev, "unable to init generic GPIO\n"); 228 233 return ret; ··· 239 236 regmap_write(chip->regs, SIFIVE_GPIO_LOW_IE, 0); 240 237 chip->irq_state = 0; 241 238 242 - chip->gc.base = -1; 243 - chip->gc.ngpio = ngpio; 244 - chip->gc.label = dev_name(dev); 245 - chip->gc.parent = dev; 246 - chip->gc.owner = THIS_MODULE; 247 - girq = &chip->gc.irq; 239 + chip->gen_gc.gc.base = -1; 240 + chip->gen_gc.gc.ngpio = ngpio; 241 + chip->gen_gc.gc.label = dev_name(dev); 242 + chip->gen_gc.gc.parent = dev; 243 + chip->gen_gc.gc.owner = THIS_MODULE; 244 + girq = &chip->gen_gc.gc.irq; 248 245 gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip); 249 246 girq->fwnode = dev_fwnode(dev); 250 247 girq->parent_domain = parent; ··· 252 249 girq->handler = handle_bad_irq; 253 250 girq->default_type = IRQ_TYPE_NONE; 254 251 255 - return gpiochip_add_data(&chip->gc, chip); 252 + return gpiochip_add_data(&chip->gen_gc.gc, chip); 256 253 } 257 254 258 255 static const struct of_device_id sifive_gpio_match[] = {