drivers/irqchip/irq-i8259.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-i8259.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-i8259.c- Extension
.c- Size
- 10192 bytes
- Lines
- 366
- Domain
- Driver Families
- Bucket
- drivers/irqchip
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/init.hlinux/ioport.hlinux/interrupt.hlinux/irqchip.hlinux/irqdomain.hlinux/kernel.hlinux/of_irq.hlinux/spinlock.hlinux/syscore_ops.hlinux/irq.hasm/i8259.hasm/io.h
Detected Declarations
function i8259_set_pollfunction disable_8259A_irqfunction enable_8259A_irqfunction make_8259A_irqfunction i8259A_irq_realfunction thisfunction i8259A_resumefunction i8259A_shutdownfunction init_8259Afunction i8259A_irq_domain_mapfunction __init_i8259_irqsfunction init_i8259_irqsfunction i8259_irq_dispatchfunction i8259_of_init
Annotated Snippet
if (!(spurious_irq_mask & irqmask)) {
printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
spurious_irq_mask |= irqmask;
}
atomic_inc(&irq_err_count);
/*
* Theoretically we do not have to handle this IRQ,
* but in Linux this does not cause problems and is
* simpler for us.
*/
goto handle_real_irq;
}
}
static void i8259A_resume(void *data)
{
if (i8259A_auto_eoi >= 0)
init_8259A(i8259A_auto_eoi);
}
static void i8259A_shutdown(void *data)
{
/* Put the i8259A into a quiescent state that
* the kernel initialization code can get it
* out of.
*/
if (i8259A_auto_eoi >= 0) {
outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
}
}
static const struct syscore_ops i8259_syscore_ops = {
.resume = i8259A_resume,
.shutdown = i8259A_shutdown,
};
static struct syscore i8259_syscore = {
.ops = &i8259_syscore_ops,
};
static void init_8259A(int auto_eoi)
{
unsigned long flags;
i8259A_auto_eoi = auto_eoi;
raw_spin_lock_irqsave(&i8259A_lock, flags);
outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
/*
* outb_p - this has to work on a wide range of PC hardware.
*/
outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */
outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
if (auto_eoi) /* master does Auto EOI */
outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
else /* master expects normal EOI */
outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */
outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */
outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
if (auto_eoi)
/*
* In AEOI mode we just have to mask the interrupt
* when acking.
*/
i8259A_chip.irq_mask_ack = disable_8259A_irq;
else
i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
udelay(100); /* wait for 8259A to initialize */
outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
static struct resource pic1_io_resource = {
.name = "pic1",
.start = PIC_MASTER_CMD,
.end = PIC_MASTER_IMR,
.flags = IORESOURCE_IO | IORESOURCE_BUSY
};
Annotation
- Immediate include surface: `linux/delay.h`, `linux/init.h`, `linux/ioport.h`, `linux/interrupt.h`, `linux/irqchip.h`, `linux/irqdomain.h`, `linux/kernel.h`, `linux/of_irq.h`.
- Detected declarations: `function i8259_set_poll`, `function disable_8259A_irq`, `function enable_8259A_irq`, `function make_8259A_irq`, `function i8259A_irq_real`, `function this`, `function i8259A_resume`, `function i8259A_shutdown`, `function init_8259A`, `function i8259A_irq_domain_map`.
- Atlas domain: Driver Families / drivers/irqchip.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.