Skip to content

Commit

Permalink
gpio: xilinx: use raw_spinlock
Browse files Browse the repository at this point in the history
The IRQ core holds a raw spinlock when calling into the driver callbacks,
which leads to the following warning:

[    5.127179] =============================
[    5.131218] [ BUG: Invalid wait context ]
[    5.135255] 6.5.10-xilinx-00026-g692b34c40d2f-dirty torvalds#482 Not tainted
[    5.141653] -----------------------------
[    5.145695] swapper/0/1 is trying to lock:
[    5.149827] c18ecd78 (&chip->gpio_lock){....}-{3:3}, at: xgpio_irq_unmask+0x50/0xd4
[    5.157602] other info that might help us debug this:
[    5.162687] context-{5:5}
[    5.165331] 3 locks held by swapper/0/1:
[    5.169287]  #0: c1b6ec84 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xd8/0xf8
[    5.176984]  #1: c1903364 (request_class){+.+.}-{4:4}, at: __setup_irq+0x20c/0x6dc
[    5.184673]  #2: c190327c (lock_class#2){....}-{2:2}, at: __setup_irq+0x2cc/0x6dc

Fix this by using a raw spinlock in the gpio-xilinx driver as well.

Signed-off-by: Daniel Mack <[email protected]>
  • Loading branch information
zonque committed Nov 7, 2023
1 parent 6cd7623 commit 8e48f34
Showing 1 changed file with 16 additions and 16 deletions.
32 changes: 16 additions & 16 deletions drivers/gpio/gpio-xilinx.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct xgpio_instance {
DECLARE_BITMAP(state, 64);
DECLARE_BITMAP(last_irq_read, 64);
DECLARE_BITMAP(dir, 64);
spinlock_t gpio_lock; /* For serializing operations */
raw_spinlock_t gpio_lock; /* For serializing operations */
int irq;
DECLARE_BITMAP(enable, 64);
DECLARE_BITMAP(rising_edge, 64);
Expand Down Expand Up @@ -180,14 +180,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

/* Write to GPIO signal and set its direction to output */
__assign_bit(bit, chip->state, val);

xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);

spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
}

/**
Expand All @@ -211,15 +211,15 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);

xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);

bitmap_copy(chip->state, state, 64);

spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
}

/**
Expand All @@ -237,13 +237,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

/* Set the GPIO bit in shadow register and set direction as input */
__set_bit(bit, chip->dir);
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);

spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);

return 0;
}
Expand All @@ -266,7 +266,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

/* Write state of GPIO signal */
__assign_bit(bit, chip->state, val);
Expand All @@ -276,7 +276,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
__clear_bit(bit, chip->dir);
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);

spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);

return 0;
}
Expand Down Expand Up @@ -404,7 +404,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
int bit = xgpio_to_bit(chip, irq_offset);
u32 mask = BIT(bit / 32), temp;

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

__clear_bit(bit, chip->enable);

Expand All @@ -414,7 +414,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
temp &= ~mask;
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
}
spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);

gpiochip_disable_irq(&chip->gc, irq_offset);
}
Expand All @@ -434,7 +434,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)

gpiochip_enable_irq(&chip->gc, irq_offset);

spin_lock_irqsave(&chip->gpio_lock, flags);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);

__set_bit(bit, chip->enable);

Expand All @@ -453,7 +453,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
}

spin_unlock_irqrestore(&chip->gpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
}

/**
Expand Down Expand Up @@ -518,7 +518,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)

chained_irq_enter(irqchip, desc);

spin_lock(&chip->gpio_lock);
raw_spin_lock(&chip->gpio_lock);

xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);

Expand All @@ -535,7 +535,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
bitmap_copy(chip->last_irq_read, all, 64);
bitmap_or(all, rising, falling, 64);

spin_unlock(&chip->gpio_lock);
raw_spin_unlock(&chip->gpio_lock);

dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);

Expand Down Expand Up @@ -626,7 +626,7 @@ static int xgpio_probe(struct platform_device *pdev)
bitmap_set(chip->hw_map, 0, width[0]);
bitmap_set(chip->hw_map, 32, width[1]);

spin_lock_init(&chip->gpio_lock);
raw_spin_lock_init(&chip->gpio_lock);

chip->gc.base = -1;
chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
Expand Down

0 comments on commit 8e48f34

Please sign in to comment.