drivers/gpio/gpio-mlxbf3.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-mlxbf3.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-mlxbf3.c- Extension
.c- Size
- 8174 bytes
- Lines
- 292
- Domain
- Driver Families
- Bucket
- drivers/gpio
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/bitops.hlinux/device.hlinux/err.hlinux/gpio/driver.hlinux/gpio/generic.hlinux/interrupt.hlinux/io.hlinux/module.hlinux/platform_device.hlinux/spinlock.hlinux/types.h
Detected Declarations
struct mlxbf3_gpio_contextfunction mlxbf3_gpio_irq_enablefunction mlxbf3_gpio_irq_disablefunction scoped_guardfunction mlxbf3_gpio_irq_handlerfunction mlxbf3_gpio_irq_set_typefunction scoped_guardfunction mlxbf3_gpio_irq_ackfunction mlxbf3_gpio_add_pin_rangesfunction mlxbf3_gpio_probefunction mlxbf3_gpio_shutdown
Annotated Snippet
struct mlxbf3_gpio_context {
struct gpio_generic_chip chip;
/* YU GPIO block address */
void __iomem *gpio_set_io;
void __iomem *gpio_clr_io;
void __iomem *gpio_io;
/* YU GPIO cause block address */
void __iomem *gpio_cause_io;
};
static void mlxbf3_gpio_irq_enable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
irq_hw_number_t offset = irqd_to_hwirq(irqd);
u32 val;
gpiochip_enable_irq(gc, offset);
guard(gpio_generic_lock_irqsave)(&gs->chip);
writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
val |= BIT(offset);
writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
}
static void mlxbf3_gpio_irq_disable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
irq_hw_number_t offset = irqd_to_hwirq(irqd);
u32 val;
scoped_guard(gpio_generic_lock_irqsave, &gs->chip) {
val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
val &= ~BIT(offset);
writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
}
gpiochip_disable_irq(gc, offset);
}
static irqreturn_t mlxbf3_gpio_irq_handler(int irq, void *ptr)
{
struct mlxbf3_gpio_context *gs = ptr;
struct gpio_chip *gc = &gs->chip.gc;
unsigned long pending;
u32 level;
pending = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0);
writel(pending, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
for_each_set_bit(level, &pending, gc->ngpio)
generic_handle_domain_irq(gc->irq.domain, level);
return IRQ_RETVAL(pending);
}
static int
mlxbf3_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
irq_hw_number_t offset = irqd_to_hwirq(irqd);
u32 val;
scoped_guard(gpio_generic_lock_irqsave, &gs->chip) {
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_BOTH:
val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
val |= BIT(offset);
writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
val |= BIT(offset);
writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
break;
case IRQ_TYPE_EDGE_RISING:
val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
val |= BIT(offset);
writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
break;
case IRQ_TYPE_EDGE_FALLING:
val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
val |= BIT(offset);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bitops.h`, `linux/device.h`, `linux/err.h`, `linux/gpio/driver.h`, `linux/gpio/generic.h`, `linux/interrupt.h`, `linux/io.h`.
- Detected declarations: `struct mlxbf3_gpio_context`, `function mlxbf3_gpio_irq_enable`, `function mlxbf3_gpio_irq_disable`, `function scoped_guard`, `function mlxbf3_gpio_irq_handler`, `function mlxbf3_gpio_irq_set_type`, `function scoped_guard`, `function mlxbf3_gpio_irq_ack`, `function mlxbf3_gpio_add_pin_ranges`, `function mlxbf3_gpio_probe`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.