From 5ae8cf7980858bcd7559034c716ada440e4cb181 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 12 Jun 2013 10:33:17 -0700 Subject: pinctrl: exynos: Add spinlocks to irq_mask and irq_unmask The patch: 1984695 pinctrl: samsung: Protect bank registers with a spinlock ...added spinlocks to protect many accesses. However, the irq_mask and irq_unmask functions still do an unprotected read/modify/write. Add the spinlock there. Signed-off-by: Doug Anderson Acked-by: Tomasz Figa Acked-by: Kukjin Kim Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-exynos.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/pinctrl/pinctrl-exynos.c') diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 2d76f66a2e0b..c29a28ee8d25 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -56,10 +56,15 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd) struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; unsigned long mask; + unsigned long flags; + + spin_lock_irqsave(&bank->slock, flags); mask = readl(d->virt_base + reg_mask); mask &= ~(1 << irqd->hwirq); writel(mask, d->virt_base + reg_mask); + + spin_unlock_irqrestore(&bank->slock, flags); } static void exynos_gpio_irq_mask(struct irq_data *irqd) @@ -68,10 +73,15 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd) struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; unsigned long mask; + unsigned long flags; + + spin_lock_irqsave(&bank->slock, flags); mask = readl(d->virt_base + reg_mask); mask |= 1 << irqd->hwirq; writel(mask, d->virt_base + reg_mask); + + spin_unlock_irqrestore(&bank->slock, flags); } static void exynos_gpio_irq_ack(struct irq_data *irqd) @@ -264,10 +274,15 @@ static void exynos_wkup_irq_unmask(struct irq_data *irqd) struct samsung_pinctrl_drv_data *d = b->drvdata; unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; unsigned long mask; + unsigned long flags; + + spin_lock_irqsave(&b->slock, flags); mask = readl(d->virt_base + reg_mask); mask &= ~(1 << irqd->hwirq); writel(mask, d->virt_base + reg_mask); + + spin_unlock_irqrestore(&b->slock, flags); } static void exynos_wkup_irq_mask(struct irq_data *irqd) @@ -276,10 +291,15 @@ static void exynos_wkup_irq_mask(struct irq_data *irqd) struct samsung_pinctrl_drv_data *d = b->drvdata; unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; unsigned long mask; + unsigned long flags; + + spin_lock_irqsave(&b->slock, flags); mask = readl(d->virt_base + reg_mask); mask |= 1 << irqd->hwirq; writel(mask, d->virt_base + reg_mask); + + spin_unlock_irqrestore(&b->slock, flags); } static void exynos_wkup_irq_ack(struct irq_data *irqd) -- cgit v1.2.3