oxnas: add spinlock in pinctrl driver
Try to address a race-condition in pinctrl-oxnas.c Signed-off-by: Daniel Golle <daniel@makrotopia.org> SVN-Revision: 49043
This commit is contained in:
parent
daf7ab04ba
commit
b64f159bc8
1 changed files with 16 additions and 2 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <linux/pinctrl/pinmux.h>
|
||||
/* Since we request GPIOs from ourself */
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "core.h"
|
||||
|
@ -41,6 +42,7 @@ struct oxnas_gpio_chip {
|
|||
void __iomem *regbase; /* GPIOA/B virtual address */
|
||||
void __iomem *ctrlbase; /* SYS/SEC_CTRL virtual address */
|
||||
struct irq_domain *domain; /* associated irq domain */
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
#define to_oxnas_gpio_chip(c) container_of(c, struct oxnas_gpio_chip, chip)
|
||||
|
@ -1145,12 +1147,17 @@ static void gpio_irq_mask(struct irq_data *d)
|
|||
void __iomem *pio = oxnas_gpio->regbase;
|
||||
unsigned mask = 1 << d->hwirq;
|
||||
unsigned type = irqd_get_trigger_type(d);
|
||||
unsigned long flags;
|
||||
|
||||
/* FIXME: need proper lock */
|
||||
if (!(type & IRQ_TYPE_EDGE_BOTH))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&oxnas_gpio->lock, flags);
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
oxnas_register_clear_mask(pio + RE_IRQ_ENABLE, mask);
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
oxnas_register_clear_mask(pio + FE_IRQ_ENABLE, mask);
|
||||
spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
|
||||
}
|
||||
|
||||
static void gpio_irq_unmask(struct irq_data *d)
|
||||
|
@ -1159,12 +1166,17 @@ static void gpio_irq_unmask(struct irq_data *d)
|
|||
void __iomem *pio = oxnas_gpio->regbase;
|
||||
unsigned mask = 1 << d->hwirq;
|
||||
unsigned type = irqd_get_trigger_type(d);
|
||||
unsigned long flags;
|
||||
|
||||
/* FIXME: need proper lock */
|
||||
if (!(type & IRQ_TYPE_EDGE_BOTH))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&oxnas_gpio->lock, flags);
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
oxnas_register_set_mask(pio + RE_IRQ_ENABLE, mask);
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
oxnas_register_set_mask(pio + FE_IRQ_ENABLE, mask);
|
||||
spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1359,6 +1371,8 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
oxnas_chip->chip = oxnas_gpio_template;
|
||||
|
||||
spin_lock_init(&oxnas_chip->lock);
|
||||
|
||||
chip = &oxnas_chip->chip;
|
||||
chip->of_node = np;
|
||||
chip->label = dev_name(&pdev->dev);
|
||||
|
|
Loading…
Reference in a new issue