mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 06:18:54 +00:00 
			
		
		
		
	arm/imx/gpio: add spinlock protection
The GPIO registers need protection from concurrent access for operations that are not atomic. Cc: stable@kernel.org Cc: Juergen Beisert <j.beisert@pengutronix.de> Cc: Daniel Mack <daniel@caiaq.de> Reported-by: rpkamiak@rockwellcollins.com Signed-off-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
		
							parent
							
								
									ef93f1443c
								
							
						
					
					
						commit
						14cb0deb66
					
				| @ -214,13 +214,16 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | ||||
| 	struct mxc_gpio_port *port = | ||||
| 		container_of(chip, struct mxc_gpio_port, chip); | ||||
| 	u32 l; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&port->lock, flags); | ||||
| 	l = __raw_readl(port->base + GPIO_GDIR); | ||||
| 	if (dir) | ||||
| 		l |= 1 << offset; | ||||
| 	else | ||||
| 		l &= ~(1 << offset); | ||||
| 	__raw_writel(l, port->base + GPIO_GDIR); | ||||
| 	spin_unlock_irqrestore(&port->lock, flags); | ||||
| } | ||||
| 
 | ||||
| static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||||
| @ -229,9 +232,12 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||||
| 		container_of(chip, struct mxc_gpio_port, chip); | ||||
| 	void __iomem *reg = port->base + GPIO_DR; | ||||
| 	u32 l; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&port->lock, flags); | ||||
| 	l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); | ||||
| 	__raw_writel(l, reg); | ||||
| 	spin_unlock_irqrestore(&port->lock, flags); | ||||
| } | ||||
| 
 | ||||
| static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) | ||||
| @ -285,6 +291,8 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) | ||||
| 		port[i].chip.base = i * 32; | ||||
| 		port[i].chip.ngpio = 32; | ||||
| 
 | ||||
| 		spin_lock_init(&port[i].lock); | ||||
| 
 | ||||
| 		/* its a serious configuration bug when it fails */ | ||||
| 		BUG_ON( gpiochip_add(&port[i].chip) < 0 ); | ||||
| 
 | ||||
|  | ||||
| @ -37,6 +37,7 @@ struct mxc_gpio_port { | ||||
| 	int virtual_irq_start; | ||||
| 	struct gpio_chip chip; | ||||
| 	u32 both_edges; | ||||
| 	spinlock_t lock; | ||||
| }; | ||||
| 
 | ||||
| int mxc_gpio_init(struct mxc_gpio_port*, int); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Baruch Siach
						Baruch Siach