xref: /linux/arch/loongarch/include/asm/irq.h (revision 0603839b18f4fb3bffa82515efcf5b02084505ef)
1*0603839bSHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */
2*0603839bSHuacai Chen /*
3*0603839bSHuacai Chen  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4*0603839bSHuacai Chen  */
5*0603839bSHuacai Chen #ifndef _ASM_IRQ_H
6*0603839bSHuacai Chen #define _ASM_IRQ_H
7*0603839bSHuacai Chen 
8*0603839bSHuacai Chen #include <linux/irqdomain.h>
9*0603839bSHuacai Chen #include <linux/irqreturn.h>
10*0603839bSHuacai Chen 
11*0603839bSHuacai Chen #define IRQ_STACK_SIZE			THREAD_SIZE
12*0603839bSHuacai Chen #define IRQ_STACK_START			(IRQ_STACK_SIZE - 16)
13*0603839bSHuacai Chen 
14*0603839bSHuacai Chen DECLARE_PER_CPU(unsigned long, irq_stack);
15*0603839bSHuacai Chen 
16*0603839bSHuacai Chen /*
17*0603839bSHuacai Chen  * The highest address on the IRQ stack contains a dummy frame which is
18*0603839bSHuacai Chen  * structured as follows:
19*0603839bSHuacai Chen  *
20*0603839bSHuacai Chen  *   top ------------
21*0603839bSHuacai Chen  *       | task sp  | <- irq_stack[cpu] + IRQ_STACK_START
22*0603839bSHuacai Chen  *       ------------
23*0603839bSHuacai Chen  *       |          | <- First frame of IRQ context
24*0603839bSHuacai Chen  *       ------------
25*0603839bSHuacai Chen  *
26*0603839bSHuacai Chen  * task sp holds a copy of the task stack pointer where the struct pt_regs
27*0603839bSHuacai Chen  * from exception entry can be found.
28*0603839bSHuacai Chen  */
29*0603839bSHuacai Chen 
30*0603839bSHuacai Chen static inline bool on_irq_stack(int cpu, unsigned long sp)
31*0603839bSHuacai Chen {
32*0603839bSHuacai Chen 	unsigned long low = per_cpu(irq_stack, cpu);
33*0603839bSHuacai Chen 	unsigned long high = low + IRQ_STACK_SIZE;
34*0603839bSHuacai Chen 
35*0603839bSHuacai Chen 	return (low <= sp && sp <= high);
36*0603839bSHuacai Chen }
37*0603839bSHuacai Chen 
38*0603839bSHuacai Chen int get_ipi_irq(void);
39*0603839bSHuacai Chen int get_pmc_irq(void);
40*0603839bSHuacai Chen int get_timer_irq(void);
41*0603839bSHuacai Chen void spurious_interrupt(void);
42*0603839bSHuacai Chen 
43*0603839bSHuacai Chen #define NR_IRQS_LEGACY 16
44*0603839bSHuacai Chen 
45*0603839bSHuacai Chen #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
46*0603839bSHuacai Chen void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool exclude_self);
47*0603839bSHuacai Chen 
48*0603839bSHuacai Chen #define MAX_IO_PICS 2
49*0603839bSHuacai Chen #define NR_IRQS	(64 + (256 * MAX_IO_PICS))
50*0603839bSHuacai Chen 
51*0603839bSHuacai Chen #define CORES_PER_EIO_NODE	4
52*0603839bSHuacai Chen 
53*0603839bSHuacai Chen #define LOONGSON_CPU_UART0_VEC		10 /* CPU UART0 */
54*0603839bSHuacai Chen #define LOONGSON_CPU_THSENS_VEC		14 /* CPU Thsens */
55*0603839bSHuacai Chen #define LOONGSON_CPU_HT0_VEC		16 /* CPU HT0 irq vector base number */
56*0603839bSHuacai Chen #define LOONGSON_CPU_HT1_VEC		24 /* CPU HT1 irq vector base number */
57*0603839bSHuacai Chen 
58*0603839bSHuacai Chen /* IRQ number definitions */
59*0603839bSHuacai Chen #define LOONGSON_LPC_IRQ_BASE		0
60*0603839bSHuacai Chen #define LOONGSON_LPC_LAST_IRQ		(LOONGSON_LPC_IRQ_BASE + 15)
61*0603839bSHuacai Chen 
62*0603839bSHuacai Chen #define LOONGSON_CPU_IRQ_BASE		16
63*0603839bSHuacai Chen #define LOONGSON_CPU_LAST_IRQ		(LOONGSON_CPU_IRQ_BASE + 14)
64*0603839bSHuacai Chen 
65*0603839bSHuacai Chen #define LOONGSON_PCH_IRQ_BASE		64
66*0603839bSHuacai Chen #define LOONGSON_PCH_ACPI_IRQ		(LOONGSON_PCH_IRQ_BASE + 47)
67*0603839bSHuacai Chen #define LOONGSON_PCH_LAST_IRQ		(LOONGSON_PCH_IRQ_BASE + 64 - 1)
68*0603839bSHuacai Chen 
69*0603839bSHuacai Chen #define LOONGSON_MSI_IRQ_BASE		(LOONGSON_PCH_IRQ_BASE + 64)
70*0603839bSHuacai Chen #define LOONGSON_MSI_LAST_IRQ		(LOONGSON_PCH_IRQ_BASE + 256 - 1)
71*0603839bSHuacai Chen 
72*0603839bSHuacai Chen #define GSI_MIN_LPC_IRQ		LOONGSON_LPC_IRQ_BASE
73*0603839bSHuacai Chen #define GSI_MAX_LPC_IRQ		(LOONGSON_LPC_IRQ_BASE + 16 - 1)
74*0603839bSHuacai Chen #define GSI_MIN_CPU_IRQ		LOONGSON_CPU_IRQ_BASE
75*0603839bSHuacai Chen #define GSI_MAX_CPU_IRQ		(LOONGSON_CPU_IRQ_BASE + 48 - 1)
76*0603839bSHuacai Chen #define GSI_MIN_PCH_IRQ		LOONGSON_PCH_IRQ_BASE
77*0603839bSHuacai Chen #define GSI_MAX_PCH_IRQ		(LOONGSON_PCH_IRQ_BASE + 256 - 1)
78*0603839bSHuacai Chen 
79*0603839bSHuacai Chen extern int find_pch_pic(u32 gsi);
80*0603839bSHuacai Chen extern int eiointc_get_node(int id);
81*0603839bSHuacai Chen 
82*0603839bSHuacai Chen static inline void eiointc_enable(void)
83*0603839bSHuacai Chen {
84*0603839bSHuacai Chen 	uint64_t misc;
85*0603839bSHuacai Chen 
86*0603839bSHuacai Chen 	misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
87*0603839bSHuacai Chen 	misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
88*0603839bSHuacai Chen 	iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
89*0603839bSHuacai Chen }
90*0603839bSHuacai Chen 
91*0603839bSHuacai Chen struct acpi_madt_lio_pic;
92*0603839bSHuacai Chen struct acpi_madt_eio_pic;
93*0603839bSHuacai Chen struct acpi_madt_ht_pic;
94*0603839bSHuacai Chen struct acpi_madt_bio_pic;
95*0603839bSHuacai Chen struct acpi_madt_msi_pic;
96*0603839bSHuacai Chen struct acpi_madt_lpc_pic;
97*0603839bSHuacai Chen 
98*0603839bSHuacai Chen struct irq_domain *loongarch_cpu_irq_init(void);
99*0603839bSHuacai Chen 
100*0603839bSHuacai Chen struct irq_domain *liointc_acpi_init(struct irq_domain *parent,
101*0603839bSHuacai Chen 					struct acpi_madt_lio_pic *acpi_liointc);
102*0603839bSHuacai Chen struct irq_domain *eiointc_acpi_init(struct irq_domain *parent,
103*0603839bSHuacai Chen 					struct acpi_madt_eio_pic *acpi_eiointc);
104*0603839bSHuacai Chen 
105*0603839bSHuacai Chen struct irq_domain *htvec_acpi_init(struct irq_domain *parent,
106*0603839bSHuacai Chen 					struct acpi_madt_ht_pic *acpi_htvec);
107*0603839bSHuacai Chen struct irq_domain *pch_lpc_acpi_init(struct irq_domain *parent,
108*0603839bSHuacai Chen 					struct acpi_madt_lpc_pic *acpi_pchlpc);
109*0603839bSHuacai Chen struct irq_domain *pch_msi_acpi_init(struct irq_domain *parent,
110*0603839bSHuacai Chen 					struct acpi_madt_msi_pic *acpi_pchmsi);
111*0603839bSHuacai Chen struct irq_domain *pch_pic_acpi_init(struct irq_domain *parent,
112*0603839bSHuacai Chen 					struct acpi_madt_bio_pic *acpi_pchpic);
113*0603839bSHuacai Chen 
114*0603839bSHuacai Chen extern struct acpi_madt_lio_pic *acpi_liointc;
115*0603839bSHuacai Chen extern struct acpi_madt_eio_pic *acpi_eiointc[MAX_IO_PICS];
116*0603839bSHuacai Chen 
117*0603839bSHuacai Chen extern struct acpi_madt_ht_pic *acpi_htintc;
118*0603839bSHuacai Chen extern struct acpi_madt_lpc_pic *acpi_pchlpc;
119*0603839bSHuacai Chen extern struct acpi_madt_msi_pic *acpi_pchmsi[MAX_IO_PICS];
120*0603839bSHuacai Chen extern struct acpi_madt_bio_pic *acpi_pchpic[MAX_IO_PICS];
121*0603839bSHuacai Chen 
122*0603839bSHuacai Chen extern struct irq_domain *cpu_domain;
123*0603839bSHuacai Chen extern struct irq_domain *liointc_domain;
124*0603839bSHuacai Chen extern struct irq_domain *pch_lpc_domain;
125*0603839bSHuacai Chen extern struct irq_domain *pch_msi_domain[MAX_IO_PICS];
126*0603839bSHuacai Chen extern struct irq_domain *pch_pic_domain[MAX_IO_PICS];
127*0603839bSHuacai Chen 
128*0603839bSHuacai Chen #include <asm-generic/irq.h>
129*0603839bSHuacai Chen 
130*0603839bSHuacai Chen #endif /* _ASM_IRQ_H */
131