Skip to content

Commit

Permalink
gpio: tqmx86: consistently refer to IRQs by hwirq numbers
Browse files Browse the repository at this point in the history
On currently supported variants of the TQMx86 GPIO controller, only
GPIOs 4-7 have IRQ support; in the interrupt status and config
registers, position 0 therefore corresponds to GPIO 4, position 1 to
GPIO 5, etc. This was made even more confusing by sometimes using the
term "offset" to refer to GPIO numbers (which are equavalent to hwirq
numbers), and sometimes to bit positions in the hardware registers.

With this change, the whole driver consistently uses hwirq numbers (==
GPIO numbers) when referring to the IRQs, and only the two pieces of
code that interact with the hardware registers (tqmx86_gpio_irq_config()
and tqmx86_gpio_irq_handler()) deal with bit positions. Space for hwirq
numbers 0-3 is reserved in the irq_type array, but remains unused for
existing (COM Express) TQMx86 variants; support for TQMx86 variants that
support IRQs on all GPIO lines will be added in the future.

No functional change intended.

Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Link: https://lore.kernel.org/r/94b78f4a9500bb71e66c0f7d3b084fec5cfe42ca.1734001247.git.matthias.schiffer@ew.tq-group.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
  • Loading branch information
Matthias Schiffer authored and Bartosz Golaszewski committed Dec 16, 2024
1 parent 2a485c8 commit 0ccf314
Showing 1 changed file with 20 additions and 20 deletions.
40 changes: 20 additions & 20 deletions drivers/gpio/gpio-tqmx86.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct tqmx86_gpio_data {
/* Lock must be held for accessing output and irq_type fields */
raw_spinlock_t spinlock;
DECLARE_BITMAP(output, TQMX86_NGPIO);
u8 irq_type[TQMX86_NGPI];
u8 irq_type[TQMX86_NGPIO];
};

static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
Expand Down Expand Up @@ -116,61 +116,59 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
return GPIO_LINE_DIRECTION_OUT;
}

static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq)
__must_hold(&gpio->spinlock)
{
u8 type = TQMX86_INT_TRIG_NONE, gpiic;
int gpiic_irq = hwirq - TQMX86_NGPO;

if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {
type = gpio->irq_type[offset] & TQMX86_INT_TRIG_MASK;
if (gpio->irq_type[hwirq] & TQMX86_INT_UNMASKED) {
type = gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK;

if (type == TQMX86_INT_TRIG_BOTH)
type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)
type = tqmx86_gpio_get(&gpio->chip, hwirq)
? TQMX86_INT_TRIG_FALLING
: TQMX86_INT_TRIG_RISING;
}

gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
gpiic &= ~TQMX86_GPIIC_MASK(offset);
gpiic |= TQMX86_GPIIC_CONFIG(offset, type);
gpiic &= ~TQMX86_GPIIC_MASK(gpiic_irq);
gpiic |= TQMX86_GPIIC_CONFIG(gpiic_irq, type);
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
}

static void tqmx86_gpio_irq_mask(struct irq_data *data)
{
unsigned int offset = (data->hwirq - TQMX86_NGPO);
struct tqmx86_gpio_data *gpio = gpiochip_get_data(
irq_data_get_irq_chip_data(data));
unsigned long flags;

raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
tqmx86_gpio_irq_config(gpio, offset);
gpio->irq_type[data->hwirq] &= ~TQMX86_INT_UNMASKED;
tqmx86_gpio_irq_config(gpio, data->hwirq);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);

gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
}

static void tqmx86_gpio_irq_unmask(struct irq_data *data)
{
unsigned int offset = (data->hwirq - TQMX86_NGPO);
struct tqmx86_gpio_data *gpio = gpiochip_get_data(
irq_data_get_irq_chip_data(data));
unsigned long flags;

gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));

raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
tqmx86_gpio_irq_config(gpio, offset);
gpio->irq_type[data->hwirq] |= TQMX86_INT_UNMASKED;
tqmx86_gpio_irq_config(gpio, data->hwirq);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
}

static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{
struct tqmx86_gpio_data *gpio = gpiochip_get_data(
irq_data_get_irq_chip_data(data));
unsigned int offset = (data->hwirq - TQMX86_NGPO);
unsigned int edge_type = type & IRQF_TRIGGER_MASK;
unsigned long flags;
u8 new_type;
Expand All @@ -190,9 +188,9 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
}

raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpio->irq_type[offset] &= ~TQMX86_INT_TRIG_MASK;
gpio->irq_type[offset] |= new_type;
tqmx86_gpio_irq_config(gpio, offset);
gpio->irq_type[data->hwirq] &= ~TQMX86_INT_TRIG_MASK;
gpio->irq_type[data->hwirq] |= new_type;
tqmx86_gpio_irq_config(gpio, data->hwirq);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);

return 0;
Expand All @@ -204,7 +202,7 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
unsigned long irq_bits, flags;
int i;
int i, hwirq;
u8 irq_status;

chained_irq_enter(irq_chip, desc);
Expand All @@ -216,6 +214,8 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)

raw_spin_lock_irqsave(&gpio->spinlock, flags);
for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
hwirq = i + TQMX86_NGPO;

/*
* Edge-both triggers are implemented by flipping the edge
* trigger after each interrupt, as the controller only supports
Expand All @@ -236,8 +236,8 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
* reading the input and setting the trigger, we will have a new
* interrupt pending.
*/
if ((gpio->irq_type[i] & TQMX86_INT_TRIG_MASK) == TQMX86_INT_TRIG_BOTH)
tqmx86_gpio_irq_config(gpio, i);
if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) == TQMX86_INT_TRIG_BOTH)
tqmx86_gpio_irq_config(gpio, hwirq);
}
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);

Expand Down

0 comments on commit 0ccf314

Please sign in to comment.