xref: /openbmc/linux/arch/powerpc/include/asm/xics.h (revision b866cc2199d6a6cdcefe4acfe4cfca3ac3c6d38e)
10b05ac6eSBenjamin Herrenschmidt /*
2446957baSAdam Buchbinder  * Common definitions across all variants of ICP and ICS interrupt
30b05ac6eSBenjamin Herrenschmidt  * controllers.
40b05ac6eSBenjamin Herrenschmidt  */
50b05ac6eSBenjamin Herrenschmidt 
60b05ac6eSBenjamin Herrenschmidt #ifndef _XICS_H
70b05ac6eSBenjamin Herrenschmidt #define _XICS_H
80b05ac6eSBenjamin Herrenschmidt 
9cd852579SMichael Ellerman #include <linux/interrupt.h>
10cd852579SMichael Ellerman 
110b05ac6eSBenjamin Herrenschmidt #define XICS_IPI		2
120b05ac6eSBenjamin Herrenschmidt #define XICS_IRQ_SPURIOUS	0
130b05ac6eSBenjamin Herrenschmidt 
140b05ac6eSBenjamin Herrenschmidt /* Want a priority other than 0.  Various HW issues require this. */
150b05ac6eSBenjamin Herrenschmidt #define	DEFAULT_PRIORITY	5
160b05ac6eSBenjamin Herrenschmidt 
170b05ac6eSBenjamin Herrenschmidt /*
18a3a9f3b4SYong Zhang  * Mark IPIs as higher priority so we can take them inside interrupts
19a3a9f3b4SYong Zhang  * FIXME: still true now?
200b05ac6eSBenjamin Herrenschmidt  */
210b05ac6eSBenjamin Herrenschmidt #define IPI_PRIORITY		4
220b05ac6eSBenjamin Herrenschmidt 
230b05ac6eSBenjamin Herrenschmidt /* The least favored priority */
240b05ac6eSBenjamin Herrenschmidt #define LOWEST_PRIORITY		0xFF
250b05ac6eSBenjamin Herrenschmidt 
260b05ac6eSBenjamin Herrenschmidt /* The number of priorities defined above */
270b05ac6eSBenjamin Herrenschmidt #define MAX_NUM_PRIORITIES	3
280b05ac6eSBenjamin Herrenschmidt 
290b05ac6eSBenjamin Herrenschmidt /* Native ICP */
305c7c1e94SBenjamin Herrenschmidt #ifdef CONFIG_PPC_ICP_NATIVE
310b05ac6eSBenjamin Herrenschmidt extern int icp_native_init(void);
32d6a4f709SPaul Mackerras extern void icp_native_flush_interrupt(void);
33ec13e9b6SSuresh Warrier extern void icp_native_cause_ipi_rm(int cpu);
345c7c1e94SBenjamin Herrenschmidt #else
355c7c1e94SBenjamin Herrenschmidt static inline int icp_native_init(void) { return -ENODEV; }
365c7c1e94SBenjamin Herrenschmidt #endif
370b05ac6eSBenjamin Herrenschmidt 
380b05ac6eSBenjamin Herrenschmidt /* PAPR ICP */
395c7c1e94SBenjamin Herrenschmidt #ifdef CONFIG_PPC_ICP_HV
400b05ac6eSBenjamin Herrenschmidt extern int icp_hv_init(void);
415c7c1e94SBenjamin Herrenschmidt #else
425c7c1e94SBenjamin Herrenschmidt static inline int icp_hv_init(void) { return -ENODEV; }
435c7c1e94SBenjamin Herrenschmidt #endif
440b05ac6eSBenjamin Herrenschmidt 
45d7436188SBenjamin Herrenschmidt #ifdef CONFIG_PPC_POWERNV
46d7436188SBenjamin Herrenschmidt extern int icp_opal_init(void);
479b256714SBenjamin Herrenschmidt extern void icp_opal_flush_interrupt(void);
48d7436188SBenjamin Herrenschmidt #else
49d7436188SBenjamin Herrenschmidt static inline int icp_opal_init(void) { return -ENODEV; }
50d7436188SBenjamin Herrenschmidt #endif
51d7436188SBenjamin Herrenschmidt 
520b05ac6eSBenjamin Herrenschmidt /* ICP ops */
530b05ac6eSBenjamin Herrenschmidt struct icp_ops {
540b05ac6eSBenjamin Herrenschmidt 	unsigned int (*get_irq)(void);
550b05ac6eSBenjamin Herrenschmidt 	void (*eoi)(struct irq_data *d);
560b05ac6eSBenjamin Herrenschmidt 	void (*set_priority)(unsigned char prio);
570b05ac6eSBenjamin Herrenschmidt 	void (*teardown_cpu)(void);
580b05ac6eSBenjamin Herrenschmidt 	void (*flush_ipi)(void);
590b05ac6eSBenjamin Herrenschmidt #ifdef CONFIG_SMP
60*b866cc21SNicholas Piggin 	void (*cause_ipi)(int cpu);
610b05ac6eSBenjamin Herrenschmidt 	irq_handler_t ipi_action;
620b05ac6eSBenjamin Herrenschmidt #endif
630b05ac6eSBenjamin Herrenschmidt };
640b05ac6eSBenjamin Herrenschmidt 
650b05ac6eSBenjamin Herrenschmidt extern const struct icp_ops *icp_ops;
660b05ac6eSBenjamin Herrenschmidt 
670b05ac6eSBenjamin Herrenschmidt /* Native ICS */
680b05ac6eSBenjamin Herrenschmidt extern int ics_native_init(void);
690b05ac6eSBenjamin Herrenschmidt 
700b05ac6eSBenjamin Herrenschmidt /* RTAS ICS */
715c7c1e94SBenjamin Herrenschmidt #ifdef CONFIG_PPC_ICS_RTAS
720b05ac6eSBenjamin Herrenschmidt extern int ics_rtas_init(void);
735c7c1e94SBenjamin Herrenschmidt #else
745c7c1e94SBenjamin Herrenschmidt static inline int ics_rtas_init(void) { return -ENODEV; }
755c7c1e94SBenjamin Herrenschmidt #endif
765c7c1e94SBenjamin Herrenschmidt 
775c7c1e94SBenjamin Herrenschmidt /* HAL ICS */
785c7c1e94SBenjamin Herrenschmidt #ifdef CONFIG_PPC_POWERNV
795c7c1e94SBenjamin Herrenschmidt extern int ics_opal_init(void);
805c7c1e94SBenjamin Herrenschmidt #else
815c7c1e94SBenjamin Herrenschmidt static inline int ics_opal_init(void) { return -ENODEV; }
825c7c1e94SBenjamin Herrenschmidt #endif
830b05ac6eSBenjamin Herrenschmidt 
840b05ac6eSBenjamin Herrenschmidt /* ICS instance, hooked up to chip_data of an irq */
850b05ac6eSBenjamin Herrenschmidt struct ics {
860b05ac6eSBenjamin Herrenschmidt 	struct list_head link;
870b05ac6eSBenjamin Herrenschmidt 	int (*map)(struct ics *ics, unsigned int virq);
880b05ac6eSBenjamin Herrenschmidt 	void (*mask_unknown)(struct ics *ics, unsigned long vec);
890b05ac6eSBenjamin Herrenschmidt 	long (*get_server)(struct ics *ics, unsigned long vec);
905ca12376SMichael Ellerman 	int (*host_match)(struct ics *ics, struct device_node *node);
910b05ac6eSBenjamin Herrenschmidt 	char data[];
920b05ac6eSBenjamin Herrenschmidt };
930b05ac6eSBenjamin Herrenschmidt 
940b05ac6eSBenjamin Herrenschmidt /* Commons */
950b05ac6eSBenjamin Herrenschmidt extern unsigned int xics_default_server;
960b05ac6eSBenjamin Herrenschmidt extern unsigned int xics_default_distrib_server;
970b05ac6eSBenjamin Herrenschmidt extern unsigned int xics_interrupt_server_size;
98bae1d8f1SGrant Likely extern struct irq_domain *xics_host;
990b05ac6eSBenjamin Herrenschmidt 
1000b05ac6eSBenjamin Herrenschmidt struct xics_cppr {
1010b05ac6eSBenjamin Herrenschmidt 	unsigned char stack[MAX_NUM_PRIORITIES];
1020b05ac6eSBenjamin Herrenschmidt 	int index;
1030b05ac6eSBenjamin Herrenschmidt };
1040b05ac6eSBenjamin Herrenschmidt 
1050b05ac6eSBenjamin Herrenschmidt DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
1060b05ac6eSBenjamin Herrenschmidt 
1070b05ac6eSBenjamin Herrenschmidt static inline void xics_push_cppr(unsigned int vec)
1080b05ac6eSBenjamin Herrenschmidt {
10969111bacSChristoph Lameter 	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
1100b05ac6eSBenjamin Herrenschmidt 
1110b05ac6eSBenjamin Herrenschmidt 	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
1120b05ac6eSBenjamin Herrenschmidt 		return;
1130b05ac6eSBenjamin Herrenschmidt 
1140b05ac6eSBenjamin Herrenschmidt 	if (vec == XICS_IPI)
1150b05ac6eSBenjamin Herrenschmidt 		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
1160b05ac6eSBenjamin Herrenschmidt 	else
1170b05ac6eSBenjamin Herrenschmidt 		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
1180b05ac6eSBenjamin Herrenschmidt }
1190b05ac6eSBenjamin Herrenschmidt 
1200b05ac6eSBenjamin Herrenschmidt static inline unsigned char xics_pop_cppr(void)
1210b05ac6eSBenjamin Herrenschmidt {
12269111bacSChristoph Lameter 	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
1230b05ac6eSBenjamin Herrenschmidt 
1240b05ac6eSBenjamin Herrenschmidt 	if (WARN_ON(os_cppr->index < 1))
1250b05ac6eSBenjamin Herrenschmidt 		return LOWEST_PRIORITY;
1260b05ac6eSBenjamin Herrenschmidt 
1270b05ac6eSBenjamin Herrenschmidt 	return os_cppr->stack[--os_cppr->index];
1280b05ac6eSBenjamin Herrenschmidt }
1290b05ac6eSBenjamin Herrenschmidt 
1300b05ac6eSBenjamin Herrenschmidt static inline void xics_set_base_cppr(unsigned char cppr)
1310b05ac6eSBenjamin Herrenschmidt {
13269111bacSChristoph Lameter 	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
1330b05ac6eSBenjamin Herrenschmidt 
1340b05ac6eSBenjamin Herrenschmidt 	/* we only really want to set the priority when there's
1350b05ac6eSBenjamin Herrenschmidt 	 * just one cppr value on the stack
1360b05ac6eSBenjamin Herrenschmidt 	 */
1370b05ac6eSBenjamin Herrenschmidt 	WARN_ON(os_cppr->index != 0);
1380b05ac6eSBenjamin Herrenschmidt 
1390b05ac6eSBenjamin Herrenschmidt 	os_cppr->stack[0] = cppr;
1400b05ac6eSBenjamin Herrenschmidt }
1410b05ac6eSBenjamin Herrenschmidt 
1420b05ac6eSBenjamin Herrenschmidt static inline unsigned char xics_cppr_top(void)
1430b05ac6eSBenjamin Herrenschmidt {
14469111bacSChristoph Lameter 	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
1450b05ac6eSBenjamin Herrenschmidt 
1460b05ac6eSBenjamin Herrenschmidt 	return os_cppr->stack[os_cppr->index];
1470b05ac6eSBenjamin Herrenschmidt }
1480b05ac6eSBenjamin Herrenschmidt 
1490b05ac6eSBenjamin Herrenschmidt DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
1500b05ac6eSBenjamin Herrenschmidt 
1510b05ac6eSBenjamin Herrenschmidt extern void xics_init(void);
1520b05ac6eSBenjamin Herrenschmidt extern void xics_setup_cpu(void);
1530b05ac6eSBenjamin Herrenschmidt extern void xics_update_irq_servers(void);
1540b05ac6eSBenjamin Herrenschmidt extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
1550b05ac6eSBenjamin Herrenschmidt extern void xics_mask_unknown_vec(unsigned int vec);
1560b05ac6eSBenjamin Herrenschmidt extern irqreturn_t xics_ipi_dispatch(int cpu);
157a7f4ee1fSMichael Ellerman extern void xics_smp_probe(void);
1580b05ac6eSBenjamin Herrenschmidt extern void xics_register_ics(struct ics *ics);
1590b05ac6eSBenjamin Herrenschmidt extern void xics_teardown_cpu(void);
1600b05ac6eSBenjamin Herrenschmidt extern void xics_kexec_teardown_cpu(int secondary);
1610b05ac6eSBenjamin Herrenschmidt extern void xics_migrate_irqs_away(void);
162137436c9SGavin Shan extern void icp_native_eoi(struct irq_data *d);
163880a3d6aSBenjamin Herrenschmidt extern int xics_set_irq_type(struct irq_data *d, unsigned int flow_type);
164880a3d6aSBenjamin Herrenschmidt extern int xics_retrigger(struct irq_data *data);
1650b05ac6eSBenjamin Herrenschmidt #ifdef CONFIG_SMP
1660b05ac6eSBenjamin Herrenschmidt extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
1670b05ac6eSBenjamin Herrenschmidt 			       unsigned int strict_check);
1680b05ac6eSBenjamin Herrenschmidt #else
1690b05ac6eSBenjamin Herrenschmidt #define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
1700b05ac6eSBenjamin Herrenschmidt #endif
1710b05ac6eSBenjamin Herrenschmidt 
1720b05ac6eSBenjamin Herrenschmidt 
1730b05ac6eSBenjamin Herrenschmidt #endif /* _XICS_H */
174