#define TQMX86_GPIODD 0/* GPIO Data Direction Register */ #define TQMX86_GPIOD 1/* GPIO Data Register */ #define TQMX86_GPIIC 3/* GPI Interrupt Configuration Register */ #define TQMX86_GPIIS 4/* GPI Interrupt Status Register */
/* * NONE, FALLING and RISING use the same bit patterns that can be programmed to * the GPII register (after passing them to the TQMX86_GPII_ macros to shift * them to the right position)
*/ #define TQMX86_INT_TRIG_NONE 0 #define TQMX86_INT_TRIG_FALLING BIT(0) #define TQMX86_INT_TRIG_RISING BIT(1) #define TQMX86_INT_TRIG_BOTH (BIT(0) | BIT(1)) #define TQMX86_INT_TRIG_MASK (BIT(0) | BIT(1)) /* Stored in irq_type with GPII bits */ #define TQMX86_INT_UNMASKED BIT(2)
struct tqmx86_gpio_data { struct gpio_chip chip; void __iomem *io_base; int irq; /* Lock must be held for accessing output and irq_type fields */
raw_spinlock_t spinlock;
DECLARE_BITMAP(output, TQMX86_NGPIO);
u8 irq_type[TQMX86_NGPIO];
};
/* * Edge-both triggers are implemented by flipping the * edge trigger after each interrupt, as the controller * only supports either rising or falling edge triggers, * but not both. * * Internally, the TQMx86 GPIO controller has separate * status registers for rising and falling edge * interrupts. GPIIC configures which bits from which * register are visible in the interrupt status register * GPIIS and defines what triggers the parent IRQ line. * Writing to GPIIS always clears both rising and * falling interrupt flags internally, regardless of the * currently configured trigger. * * In consequence, we can cleanly implement the * edge-both trigger in software by first clearing the * interrupt and then setting the new trigger based on * the current GPIO input in tqmx86_gpio_irq_config() - * even if an edge arrives between reading the input and * setting the trigger, we will have a new interrupt * pending.
*/ if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) ==
TQMX86_INT_TRIG_BOTH)
tqmx86_gpio_irq_config(gpio, hwirq);
}
}
for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
generic_handle_domain_irq(gpio->chip.irq.domain,
i + TQMX86_NGPO);
chained_irq_exit(irq_chip, desc);
}
/* Minimal runtime PM is needed by the IRQ subsystem */ staticint __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
{ return0;
}
/* * Reading the previous output state is not possible with TQMx86 hardware. * Initialize all outputs to 0 to have a defined state that matches the * shadow register.
*/
tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-06-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.