Skip to contentSkip to conversation

gpio: gpio-ml-ioh: Use spinlock for register access protection

PATCH Applied Axel Lin 3 participants 7 messages Jul 29, 2012 – Aug 14, 2012

Subsystems (2)
lore
Share & tools
lore

Axel Lin

author
#0 lore raw

PATCH 1/2 gpio: gpio-ml-ioh: Use spinlock for register access protection

gpio_chip.can_sleep is 0, but current code uses mutex in ioh_gpio_set, ioh_gpio_get and ioh_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

---
 drivers/gpio/gpio-ml-ioh.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/gpio/gpio-ml-ioh.c +10 -10
index db01f15..6a29ee1 100644
@@ -87,8 +87,7 @@ struct ioh_gpio_reg_data {
  * @gpio_use_sel:		Save GPIO_USE_SEL1~4 register for PM
  * @ch:				Indicate GPIO channel
  * @irq_base:		Save base of IRQ number for interrupt
- * @spinlock:		Used for register access protection in
- *				interrupt context ioh_irq_type and PM;
+ * @spinlock:		Used for register access protection
  */
 struct ioh_gpio {
 	void __iomem *base;
@@ -97,7 +96,6 @@ struct ioh_gpio {
 	struct gpio_chip gpio;
 	struct ioh_gpio_reg_data ioh_gpio_reg;
 	u32 gpio_use_sel;
-	struct mutex lock;
 	int ch;
 	int irq_base;
 	spinlock_t spinlock;
@@ -109,8 +107,9 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
 {
 	u32 reg_val;
 	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	reg_val = ioread32(&chip->reg->regs[chip->ch].po);
 	if (val)
 		reg_val |= (1 << nr);
@@ -118,7 +117,7 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
 		reg_val &= ~(1 << nr);
 
 	iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 }
 
 static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
@@ -134,8 +133,9 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
 	u32 pm;
 	u32 reg_val;
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	pm = ioread32(&chip->reg->regs[chip->ch].pm) &
 					((1 << num_ports[chip->ch]) - 1);
 	pm |= (1 << nr);
@@ -148,7 +148,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 		reg_val &= ~(1 << nr);
 	iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
 
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 
 	return 0;
 }
@@ -157,13 +157,14 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
 {
 	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
 	u32 pm;
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	pm = ioread32(&chip->reg->regs[chip->ch].pm) &
 				((1 << num_ports[chip->ch]) - 1);
 	pm &= ~(1 << nr);
 	iowrite32(pm, &chip->reg->regs[chip->ch].pm);
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 
 	return 0;
 }
@@ -447,7 +448,6 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
 		chip->base = base;
 		chip->reg = chip->base;
 		chip->ch = i;
-		mutex_init(&chip->lock);
 		spin_lock_init(&chip->spinlock);
 		ioh_gpio_setup(chip, num_ports[i]);
 		ret = gpiochip_add(&chip->gpio);
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 2/2 gpio: gpio-pch: Use spinlock for register access protection

gpio_chip.can_sleep is 0, but current code uses mutex in pch_gpio_set pch_gpio_get and pch_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

---
 drivers/gpio/gpio-pch.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)
drivers/gpio/gpio-pch.c +10 -12
index 139ad3e..4ad0c4f 100644
@@ -92,9 +92,7 @@ struct pch_gpio_reg_data {
  * @lock:			Used for register access protection
  * @irq_base:		Save base of IRQ number for interrupt
  * @ioh:		IOH ID
- * @spinlock:		Used for register access protection in
- *				interrupt context pch_irq_mask,
- *				pch_irq_unmask and pch_irq_type;
+ * @spinlock:		Used for register access protection
  */
 struct pch_gpio {
 	void __iomem *base;
@@ -102,7 +100,6 @@ struct pch_gpio {
 	struct device *dev;
 	struct gpio_chip gpio;
 	struct pch_gpio_reg_data pch_gpio_reg;
-	struct mutex lock;
 	int irq_base;
 	enum pch_type_t ioh;
 	spinlock_t spinlock;
@@ -112,8 +109,9 @@ static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
 {
 	u32 reg_val;
 	struct pch_gpio *chip =	container_of(gpio, struct pch_gpio, gpio);
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	reg_val = ioread32(&chip->reg->po);
 	if (val)
 		reg_val |= (1 << nr);
@@ -121,7 +119,7 @@ static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
 		reg_val &= ~(1 << nr);
 
 	iowrite32(reg_val, &chip->reg->po);
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 }
 
 static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr)
@@ -137,8 +135,9 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 	struct pch_gpio *chip =	container_of(gpio, struct pch_gpio, gpio);
 	u32 pm;
 	u32 reg_val;
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
 	pm |= (1 << nr);
 	iowrite32(pm, &chip->reg->pm);
@@ -149,8 +148,7 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 	else
 		reg_val &= ~(1 << nr);
 	iowrite32(reg_val, &chip->reg->po);
-
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 
 	return 0;
 }
@@ -159,12 +157,13 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
 {
 	struct pch_gpio *chip =	container_of(gpio, struct pch_gpio, gpio);
 	u32 pm;
+	unsigned long flags;
 
-	mutex_lock(&chip->lock);
+	spin_lock_irqsave(&chip->spinlock, flags);
 	pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
 	pm &= ~(1 << nr);
 	iowrite32(pm, &chip->reg->pm);
-	mutex_unlock(&chip->lock);
+	spin_unlock_irqrestore(&chip->spinlock, flags);
 
 	return 0;
 }
@@ -387,7 +386,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
 
 	chip->reg = chip->base;
 	pci_set_drvdata(pdev, chip);
-	mutex_init(&chip->lock);
 	spin_lock_init(&chip->spinlock);
 	pch_gpio_setup(chip);
 	ret = gpiochip_add(&chip->gpio);
Signature · 1 line
1.7.9.5
#2 lore raw

Re: [PATCH RFT 2/2] gpio: gpio-pch: Use spinlock for register access protection

Quoted 6 lines · Axel Lin

gpio_chip.can_sleep is 0, but current code uses mutex in pch_gpio_set pch_gpio_get and pch_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

Same with this, yell or I'll apply.

Yours,
Linus Walleij

#3 lore raw

Re: [PATCH RFT 2/2] gpio: gpio-pch: Use spinlock for register access protection

In reply to Axel Lin
Quoted 6 lines · Axel Lin

gpio_chip.can_sleep is 0, but current code uses mutex in pch_gpio_set pch_gpio_get and pch_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

Applied to my devel branch for the next merge window...

Yours,
Linus Walleij

#4 lore raw
In reply to Axel Lin
Quoted 6 lines · Axel Lin

gpio_chip.can_sleep is 0, but current code uses mutex in ioh_gpio_set, ioh_gpio_get and ioh_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

So IOH guys what are you saying about this?

If you say nothing I will apply these patches.

Yours,
Linus Walleij

#5 lore raw
Quoted 10 lines · On Mon, 13 Aug 2012 14:01:31 +0200 Linus Walleij <[email protected]>…
Quoted 6 lines · Axel Lin

gpio_chip.can_sleep is 0, but current code uses mutex in ioh_gpio_set, ioh_gpio_get and ioh_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

So IOH guys what are you saying about this?

I'm not the IOH guy, but just happened to work on it for some time :) Anyway, the 2 patches both look good to me.

Thanks,
Feng

#6 lore raw
In reply to Axel Lin
Quoted 6 lines · Axel Lin

gpio_chip.can_sleep is 0, but current code uses mutex in ioh_gpio_set, ioh_gpio_get and ioh_gpio_direction_input functions.
Thus those functions are not callable from interrupt context. This patch converts mutex into spinlock.

Applied to my devel branch for the next merge window, it doesn't seem like a regression to me atleast.

Yours,
Linus Walleij