mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
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:
parent
8beaf83901
commit
2af1f66753
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user