File Index
Files and directories
Sign in
FILE

xics.h

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/include/asm/xics.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * Common definitions across all variants of ICP and ICS interrupt
  4 * controllers.
  5 */
  6
  7#ifndef _XICS_H
  8#define _XICS_H
  9
 10#include <linux/interrupt.h>
 11
 12#define XICS_IPI		2
 13#define XICS_IRQ_SPURIOUS	0
 14
 15/* Want a priority other than 0.  Various HW issues require this. */
 16#define	DEFAULT_PRIORITY	5
 17
 18/*
 19 * Mark IPIs as higher priority so we can take them inside interrupts
 20 * FIXME: still true now?
 21 */
 22#define IPI_PRIORITY		4
 23
 24/* The least favored priority */
 25#define LOWEST_PRIORITY		0xFF
 26
 27/* The number of priorities defined above */
 28#define MAX_NUM_PRIORITIES	3
 29
 30/* Native ICP */
 31#ifdef CONFIG_PPC_ICP_NATIVE
 32extern int icp_native_init(void);
 33extern void icp_native_flush_interrupt(void);
 34#else
 35static inline int icp_native_init(void) { return -ENODEV; }
 36#endif
 37
 38/* PAPR ICP */
 39#ifdef CONFIG_PPC_ICP_HV
 40int __init icp_hv_init(void);
 41#else
 42static inline int icp_hv_init(void) { return -ENODEV; }
 43#endif
 44
 45#ifdef CONFIG_PPC_POWERNV
 46int __init icp_opal_init(void);
 47extern void icp_opal_flush_interrupt(void);
 48#else
 49static inline int icp_opal_init(void) { return -ENODEV; }
 50#endif
 51
 52/* ICP ops */
 53struct icp_ops {
 54	unsigned int (*get_irq)(void);
 55	void (*eoi)(struct irq_data *d);
 56	void (*set_priority)(unsigned char prio);
 57	void (*teardown_cpu)(void);
 58	void (*flush_ipi)(void);
 59#ifdef CONFIG_SMP
 60	void (*cause_ipi)(int cpu);
 61	irq_handler_t ipi_action;
 62#endif
 63};
 64
 65extern const struct icp_ops *icp_ops;
 66
 67#ifdef CONFIG_PPC_ICS_NATIVE
 68/* Native ICS */
 69extern int ics_native_init(void);
 70#else
 71static inline int ics_native_init(void) { return -ENODEV; }
 72#endif
 73
 74/* RTAS ICS */
 75#ifdef CONFIG_PPC_ICS_RTAS
 76extern int ics_rtas_init(void);
 77#else
 78static inline int ics_rtas_init(void) { return -ENODEV; }
 79#endif
 80
 81/* HAL ICS */
 82#ifdef CONFIG_PPC_POWERNV
 83extern int ics_opal_init(void);
 84#else
 85static inline int ics_opal_init(void) { return -ENODEV; }
 86#endif
 87
 88/* ICS instance, hooked up to chip_data of an irq */
 89struct ics {
 90	struct list_head link;
 91	int (*check)(struct ics *ics, unsigned int hwirq);
 92	void (*mask_unknown)(struct ics *ics, unsigned long vec);
 93	long (*get_server)(struct ics *ics, unsigned long vec);
 94	int (*host_match)(struct ics *ics, struct device_node *node);
 95	struct irq_chip *chip;
 96	char data[];
 97};
 98
 99/* Commons */
100extern unsigned int xics_default_server;
101extern unsigned int xics_default_distrib_server;
102extern unsigned int xics_interrupt_server_size;
103extern struct irq_domain *xics_host;
104
105struct xics_cppr {
106	unsigned char stack[MAX_NUM_PRIORITIES];
107	int index;
108};
109
110DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
111
112static inline void xics_push_cppr(unsigned int vec)
113{
114	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
115
116	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
117		return;
118
119	if (vec == XICS_IPI)
120		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
121	else
122		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
123}
124
125static inline unsigned char xics_pop_cppr(void)
126{
127	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
128
129	if (WARN_ON(os_cppr->index < 1))
130		return LOWEST_PRIORITY;
131
132	return os_cppr->stack[--os_cppr->index];
133}
134
135static inline void xics_set_base_cppr(unsigned char cppr)
136{
137	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
138
139	/* we only really want to set the priority when there's
140	 * just one cppr value on the stack
141	 */
142	WARN_ON(os_cppr->index != 0);
143
144	os_cppr->stack[0] = cppr;
145}
146
147static inline unsigned char xics_cppr_top(void)
148{
149	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
150	
151	return os_cppr->stack[os_cppr->index];
152}
153
154DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
155
156extern void xics_init(void);
157extern void xics_setup_cpu(void);
158extern void xics_update_irq_servers(void);
159extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
160extern void xics_mask_unknown_vec(unsigned int vec);
161extern void xics_smp_probe(void);
162extern void xics_register_ics(struct ics *ics);
163extern void xics_teardown_cpu(void);
164extern void xics_kexec_teardown_cpu(int secondary);
165extern void xics_migrate_irqs_away(void);
166extern void icp_native_eoi(struct irq_data *d);
167extern int xics_set_irq_type(struct irq_data *d, unsigned int flow_type);
168extern int xics_retrigger(struct irq_data *data);
169#ifdef CONFIG_SMP
170extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
171			       unsigned int strict_check);
172#else
173#define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
174#endif
175
176
177#endif /* _XICS_H */
~/ Read-only file preview.