drivers/irqchip/irq-bcm7038-l1.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-bcm7038-l1.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-bcm7038-l1.c
Extension
.c
Size
11775 bytes
Lines
458
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bcm7038_l1_chip {
	raw_spinlock_t		lock;
	unsigned int		n_words;
	struct irq_domain	*domain;
	struct bcm7038_l1_cpu	*cpus[NR_CPUS];
#ifdef CONFIG_PM_SLEEP
	struct list_head	list;
	u32			wake_mask[MAX_WORDS];
#endif
	u32			irq_fwd_mask[MAX_WORDS];
	u8			affinity[MAX_WORDS * IRQS_PER_WORD];
};

struct bcm7038_l1_cpu {
	void __iomem		*map_base;
	u32			mask_cache[];
};

/*
 * STATUS/MASK_STATUS/MASK_SET/MASK_CLEAR are packed one right after another:
 *
 * 7038:
 *   0x1000_1400: W0_STATUS
 *   0x1000_1404: W1_STATUS
 *   0x1000_1408: W0_MASK_STATUS
 *   0x1000_140c: W1_MASK_STATUS
 *   0x1000_1410: W0_MASK_SET
 *   0x1000_1414: W1_MASK_SET
 *   0x1000_1418: W0_MASK_CLEAR
 *   0x1000_141c: W1_MASK_CLEAR
 *
 * 7445:
 *   0xf03e_1500: W0_STATUS
 *   0xf03e_1504: W1_STATUS
 *   0xf03e_1508: W2_STATUS
 *   0xf03e_150c: W3_STATUS
 *   0xf03e_1510: W4_STATUS
 *   0xf03e_1514: W0_MASK_STATUS
 *   0xf03e_1518: W1_MASK_STATUS
 *   [...]
 */

static inline unsigned int reg_status(struct bcm7038_l1_chip *intc,
				      unsigned int word)
{
	return (0 * intc->n_words + word) * sizeof(u32);
}

static inline unsigned int reg_mask_set(struct bcm7038_l1_chip *intc,
					unsigned int word)
{
	return (2 * intc->n_words + word) * sizeof(u32);
}

static inline unsigned int reg_mask_clr(struct bcm7038_l1_chip *intc,
					unsigned int word)
{
	return (3 * intc->n_words + word) * sizeof(u32);
}

static inline u32 l1_readl(void __iomem *reg)
{
	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
		return ioread32be(reg);
	else
		return readl(reg);
}

static inline void l1_writel(u32 val, void __iomem *reg)
{
	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
		iowrite32be(val, reg);
	else
		writel(val, reg);
}

static void bcm7038_l1_irq_handle(struct irq_desc *desc)
{
	struct bcm7038_l1_chip *intc = irq_desc_get_handler_data(desc);
	struct bcm7038_l1_cpu *cpu;
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned int idx;

#if defined(CONFIG_SMP) && defined(CONFIG_MIPS)
	cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
#else
	cpu = intc->cpus[0];
#endif

	chained_irq_enter(chip, desc);

Annotation

Implementation Notes