[PATCH] arm/orion: use set_bit and clear_bit in gpio implementation

Holger Brunck holger.brunck at keymile.com
Wed Dec 7 09:34:43 EST 2011


set_bit and clear_bit are already atomic operations. So use this
functions to set or unset gpio configurations. This makes the
additional spinlock unneeded.

Signed-off-by: Stefan Bigler <stefan.bigler at keymile.com>
Signed-off-by: Holger Brunck <holger.brunck at keymile.com>
cc: Lennert Buytenhek <kernel at wantstofly.org>
cc: Nicolas Pitre <nico at fluxnic.net>
cc: Russell King <linux at arm.linux.org.uk>
cc: Thomas Gleixner <tglx at linutronix.de>
---
 arch/arm/plat-orion/gpio.c |   38 ++++++--------------------------------
 1 files changed, 6 insertions(+), 32 deletions(-)

diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 41ab97e..d9d5577 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -31,7 +31,6 @@
 
 struct orion_gpio_chip {
 	struct gpio_chip	chip;
-	spinlock_t		lock;
 	void __iomem		*base;
 	unsigned long		valid_input;
 	unsigned long		valid_output;
@@ -86,39 +85,27 @@ static int orion_gpio_chip_count;
 static inline void
 __set_direction(struct orion_gpio_chip *ochip, unsigned pin, int input)
 {
-	u32 u;
-
-	u = readl(GPIO_IO_CONF(ochip));
 	if (input)
-		u |= 1 << pin;
+		set_bit(pin, (void*)GPIO_IO_CONF(ochip));
 	else
-		u &= ~(1 << pin);
-	writel(u, GPIO_IO_CONF(ochip));
+		clear_bit(pin, (void*)GPIO_IO_CONF(ochip));
 }
 
 static void __set_level(struct orion_gpio_chip *ochip, unsigned pin, int high)
 {
-	u32 u;
-
-	u = readl(GPIO_OUT(ochip));
 	if (high)
-		u |= 1 << pin;
+		set_bit(pin, (void*)GPIO_OUT(ochip));
 	else
-		u &= ~(1 << pin);
-	writel(u, GPIO_OUT(ochip));
+		clear_bit(pin, (void*)GPIO_OUT(ochip));
 }
 
 static inline void
 __set_blinking(struct orion_gpio_chip *ochip, unsigned pin, int blink)
 {
-	u32 u;
-
-	u = readl(GPIO_BLINK_EN(ochip));
 	if (blink)
-		u |= 1 << pin;
+		set_bit(pin, (void*)GPIO_BLINK_EN(ochip));
 	else
-		u &= ~(1 << pin);
-	writel(u, GPIO_BLINK_EN(ochip));
+		clear_bit(pin, (void*)GPIO_BLINK_EN(ochip));
 }
 
 static inline int
@@ -159,14 +146,11 @@ static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
 {
 	struct orion_gpio_chip *ochip =
 		container_of(chip, struct orion_gpio_chip, chip);
-	unsigned long flags;
 
 	if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK))
 		return -EINVAL;
 
-	spin_lock_irqsave(&ochip->lock, flags);
 	__set_direction(ochip, pin, 1);
-	spin_unlock_irqrestore(&ochip->lock, flags);
 
 	return 0;
 }
@@ -191,16 +175,13 @@ orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value)
 {
 	struct orion_gpio_chip *ochip =
 		container_of(chip, struct orion_gpio_chip, chip);
-	unsigned long flags;
 
 	if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
 		return -EINVAL;
 
-	spin_lock_irqsave(&ochip->lock, flags);
 	__set_blinking(ochip, pin, 0);
 	__set_level(ochip, pin, value);
 	__set_direction(ochip, pin, 0);
-	spin_unlock_irqrestore(&ochip->lock, flags);
 
 	return 0;
 }
@@ -209,11 +190,8 @@ static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
 {
 	struct orion_gpio_chip *ochip =
 		container_of(chip, struct orion_gpio_chip, chip);
-	unsigned long flags;
 
-	spin_lock_irqsave(&ochip->lock, flags);
 	__set_level(ochip, pin, value);
-	spin_unlock_irqrestore(&ochip->lock, flags);
 }
 
 static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
@@ -283,15 +261,12 @@ void __init orion_gpio_set_valid(unsigned pin, int mode)
 void orion_gpio_set_blink(unsigned pin, int blink)
 {
 	struct orion_gpio_chip *ochip = orion_gpio_chip_find(pin);
-	unsigned long flags;
 
 	if (ochip == NULL)
 		return;
 
-	spin_lock_irqsave(&ochip->lock, flags);
 	__set_level(ochip, pin, 0);
 	__set_blinking(ochip, pin, blink);
-	spin_unlock_irqrestore(&ochip->lock, flags);
 }
 EXPORT_SYMBOL(orion_gpio_set_blink);
 
@@ -399,7 +374,6 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
 	ochip->chip.base = gpio_base;
 	ochip->chip.ngpio = ngpio;
 	ochip->chip.can_sleep = 0;
-	spin_lock_init(&ochip->lock);
 	ochip->base = (void __iomem *)base;
 	ochip->valid_input = 0;
 	ochip->valid_output = 0;
-- 
1.7.1




More information about the linux-arm-kernel mailing list