drivers/irqchip/irq-loongson-eiointc.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-loongson-eiointc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-loongson-eiointc.c- Extension
.c- Size
- 17545 bytes
- Lines
- 681
- 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.
- 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/cpuhotplug.hlinux/interrupt.hlinux/irq.hlinux/irqchip.hlinux/irqdomain.hlinux/irqchip/chained_irq.hlinux/kernel.hlinux/kvm_para.hlinux/syscore_ops.hasm/numa.hirq-loongson.h
Detected Declarations
struct eiointc_privstruct eiointc_ip_routestruct eiointc_privfunction eiointc_enablefunction cpu_to_eio_nodefunction eiointc_set_irq_routefunction for_each_online_cpufunction veiointc_set_irq_routefunction eiointc_set_irq_affinityfunction eiointc_indexfunction eiointc_router_initfunction read_isrfunction write_isrfunction read_isrfunction write_isrfunction eiointc_irq_dispatchfunction eiointc_ack_irqfunction eiointc_domain_allocfunction eiointc_domain_freefunction acpi_set_vec_parentfunction eiointc_suspendfunction eiointc_resumefunction pch_pic_parse_madtfunction pch_msi_parse_madtfunction acpi_cascade_irqdomain_initfunction eiointc_initfunction eiointc_acpi_initfunction eiointc_of_init
Annotated Snippet
struct eiointc_ip_route {
struct eiointc_priv *priv;
/* Offset Routed destination IP */
int start;
int end;
};
struct eiointc_priv {
u32 node;
u32 vec_count;
nodemask_t node_map;
cpumask_t cpuspan_map;
struct fwnode_handle *domain_handle;
struct irq_domain *eiointc_domain;
int flags;
irq_hw_number_t parent_hwirq;
struct eiointc_ip_route route_info[VEC_REG_COUNT];
};
static struct eiointc_priv *eiointc_priv[MAX_IO_PICS];
static void eiointc_enable(void)
{
#ifdef CONFIG_MACH_LOONGSON64
uint64_t misc;
misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
#endif
}
static int cpu_to_eio_node(int cpu)
{
if (!kvm_para_has_feature(KVM_FEATURE_VIRT_EXTIOI))
return cpu_logical_map(cpu) / CORES_PER_EIO_NODE;
else
return cpu_logical_map(cpu) / CORES_PER_VEIO_NODE;
}
#ifdef CONFIG_SMP
static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode, nodemask_t *node_map)
{
int i, node, cpu_node, route_node;
unsigned char coremap;
uint32_t pos_off, data, data_byte, data_mask;
pos_off = pos & ~3;
data_byte = pos & 3;
data_mask = ~BIT_MASK(data_byte) & 0xf;
/* Calculate node and coremap of target irq */
cpu_node = cpu_logical_map(cpu) / CORES_PER_EIO_NODE;
coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE);
for_each_online_cpu(i) {
node = cpu_to_eio_node(i);
if (!node_isset(node, *node_map))
continue;
/* EIO node 0 is in charge of inter-node interrupt dispatch */
route_node = (node == mnode) ? cpu_node : node;
data = ((coremap | (route_node << 4)) << (data_byte * 8));
csr_any_send(EIOINTC_REG_ROUTE + pos_off, data, data_mask, node * CORES_PER_EIO_NODE);
}
}
static void veiointc_set_irq_route(unsigned int vector, unsigned int cpu)
{
unsigned long reg = EIOINTC_REG_ROUTE_VEC(vector);
unsigned int data;
data = iocsr_read32(reg);
data &= ~EIOINTC_REG_ROUTE_VEC_MASK(vector);
data |= cpu_logical_map(cpu) << EIOINTC_REG_ROUTE_VEC_SHIFT(vector);
iocsr_write32(data, reg);
}
static DEFINE_RAW_SPINLOCK(affinity_lock);
static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, bool force)
{
unsigned int cpu;
unsigned long flags;
uint32_t vector, regaddr;
struct eiointc_priv *priv = d->domain->host_data;
raw_spin_lock_irqsave(&affinity_lock, flags);
cpu = cpumask_first_and_and(&priv->cpuspan_map, affinity, cpu_online_mask);
Annotation
- Immediate include surface: `linux/cpuhotplug.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/irqchip.h`, `linux/irqdomain.h`, `linux/irqchip/chained_irq.h`, `linux/kernel.h`, `linux/kvm_para.h`.
- Detected declarations: `struct eiointc_priv`, `struct eiointc_ip_route`, `struct eiointc_priv`, `function eiointc_enable`, `function cpu_to_eio_node`, `function eiointc_set_irq_route`, `function for_each_online_cpu`, `function veiointc_set_irq_route`, `function eiointc_set_irq_affinity`, `function eiointc_index`.
- 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.