gpio: xilinx: Use better bitmap APIs where appropriate

There are bitmap_gather() and bitmap_scatter() that are factually
simplified version of the APIs used in the driver. Use them where
appropriate.

While at it, replace bitmap_bitremap() with find_nth_bit()
for the sake of simplification.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250205093200.373709-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
Andy Shevchenko 2025-02-05 11:31:10 +02:00 committed by Bartosz Golaszewski
parent 8beaf83901
commit 2af1f66753

View File

@ -45,8 +45,7 @@
* struct xgpio_instance - Stores information about GPIO device
* @gc: GPIO chip
* @regs: register block
* @hw_map: GPIO pin mapping on hardware side
* @sw_map: GPIO pin mapping on software side
* @map: GPIO pin mapping on hardware side
* @state: GPIO write state shadow register
* @last_irq_read: GPIO read state register from last interrupt
* @dir: GPIO direction shadow register
@ -60,8 +59,7 @@
struct xgpio_instance {
struct gpio_chip gc;
void __iomem *regs;
DECLARE_BITMAP(hw_map, 64);
DECLARE_BITMAP(sw_map, 64);
DECLARE_BITMAP(map, 64);
DECLARE_BITMAP(state, 64);
DECLARE_BITMAP(last_irq_read, 64);
DECLARE_BITMAP(dir, 64);
@ -73,16 +71,6 @@ struct xgpio_instance {
struct clk *clk;
};
static inline int xgpio_from_bit(struct xgpio_instance *chip, int bit)
{
return bitmap_bitremap(bit, chip->hw_map, chip->sw_map, 64);
}
static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
{
return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, 64);
}
static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
{
const size_t index = BIT_WORD(bit);
@ -128,7 +116,8 @@ static void xgpio_write_ch(struct xgpio_instance *chip, int reg, int bit, unsign
static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
{
int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
unsigned long lastbit = find_nth_bit(chip->map, 64, chip->gc.ngpio - 1);
int bit;
for (bit = 0; bit <= lastbit ; bit += 32)
xgpio_read_ch(chip, reg, bit, a);
@ -136,7 +125,8 @@ static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned lon
static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
{
int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
unsigned long lastbit = find_nth_bit(chip->map, 64, chip->gc.ngpio - 1);
int bit;
for (bit = 0; bit <= lastbit ; bit += 32)
xgpio_write_ch(chip, reg, bit, a);
@ -156,7 +146,7 @@ static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned lo
static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
{
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);
unsigned long bit = find_nth_bit(chip->map, 64, gpio);
DECLARE_BITMAP(state, 64);
xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, state);
@ -177,7 +167,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);
unsigned long bit = find_nth_bit(chip->map, 64, gpio);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
@ -207,8 +197,8 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
bitmap_scatter(hw_mask, mask, chip->map, 64);
bitmap_scatter(hw_bits, bits, chip->map, 64);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
@ -234,7 +224,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);
unsigned long bit = find_nth_bit(chip->map, 64, gpio);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
@ -263,7 +253,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int bit = xgpio_to_bit(chip, gpio);
unsigned long bit = find_nth_bit(chip->map, 64, gpio);
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
@ -395,7 +385,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
unsigned long flags;
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int bit = xgpio_to_bit(chip, irq_offset);
unsigned long bit = find_nth_bit(chip->map, 64, irq_offset);
u32 mask = BIT(bit / 32), temp;
raw_spin_lock_irqsave(&chip->gpio_lock, flags);
@ -422,7 +412,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
unsigned long flags;
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int bit = xgpio_to_bit(chip, irq_offset);
unsigned long bit = find_nth_bit(chip->map, 64, irq_offset);
u32 old_enable = xgpio_get_value32(chip->enable, bit);
u32 mask = BIT(bit / 32), val;
@ -462,7 +452,7 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
{
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int bit = xgpio_to_bit(chip, irq_offset);
unsigned long bit = find_nth_bit(chip->map, 64, irq_offset);
/*
* The Xilinx GPIO hardware provides a single interrupt status
@ -502,10 +492,10 @@ static void xgpio_irqhandler(struct irq_desc *desc)
struct irq_chip *irqchip = irq_desc_get_chip(desc);
DECLARE_BITMAP(rising, 64);
DECLARE_BITMAP(falling, 64);
DECLARE_BITMAP(all, 64);
DECLARE_BITMAP(hw, 64);
DECLARE_BITMAP(sw, 64);
int irq_offset;
u32 status;
u32 bit;
status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
@ -514,29 +504,28 @@ static void xgpio_irqhandler(struct irq_desc *desc)
raw_spin_lock(&chip->gpio_lock);
xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, hw);
bitmap_complement(rising, chip->last_irq_read, 64);
bitmap_and(rising, rising, all, 64);
bitmap_and(rising, rising, hw, 64);
bitmap_and(rising, rising, chip->enable, 64);
bitmap_and(rising, rising, chip->rising_edge, 64);
bitmap_complement(falling, all, 64);
bitmap_complement(falling, hw, 64);
bitmap_and(falling, falling, chip->last_irq_read, 64);
bitmap_and(falling, falling, chip->enable, 64);
bitmap_and(falling, falling, chip->falling_edge, 64);
bitmap_copy(chip->last_irq_read, all, 64);
bitmap_or(all, rising, falling, 64);
bitmap_copy(chip->last_irq_read, hw, 64);
bitmap_or(hw, rising, falling, 64);
raw_spin_unlock(&chip->gpio_lock);
dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
for_each_set_bit(bit, all, 64) {
irq_offset = xgpio_from_bit(chip, bit);
bitmap_gather(sw, hw, chip->map, 64);
for_each_set_bit(irq_offset, sw, 64)
generic_handle_domain_irq(gc->irq.domain, irq_offset);
}
chained_irq_exit(irqchip, desc);
}
@ -613,17 +602,14 @@ static int xgpio_probe(struct platform_device *pdev)
if (width[1] > 32)
return -EINVAL;
/* Setup software pin mapping */
bitmap_set(chip->sw_map, 0, width[0] + width[1]);
/* Setup hardware pin mapping */
bitmap_set(chip->hw_map, 0, width[0]);
bitmap_set(chip->hw_map, 32, width[1]);
bitmap_set(chip->map, 0, width[0]);
bitmap_set(chip->map, 32, width[1]);
raw_spin_lock_init(&chip->gpio_lock);
chip->gc.base = -1;
chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
chip->gc.ngpio = bitmap_weight(chip->map, 64);
chip->gc.parent = dev;
chip->gc.direction_input = xgpio_dir_in;
chip->gc.direction_output = xgpio_dir_out;