summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5b8d953)
Try to address a race-condition in pinctrl-oxnas.c
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@49043
3c298f89-4303-0410-b956-
a3cf2f4a3e73
#include <linux/pinctrl/pinmux.h>
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
#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"
#include <linux/version.h>
#include "core.h"
void __iomem *regbase; /* GPIOA/B virtual address */
void __iomem *ctrlbase; /* SYS/SEC_CTRL virtual address */
struct irq_domain *domain; /* associated irq domain */
void __iomem *regbase; /* GPIOA/B virtual address */
void __iomem *ctrlbase; /* SYS/SEC_CTRL virtual address */
struct irq_domain *domain; /* associated irq domain */
};
#define to_oxnas_gpio_chip(c) container_of(c, struct oxnas_gpio_chip, chip)
};
#define to_oxnas_gpio_chip(c) container_of(c, struct oxnas_gpio_chip, chip)
void __iomem *pio = oxnas_gpio->regbase;
unsigned mask = 1 << d->hwirq;
unsigned type = irqd_get_trigger_type(d);
void __iomem *pio = oxnas_gpio->regbase;
unsigned mask = 1 << d->hwirq;
unsigned type = irqd_get_trigger_type(d);
- /* 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);
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)
}
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);
void __iomem *pio = oxnas_gpio->regbase;
unsigned mask = 1 << d->hwirq;
unsigned type = irqd_get_trigger_type(d);
+ unsigned long flags;
+
+ if (!(type & IRQ_TYPE_EDGE_BOTH))
+ return;
- /* FIXME: need proper lock */
+ 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);
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);
oxnas_chip->chip = oxnas_gpio_template;
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);
chip = &oxnas_chip->chip;
chip->of_node = np;
chip->label = dev_name(&pdev->dev);