arch/powerpc/platforms/ps3/interrupt.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/ps3/interrupt.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/ps3/interrupt.c
Extension
.c
Size
19517 bytes
Lines
784
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ps3_bmp {
	struct {
		u64 status;
		u64 unused_1[3];
		unsigned long mask;
		u64 unused_2[3];
	};
};

/**
 * struct ps3_private - a per cpu data structure
 * @bmp: ps3_bmp structure
 * @bmp_lock: Synchronize access to bmp.
 * @ipi_debug_brk_mask: Mask for debug break IPIs
 * @ppe_id: HV logical_ppe_id
 * @thread_id: HV thread_id
 * @ipi_mask: Mask of IPI virqs
 */

struct ps3_private {
	struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
	spinlock_t bmp_lock;
	u64 ppe_id;
	u64 thread_id;
	unsigned long ipi_debug_brk_mask;
	unsigned long ipi_mask;
};

static DEFINE_PER_CPU(struct ps3_private, ps3_private);

/**
 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
 * @virq: The assigned Linux virq.
 *
 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
 */

static void ps3_chip_mask(struct irq_data *d)
{
	struct ps3_private *pd = irq_data_get_irq_chip_data(d);
	unsigned long flags;

	DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
		pd->thread_id, d->irq);

	local_irq_save(flags);
	clear_bit(63 - d->irq, &pd->bmp.mask);
	lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
	local_irq_restore(flags);
}

/**
 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
 * @virq: The assigned Linux virq.
 *
 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
 */

static void ps3_chip_unmask(struct irq_data *d)
{
	struct ps3_private *pd = irq_data_get_irq_chip_data(d);
	unsigned long flags;

	DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
		pd->thread_id, d->irq);

	local_irq_save(flags);
	set_bit(63 - d->irq, &pd->bmp.mask);
	lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
	local_irq_restore(flags);
}

/**
 * ps3_chip_eoi - HV end-of-interrupt.
 * @virq: The assigned Linux virq.
 *
 * Calls lv1_end_of_interrupt_ext().
 */

static void ps3_chip_eoi(struct irq_data *d)
{
	const struct ps3_private *pd = irq_data_get_irq_chip_data(d);

	/* non-IPIs are EOIed here. */

	if (!test_bit(63 - d->irq, &pd->ipi_mask))
		lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
}

/**

Annotation

Implementation Notes