arch/powerpc/include/asm/xics.h

Source file repositories/reference/linux-study-clean/arch/powerpc/include/asm/xics.h

File Facts

System
Linux kernel
Corpus path
arch/powerpc/include/asm/xics.h
Extension
.h
Size
4446 bytes
Lines
178
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source 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 icp_ops {
	unsigned int (*get_irq)(void);
	void (*eoi)(struct irq_data *d);
	void (*set_priority)(unsigned char prio);
	void (*teardown_cpu)(void);
	void (*flush_ipi)(void);
#ifdef CONFIG_SMP
	void (*cause_ipi)(int cpu);
	irq_handler_t ipi_action;
#endif
};

extern const struct icp_ops *icp_ops;

#ifdef CONFIG_PPC_ICS_NATIVE
/* Native ICS */
extern int ics_native_init(void);
#else
static inline int ics_native_init(void) { return -ENODEV; }
#endif

/* RTAS ICS */
#ifdef CONFIG_PPC_ICS_RTAS
extern int ics_rtas_init(void);
#else
static inline int ics_rtas_init(void) { return -ENODEV; }
#endif

/* HAL ICS */
#ifdef CONFIG_PPC_POWERNV
extern int ics_opal_init(void);
#else
static inline int ics_opal_init(void) { return -ENODEV; }
#endif

/* ICS instance, hooked up to chip_data of an irq */
struct ics {
	struct list_head link;
	int (*check)(struct ics *ics, unsigned int hwirq);
	void (*mask_unknown)(struct ics *ics, unsigned long vec);
	long (*get_server)(struct ics *ics, unsigned long vec);
	int (*host_match)(struct ics *ics, struct device_node *node);
	struct irq_chip *chip;
	char data[];
};

/* Commons */
extern unsigned int xics_default_server;
extern unsigned int xics_default_distrib_server;
extern unsigned int xics_interrupt_server_size;
extern struct irq_domain *xics_host;

struct xics_cppr {
	unsigned char stack[MAX_NUM_PRIORITIES];
	int index;
};

DECLARE_PER_CPU(struct xics_cppr, xics_cppr);

static inline void xics_push_cppr(unsigned int vec)
{
	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);

	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
		return;

	if (vec == XICS_IPI)
		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
	else
		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
}

static inline unsigned char xics_pop_cppr(void)
{
	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);

	if (WARN_ON(os_cppr->index < 1))
		return LOWEST_PRIORITY;

	return os_cppr->stack[--os_cppr->index];
}

static inline void xics_set_base_cppr(unsigned char cppr)
{
	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);

	/* we only really want to set the priority when there's
	 * just one cppr value on the stack
	 */
	WARN_ON(os_cppr->index != 0);

Annotation

Implementation Notes