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

gpio: pci-idio-16: make use of raw_spinlock variants

The pci-idio-16 gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.

A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.

Signed-off-by: Julia Cartwright <julia@ni.com>
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Julia Cartwright and committed by
Linus Walleij
ea38ce08 3906e808

+14 -14
+14 -14
drivers/gpio/gpio-pci-idio-16.c
··· 59 59 */ 60 60 struct idio_16_gpio { 61 61 struct gpio_chip chip; 62 - spinlock_t lock; 62 + raw_spinlock_t lock; 63 63 struct idio_16_gpio_reg __iomem *reg; 64 64 unsigned long irq_mask; 65 65 }; ··· 121 121 } else 122 122 base = &idio16gpio->reg->out0_7; 123 123 124 - spin_lock_irqsave(&idio16gpio->lock, flags); 124 + raw_spin_lock_irqsave(&idio16gpio->lock, flags); 125 125 126 126 if (value) 127 127 out_state = ioread8(base) | mask; ··· 130 130 131 131 iowrite8(out_state, base); 132 132 133 - spin_unlock_irqrestore(&idio16gpio->lock, flags); 133 + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 134 134 } 135 135 136 136 static void idio_16_gpio_set_multiple(struct gpio_chip *chip, ··· 140 140 unsigned long flags; 141 141 unsigned int out_state; 142 142 143 - spin_lock_irqsave(&idio16gpio->lock, flags); 143 + raw_spin_lock_irqsave(&idio16gpio->lock, flags); 144 144 145 145 /* process output lines 0-7 */ 146 146 if (*mask & 0xFF) { ··· 160 160 iowrite8(out_state, &idio16gpio->reg->out8_15); 161 161 } 162 162 163 - spin_unlock_irqrestore(&idio16gpio->lock, flags); 163 + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 164 164 } 165 165 166 166 static void idio_16_irq_ack(struct irq_data *data) ··· 177 177 idio16gpio->irq_mask &= ~mask; 178 178 179 179 if (!idio16gpio->irq_mask) { 180 - spin_lock_irqsave(&idio16gpio->lock, flags); 180 + raw_spin_lock_irqsave(&idio16gpio->lock, flags); 181 181 182 182 iowrite8(0, &idio16gpio->reg->irq_ctl); 183 183 184 - spin_unlock_irqrestore(&idio16gpio->lock, flags); 184 + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 185 185 } 186 186 } 187 187 ··· 196 196 idio16gpio->irq_mask |= mask; 197 197 198 198 if (!prev_irq_mask) { 199 - spin_lock_irqsave(&idio16gpio->lock, flags); 199 + raw_spin_lock_irqsave(&idio16gpio->lock, flags); 200 200 201 201 ioread8(&idio16gpio->reg->irq_ctl); 202 202 203 - spin_unlock_irqrestore(&idio16gpio->lock, flags); 203 + raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 204 204 } 205 205 } 206 206 ··· 229 229 struct gpio_chip *const chip = &idio16gpio->chip; 230 230 int gpio; 231 231 232 - spin_lock(&idio16gpio->lock); 232 + raw_spin_lock(&idio16gpio->lock); 233 233 234 234 irq_status = ioread8(&idio16gpio->reg->irq_status); 235 235 236 - spin_unlock(&idio16gpio->lock); 236 + raw_spin_unlock(&idio16gpio->lock); 237 237 238 238 /* Make sure our device generated IRQ */ 239 239 if (!(irq_status & 0x3) || !(irq_status & 0x4)) ··· 242 242 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) 243 243 generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); 244 244 245 - spin_lock(&idio16gpio->lock); 245 + raw_spin_lock(&idio16gpio->lock); 246 246 247 247 /* Clear interrupt */ 248 248 iowrite8(0, &idio16gpio->reg->in0_7); 249 249 250 - spin_unlock(&idio16gpio->lock); 250 + raw_spin_unlock(&idio16gpio->lock); 251 251 252 252 return IRQ_HANDLED; 253 253 } ··· 302 302 idio16gpio->chip.set = idio_16_gpio_set; 303 303 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; 304 304 305 - spin_lock_init(&idio16gpio->lock); 305 + raw_spin_lock_init(&idio16gpio->lock); 306 306 307 307 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); 308 308 if (err) {