drivers/irqchip/irq-riscv-imsic-state.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-riscv-imsic-state.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-riscv-imsic-state.c- Extension
.c- Size
- 25500 bytes
- Lines
- 969
- Domain
- Driver Families
- Bucket
- drivers/irqchip
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/acpi.hlinux/cpu.hlinux/bitmap.hlinux/interrupt.hlinux/irq.hlinux/module.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/seq_file.hlinux/spinlock.hlinux/smp.hasm/hwcap.hirq-riscv-imsic-state.h
Detected Declarations
function Copyrightfunction imsic_csr_readfunction imsic_csr_read_clearfunction imsic_csr_setfunction imsic_csr_clearfunction __imsic_eix_read_clearfunction __imsic_id_read_clear_enabledfunction __imsic_id_read_clear_pendingfunction __imsic_eix_updatefunction __imsic_local_syncfunction for_each_set_bitfunction __imsic_local_timer_startfunction __imsic_local_timer_startfunction imsic_local_deliveryfunction imsic_local_timer_callbackfunction __imsic_remote_syncfunction imsic_starting_cpufunction __imsic_remote_syncfunction imsic_vector_maskfunction imsic_vector_unmaskfunction imsic_vector_force_move_cleanupfunction imsic_vector_move_updatefunction imsic_vector_movefunction imsic_vector_debug_showfunction imsic_vector_debug_show_summaryfunction imsic_vector_freefunction imsic_local_cleanupfunction for_each_possible_cpufunction imsic_local_initfunction imsic_state_onlinefunction imsic_state_offlinefunction imsic_matrix_initfunction imsic_populate_global_dtfunction imsic_populate_global_acpifunction imsic_get_parent_hartidfunction imsic_get_mmio_resourcefunction imsic_parse_fwnodefunction imsic_setup_stateexport imsic_get_global_config
Annotated Snippet
if (mvec) {
/*
* If the old vector has not been updated then
* try again in the next sync-up call.
*/
if (READ_ONCE(mvec->move_next)) {
ret = false;
continue;
}
WRITE_ONCE(vec->move_prev, NULL);
}
/*
* If a vector was being moved to a new vector on some other
* CPU then we can get a MSI during the movement so check the
* ID pending bit and re-trigger the new ID on other CPU using
* MMIO write.
*/
mvec = READ_ONCE(vec->move_next);
if (mvec) {
/*
* Devices having non-atomic MSI update might see
* an intermediate state so check both old ID and
* new ID for pending interrupts.
*
* For details, see imsic_irq_set_affinity().
*/
tvec = vec->local_id == mvec->local_id ?
NULL : &lpriv->vectors[mvec->local_id];
if (tvec && !irq_can_move_in_process_context(irq_get_irq_data(vec->irq)) &&
__imsic_id_read_clear_pending(tvec->local_id)) {
/* Retrigger temporary vector if it was already in-use */
if (READ_ONCE(tvec->enable)) {
tlocal = per_cpu_ptr(imsic->global.local, tvec->cpu);
writel_relaxed(tvec->local_id, tlocal->msi_va);
}
mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
writel_relaxed(mvec->local_id, mlocal->msi_va);
}
if (__imsic_id_read_clear_pending(vec->local_id)) {
mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
writel_relaxed(mvec->local_id, mlocal->msi_va);
}
WRITE_ONCE(vec->move_next, NULL);
imsic_vector_free(vec);
}
skip:
bitmap_clear(lpriv->dirty_bitmap, i, 1);
}
return ret;
}
#ifdef CONFIG_SMP
static void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
lockdep_assert_held(&lpriv->lock);
if (!timer_pending(&lpriv->timer)) {
lpriv->timer.expires = jiffies + 1;
add_timer_on(&lpriv->timer, cpu);
}
}
#else
static inline void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
}
#endif
void imsic_local_sync_all(bool force_all)
{
struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
unsigned long flags;
raw_spin_lock_irqsave(&lpriv->lock, flags);
if (force_all)
bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
if (!__imsic_local_sync(lpriv))
__imsic_local_timer_start(lpriv, smp_processor_id());
raw_spin_unlock_irqrestore(&lpriv->lock, flags);
}
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/cpu.h`, `linux/bitmap.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`.
- Detected declarations: `function Copyright`, `function imsic_csr_read`, `function imsic_csr_read_clear`, `function imsic_csr_set`, `function imsic_csr_clear`, `function __imsic_eix_read_clear`, `function __imsic_id_read_clear_enabled`, `function __imsic_id_read_clear_pending`, `function __imsic_eix_update`, `function __imsic_local_sync`.
- Atlas domain: Driver Families / drivers/irqchip.
- Implementation status: integration 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.