Prev: [08/36] amd64_edac: Fix DCT base address selector
Next: [13/36] 9p: strlen() doesnt count the terminator
From: Greg KH on 6 Aug 2010 15:40 2.6.34-stable review patch. If anyone has any objections, please let us know. ------------------ From: Baruch Siach <baruch(a)tkos.co.il> commit 14cb0deb66fcfca8fdbef75da8c84b5405a8c767 upstream. The GPIO registers need protection from concurrent access for operations that are not atomic. Cc: Juergen Beisert <j.beisert(a)pengutronix.de> Cc: Daniel Mack <daniel(a)caiaq.de> Reported-by: rpkamiak(a)rockwellcollins.com Signed-off-by: Baruch Siach <baruch(a)tkos.co.il> Signed-off-by: Sascha Hauer <s.hauer(a)pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de> --- arch/arm/plat-mxc/gpio.c | 8 ++++++++ arch/arm/plat-mxc/include/mach/gpio.h | 1 + 2 files changed, 9 insertions(+) --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -215,13 +215,16 @@ static void _set_gpio_direction(struct g 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) @@ -230,9 +233,12 @@ static void mxc_gpio_set(struct gpio_chi 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) @@ -286,6 +292,8 @@ int __init mxc_gpio_init(struct mxc_gpio 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 ); --- a/arch/arm/plat-mxc/include/mach/gpio.h +++ b/arch/arm/plat-mxc/include/mach/gpio.h @@ -36,6 +36,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); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |