irqchip: fix WARNNING of lockdep [1/1]
authorQianggui Song <qianggui.song@amlogic.com>
Fri, 27 Sep 2019 06:20:30 +0000 (14:20 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 18 Oct 2019 11:11:50 +0000 (04:11 -0700)
PD#SWPL-14700

Problem:
When open lockdep there is a warnning:
WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected

Solution:
use hardirq-safe lock to protect critical sections

Verify:
g12a

Change-Id: Icd7550efcdefb5589d248b862b77919db8581484
Signed-off-by: Qianggui Song <qianggui.song@amlogic.com>
drivers/amlogic/irqchip/irq-meson-gpio.c

index 507f81c..e273570 100644 (file)
@@ -141,13 +141,14 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
                               u32 **channel_hwirq)
 {
        unsigned int reg, idx;
+       unsigned long flags;
 
-       spin_lock(&ctl->lock);
+       spin_lock_irqsave(&ctl->lock, flags);
 
        /* Find a free channel */
        idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
        if (idx >= NUM_CHANNEL) {
-               spin_unlock(&ctl->lock);
+               spin_unlock_irqrestore(&ctl->lock, flags);
                pr_debug("No channel available\n");
                return -ENOSPC;
        }
@@ -172,7 +173,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
         */
        *channel_hwirq = &(ctl->channel_irqs[idx]);
 
-       spin_unlock(&ctl->lock);
+       spin_unlock_irqrestore(&ctl->lock, flags);
 
        pr_debug("hwirq %lu assigned to channel %d - irq %u\n",
                 hwirq, idx, **channel_hwirq);
@@ -203,6 +204,7 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
 {
        u32 val = 0;
        unsigned int idx;
+       unsigned long flags;
 
        idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
 
@@ -219,10 +221,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
                if (!ctl->support_double_edge)
                        return -EINVAL;
                val |= REG_EDGE_BOTH_EDGE(idx);
-               spin_lock(&ctl->lock);
+               spin_lock_irqsave(&ctl->lock, flags);
                meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
                                   REG_EDGE_BOTH_EDGE(idx), val);
-               spin_unlock(&ctl->lock);
+               spin_unlock_irqrestore(&ctl->lock, flags);
                return 0;
        }
 
@@ -232,7 +234,7 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
                val |= REG_EDGE_POL_LOW(idx);
 
-       spin_lock(&ctl->lock);
+       spin_lock_irqsave(&ctl->lock, flags);
 
        /* Double-edge has priority over all others. If a double-edge gpio
         * changes to another method's, we need to reset the corresponding bit
@@ -245,7 +247,7 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
        meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
                                   REG_EDGE_POL_MASK(idx), val);
 
-       spin_unlock(&ctl->lock);
+       spin_unlock_irqrestore(&ctl->lock, flags);
 
        return 0;
 }