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: ath79: use the generic GPIO chip lock for IRQ handling

This driver uses its own raw spinlock in interrupt routines while the
generic GPIO chip callbacks use a separate one. This is, of course, racy
so use the fact that the lock in generic GPIO chip is also a raw
spinlock and convert the interrupt handling functions in this module to
using the provided generic GPIO chip locking API.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20250910-gpio-mmio-gpio-conv-part4-v2-5-f3d1a4c57124@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

+19 -32
+19 -32
drivers/gpio/gpio-ath79.c
··· 31 31 struct ath79_gpio_ctrl { 32 32 struct gpio_generic_chip chip; 33 33 void __iomem *base; 34 - raw_spinlock_t lock; 35 34 unsigned long both_edges; 36 35 }; 37 36 ··· 71 72 { 72 73 struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); 73 74 u32 mask = BIT(irqd_to_hwirq(data)); 74 - unsigned long flags; 75 75 76 76 gpiochip_enable_irq(&ctrl->chip.gc, irqd_to_hwirq(data)); 77 - raw_spin_lock_irqsave(&ctrl->lock, flags); 77 + 78 + guard(gpio_generic_lock_irqsave)(&ctrl->chip); 79 + 78 80 ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); 79 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 80 81 } 81 82 82 83 static void ath79_gpio_irq_mask(struct irq_data *data) 83 84 { 84 85 struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); 85 86 u32 mask = BIT(irqd_to_hwirq(data)); 86 - unsigned long flags; 87 87 88 - raw_spin_lock_irqsave(&ctrl->lock, flags); 89 - ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); 90 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 88 + scoped_guard(gpio_generic_lock_irqsave, &ctrl->chip) 89 + ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); 90 + 91 91 gpiochip_disable_irq(&ctrl->chip.gc, irqd_to_hwirq(data)); 92 92 } 93 93 ··· 94 96 { 95 97 struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); 96 98 u32 mask = BIT(irqd_to_hwirq(data)); 97 - unsigned long flags; 98 99 99 - raw_spin_lock_irqsave(&ctrl->lock, flags); 100 + guard(gpio_generic_lock_irqsave)(&ctrl->chip); 100 101 ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); 101 102 ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); 102 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 103 103 } 104 104 105 105 static void ath79_gpio_irq_disable(struct irq_data *data) 106 106 { 107 107 struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); 108 108 u32 mask = BIT(irqd_to_hwirq(data)); 109 - unsigned long flags; 110 109 111 - raw_spin_lock_irqsave(&ctrl->lock, flags); 110 + guard(gpio_generic_lock_irqsave)(&ctrl->chip); 112 111 ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); 113 112 ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0); 114 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 115 113 } 116 114 117 115 static int ath79_gpio_irq_set_type(struct irq_data *data, ··· 116 122 struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); 117 123 u32 mask = BIT(irqd_to_hwirq(data)); 118 124 u32 type = 0, polarity = 0; 119 - unsigned long flags; 120 125 bool disabled; 121 126 122 127 switch (flow_type) { ··· 137 144 return -EINVAL; 138 145 } 139 146 140 - raw_spin_lock_irqsave(&ctrl->lock, flags); 147 + guard(gpio_generic_lock_irqsave)(&ctrl->chip); 141 148 142 149 if (flow_type == IRQ_TYPE_EDGE_BOTH) { 143 150 ctrl->both_edges |= mask; ··· 162 169 ath79_gpio_update_bits( 163 170 ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); 164 171 165 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 166 - 167 172 return 0; 168 173 } 169 174 ··· 183 192 struct gpio_generic_chip *gen_gc = to_gpio_generic_chip(gc); 184 193 struct ath79_gpio_ctrl *ctrl = 185 194 container_of(gen_gc, struct ath79_gpio_ctrl, chip); 186 - unsigned long flags, pending; 195 + unsigned long pending; 187 196 u32 both_edges, state; 188 197 int irq; 189 198 190 199 chained_irq_enter(irqchip, desc); 191 200 192 - raw_spin_lock_irqsave(&ctrl->lock, flags); 201 + scoped_guard(gpio_generic_lock_irqsave, &ctrl->chip) { 202 + pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING); 193 203 194 - pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING); 195 - 196 - /* Update the polarity of the both edges irqs */ 197 - both_edges = ctrl->both_edges & pending; 198 - if (both_edges) { 199 - state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN); 200 - ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY, 201 - both_edges, ~state); 204 + /* Update the polarity of the both edges irqs */ 205 + both_edges = ctrl->both_edges & pending; 206 + if (both_edges) { 207 + state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN); 208 + ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY, 209 + both_edges, ~state); 210 + } 202 211 } 203 - 204 - raw_spin_unlock_irqrestore(&ctrl->lock, flags); 205 212 206 213 for_each_set_bit(irq, &pending, gc->ngpio) 207 214 generic_handle_domain_irq(gc->irq.domain, irq); ··· 244 255 ctrl->base = devm_platform_ioremap_resource(pdev, 0); 245 256 if (IS_ERR(ctrl->base)) 246 257 return PTR_ERR(ctrl->base); 247 - 248 - raw_spin_lock_init(&ctrl->lock); 249 258 250 259 config = (struct gpio_generic_chip_config) { 251 260 .dev = dev,