pinctrl: intel: Protect set wake flow by spin lock
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Fri, 8 Jul 2016 11:30:46 +0000 (14:30 +0300)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 11 Jul 2016 09:15:33 +0000 (11:15 +0200)
It seems intel_gpio_irq_wake() misses lock protection against I/O flow.
Use spin lock here as well.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/intel/pinctrl-intel.c

index fe19b1e..257cab1 100644 (file)
@@ -796,12 +796,15 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
        const struct intel_community *community;
        unsigned pin = irqd_to_hwirq(d);
        unsigned padno, gpp, gpp_offset;
+       unsigned long flags;
        u32 gpe_en;
 
        community = intel_get_community(pctrl, pin);
        if (!community)
                return -EINVAL;
 
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+
        padno = pin_to_padno(community, pin);
        gpp = padno / community->gpp_size;
        gpp_offset = padno % community->gpp_size;
@@ -821,6 +824,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
                gpe_en &= ~BIT(gpp_offset);
        writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
 
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
        dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
        return 0;
 }