drivers/soc/ixp4xx/ixp4xx-qmgr.c
Source file repositories/reference/linux-study-clean/drivers/soc/ixp4xx/ixp4xx-qmgr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/soc/ixp4xx/ixp4xx-qmgr.c- Extension
.c- Size
- 11972 bytes
- Lines
- 488
- Domain
- Driver Families
- Bucket
- drivers/soc
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/ioport.hlinux/interrupt.hlinux/kernel.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/soc/ixp4xx/qmgr.hlinux/soc/ixp4xx/cpu.h
Detected Declarations
function qmgr_put_entryfunction qmgr_get_entryfunction __qmgr_get_stat1function __qmgr_get_stat2function qmgr_stat_emptyfunction qmgr_stat_below_low_watermarkfunction qmgr_stat_fullfunction qmgr_stat_overflowfunction qmgr_set_irqfunction qmgr_irq1_a0function qmgr_irq2_a0function qmgr_irqfunction qmgr_enable_irqfunction qmgr_disable_irqfunction shift_maskfunction qmgr_release_queuefunction ixp4xx_qmgr_probefunction ixp4xx_qmgr_removeexport qmgr_put_entryexport qmgr_get_entryexport qmgr_stat_emptyexport qmgr_stat_below_low_watermarkexport qmgr_stat_fullexport qmgr_stat_overflowexport qmgr_set_irqexport qmgr_enable_irqexport qmgr_disable_irqexport qmgr_queue_descsexport qmgr_request_queueexport __qmgr_request_queueexport qmgr_release_queue
Annotated Snippet
if (stat & BIT(src & 3)) {
irq_handlers[i](irq_pdevs[i]);
ret = IRQ_HANDLED;
}
}
return ret;
}
static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
{
int i, ret = 0;
u32 req_bitmap;
/* ACK - it may clear any bits so don't rely on it */
__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]);
req_bitmap = __raw_readl(&qmgr_regs->irqen[1]) &
__raw_readl(&qmgr_regs->statne_h);
while (req_bitmap) {
i = __fls(req_bitmap); /* number of the last "high" queue */
req_bitmap &= ~BIT(i);
irq_handlers[HALF_QUEUES + i](irq_pdevs[HALF_QUEUES + i]);
ret = IRQ_HANDLED;
}
return ret;
}
static irqreturn_t qmgr_irq(int irq, void *pdev)
{
int i, half = (irq == qmgr_irq_1 ? 0 : 1);
u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
if (!req_bitmap)
return 0;
__raw_writel(req_bitmap, &qmgr_regs->irqstat[half]); /* ACK */
while (req_bitmap) {
i = __fls(req_bitmap); /* number of the last queue */
req_bitmap &= ~BIT(i);
i += half * HALF_QUEUES;
irq_handlers[i](irq_pdevs[i]);
}
return IRQ_HANDLED;
}
void qmgr_enable_irq(unsigned int queue)
{
unsigned long flags;
int half = queue / 32;
u32 mask = 1 << (queue & (HALF_QUEUES - 1));
spin_lock_irqsave(&qmgr_lock, flags);
__raw_writel(__raw_readl(&qmgr_regs->irqen[half]) | mask,
&qmgr_regs->irqen[half]);
spin_unlock_irqrestore(&qmgr_lock, flags);
}
void qmgr_disable_irq(unsigned int queue)
{
unsigned long flags;
int half = queue / 32;
u32 mask = 1 << (queue & (HALF_QUEUES - 1));
spin_lock_irqsave(&qmgr_lock, flags);
__raw_writel(__raw_readl(&qmgr_regs->irqen[half]) & ~mask,
&qmgr_regs->irqen[half]);
__raw_writel(mask, &qmgr_regs->irqstat[half]); /* clear */
spin_unlock_irqrestore(&qmgr_lock, flags);
}
static inline void shift_mask(u32 *mask)
{
mask[3] = mask[3] << 1 | mask[2] >> 31;
mask[2] = mask[2] << 1 | mask[1] >> 31;
mask[1] = mask[1] << 1 | mask[0] >> 31;
mask[0] <<= 1;
}
#if DEBUG_QMGR
int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark,
const char *desc_format, const char* name)
#else
int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark)
Annotation
- Immediate include surface: `linux/ioport.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/soc/ixp4xx/qmgr.h`, `linux/soc/ixp4xx/cpu.h`.
- Detected declarations: `function qmgr_put_entry`, `function qmgr_get_entry`, `function __qmgr_get_stat1`, `function __qmgr_get_stat2`, `function qmgr_stat_empty`, `function qmgr_stat_below_low_watermark`, `function qmgr_stat_full`, `function qmgr_stat_overflow`, `function qmgr_set_irq`, `function qmgr_irq1_a0`.
- Atlas domain: Driver Families / drivers/soc.
- 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.