]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
gpio: aspeed-sgpio: Convert aspeed_sgpio.lock to raw_spinlock
authorIwona Winiarska <iwona.winiarska@intel.com>
Sat, 4 Dec 2021 17:10:27 +0000 (18:10 +0100)
committerPaolo Pisati <paolo.pisati@canonical.com>
Fri, 28 Jan 2022 10:02:33 +0000 (11:02 +0100)
BugLink: https://bugs.launchpad.net/bugs/1959376
[ Upstream commit ab39d6988dd53f354130438d8afa5596a2440fed ]

The gpio-aspeed-sgpio driver implements an irq_chip which need to be
invoked from hardirq context. Since spin_lock() can sleep with
PREEMPT_RT, it is no longer legal to invoke it while interrupts are
disabled.
This also causes lockdep to complain about:
[   25.919465] [ BUG: Invalid wait context ]
because aspeed_sgpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/gpio/gpio-aspeed-sgpio.c

index b3a9b8488f11de696f0e00e42d7620c09b343c13..454cefbeecf0e798f0b4c11261a12db67f53a0ae 100644 (file)
@@ -31,7 +31,7 @@ struct aspeed_sgpio {
        struct gpio_chip chip;
        struct irq_chip intc;
        struct clk *pclk;
-       spinlock_t lock;
+       raw_spinlock_t lock;
        void __iomem *base;
        int irq;
 };
@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
        enum aspeed_sgpio_reg reg;
        int rc = 0;
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata;
        rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
        return rc;
 }
@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
        struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
        unsigned long flags;
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        sgpio_set_value(gc, offset, val);
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v
        /* No special action is required for setting the direction; we'll
         * error-out in sgpio_set_value if this isn't an output GPIO */
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
        rc = sgpio_set_value(gc, offset, val);
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
        return rc;
 }
@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d)
 
        status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        iowrite32(bit, status_addr);
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
        irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
        addr = bank_reg(gpio, bank, reg_irq_enable);
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        reg = ioread32(addr);
        if (set)
@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
 
        iowrite32(reg, addr);
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_mask(struct irq_data *d)
@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        addr = bank_reg(gpio, bank, reg_irq_type0);
        reg = ioread32(addr);
@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
        reg = (reg & ~bit) | type2;
        iowrite32(reg, addr);
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
        irq_set_handler_locked(d, handler);
 
@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
        reg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-       spin_lock_irqsave(&gpio->lock, flags);
+       raw_spin_lock_irqsave(&gpio->lock, flags);
 
        val = readl(reg);
 
@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
        writel(val, reg);
 
-       spin_unlock_irqrestore(&gpio->lock, flags);
+       raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
        return 0;
 }
@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev)
        iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval |
                  ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL);
 
-       spin_lock_init(&gpio->lock);
+       raw_spin_lock_init(&gpio->lock);
 
        gpio->chip.parent = &pdev->dev;
        gpio->chip.ngpio = nr_gpios * 2;