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

gpio: etraxfs: make use of raw_spinlock variants

The etraxfs 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>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Julia Cartwright and committed by
Linus Walleij
f9c56536 a080ce53

+12 -12
+12 -12
drivers/gpio/gpio-etraxfs.c
··· 54 54 struct etraxfs_gpio_info; 55 55 56 56 struct etraxfs_gpio_block { 57 - spinlock_t lock; 57 + raw_spinlock_t lock; 58 58 u32 mask; 59 59 u32 cfg; 60 60 u32 pins; ··· 233 233 struct etraxfs_gpio_block *block = chip->block; 234 234 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); 235 235 236 - spin_lock(&block->lock); 236 + raw_spin_lock(&block->lock); 237 237 block->mask &= ~BIT(grpirq); 238 238 writel(block->mask, block->regs + block->info->rw_intr_mask); 239 - spin_unlock(&block->lock); 239 + raw_spin_unlock(&block->lock); 240 240 } 241 241 242 242 static void etraxfs_gpio_irq_unmask(struct irq_data *d) ··· 246 246 struct etraxfs_gpio_block *block = chip->block; 247 247 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); 248 248 249 - spin_lock(&block->lock); 249 + raw_spin_lock(&block->lock); 250 250 block->mask |= BIT(grpirq); 251 251 writel(block->mask, block->regs + block->info->rw_intr_mask); 252 - spin_unlock(&block->lock); 252 + raw_spin_unlock(&block->lock); 253 253 } 254 254 255 255 static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type) ··· 280 280 return -EINVAL; 281 281 } 282 282 283 - spin_lock(&block->lock); 283 + raw_spin_lock(&block->lock); 284 284 block->cfg &= ~(0x7 << (grpirq * 3)); 285 285 block->cfg |= (cfg << (grpirq * 3)); 286 286 writel(block->cfg, block->regs + block->info->rw_intr_cfg); 287 - spin_unlock(&block->lock); 287 + raw_spin_unlock(&block->lock); 288 288 289 289 return 0; 290 290 } ··· 297 297 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); 298 298 int ret = -EBUSY; 299 299 300 - spin_lock(&block->lock); 300 + raw_spin_lock(&block->lock); 301 301 if (block->group[grpirq]) 302 302 goto out; 303 303 ··· 316 316 } 317 317 318 318 out: 319 - spin_unlock(&block->lock); 319 + raw_spin_unlock(&block->lock); 320 320 return ret; 321 321 } 322 322 ··· 327 327 struct etraxfs_gpio_block *block = chip->block; 328 328 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq); 329 329 330 - spin_lock(&block->lock); 330 + raw_spin_lock(&block->lock); 331 331 block->group[grpirq] = 0; 332 332 gpiochip_unlock_as_irq(&chip->gc, d->hwirq); 333 - spin_unlock(&block->lock); 333 + raw_spin_unlock(&block->lock); 334 334 } 335 335 336 336 static struct irq_chip etraxfs_gpio_irq_chip = { ··· 391 391 if (!block) 392 392 return -ENOMEM; 393 393 394 - spin_lock_init(&block->lock); 394 + raw_spin_lock_init(&block->lock); 395 395 396 396 block->regs = regs; 397 397 block->info = info;