xref: /linux/arch/loongarch/include/asm/irq.h (revision 46859ac8af52ae599e1b51992ddef3eb43f295fc)
10603839bSHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */
20603839bSHuacai Chen /*
30603839bSHuacai Chen  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
40603839bSHuacai Chen  */
50603839bSHuacai Chen #ifndef _ASM_IRQ_H
60603839bSHuacai Chen #define _ASM_IRQ_H
70603839bSHuacai Chen 
80603839bSHuacai Chen #include <linux/irqdomain.h>
90603839bSHuacai Chen #include <linux/irqreturn.h>
100603839bSHuacai Chen 
110603839bSHuacai Chen #define IRQ_STACK_SIZE			THREAD_SIZE
120603839bSHuacai Chen #define IRQ_STACK_START			(IRQ_STACK_SIZE - 16)
130603839bSHuacai Chen 
140603839bSHuacai Chen DECLARE_PER_CPU(unsigned long, irq_stack);
150603839bSHuacai Chen 
160603839bSHuacai Chen /*
170603839bSHuacai Chen  * The highest address on the IRQ stack contains a dummy frame which is
180603839bSHuacai Chen  * structured as follows:
190603839bSHuacai Chen  *
200603839bSHuacai Chen  *   top ------------
210603839bSHuacai Chen  *       | task sp  | <- irq_stack[cpu] + IRQ_STACK_START
220603839bSHuacai Chen  *       ------------
230603839bSHuacai Chen  *       |          | <- First frame of IRQ context
240603839bSHuacai Chen  *       ------------
250603839bSHuacai Chen  *
260603839bSHuacai Chen  * task sp holds a copy of the task stack pointer where the struct pt_regs
270603839bSHuacai Chen  * from exception entry can be found.
280603839bSHuacai Chen  */
290603839bSHuacai Chen 
300603839bSHuacai Chen static inline bool on_irq_stack(int cpu, unsigned long sp)
310603839bSHuacai Chen {
320603839bSHuacai Chen 	unsigned long low = per_cpu(irq_stack, cpu);
330603839bSHuacai Chen 	unsigned long high = low + IRQ_STACK_SIZE;
340603839bSHuacai Chen 
350603839bSHuacai Chen 	return (low <= sp && sp <= high);
360603839bSHuacai Chen }
370603839bSHuacai Chen 
380603839bSHuacai Chen int get_ipi_irq(void);
390603839bSHuacai Chen int get_pmc_irq(void);
400603839bSHuacai Chen int get_timer_irq(void);
410603839bSHuacai Chen void spurious_interrupt(void);
420603839bSHuacai Chen 
430603839bSHuacai Chen #define NR_IRQS_LEGACY 16
440603839bSHuacai Chen 
450603839bSHuacai Chen #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
460603839bSHuacai Chen void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool exclude_self);
470603839bSHuacai Chen 
480603839bSHuacai Chen #define MAX_IO_PICS 2
490603839bSHuacai Chen #define NR_IRQS	(64 + (256 * MAX_IO_PICS))
500603839bSHuacai Chen 
510603839bSHuacai Chen #define CORES_PER_EIO_NODE	4
520603839bSHuacai Chen 
530603839bSHuacai Chen #define LOONGSON_CPU_UART0_VEC		10 /* CPU UART0 */
540603839bSHuacai Chen #define LOONGSON_CPU_THSENS_VEC		14 /* CPU Thsens */
550603839bSHuacai Chen #define LOONGSON_CPU_HT0_VEC		16 /* CPU HT0 irq vector base number */
560603839bSHuacai Chen #define LOONGSON_CPU_HT1_VEC		24 /* CPU HT1 irq vector base number */
570603839bSHuacai Chen 
580603839bSHuacai Chen /* IRQ number definitions */
590603839bSHuacai Chen #define LOONGSON_LPC_IRQ_BASE		0
600603839bSHuacai Chen #define LOONGSON_LPC_LAST_IRQ		(LOONGSON_LPC_IRQ_BASE + 15)
610603839bSHuacai Chen 
620603839bSHuacai Chen #define LOONGSON_CPU_IRQ_BASE		16
630603839bSHuacai Chen #define LOONGSON_CPU_LAST_IRQ		(LOONGSON_CPU_IRQ_BASE + 14)
640603839bSHuacai Chen 
650603839bSHuacai Chen #define LOONGSON_PCH_IRQ_BASE		64
660603839bSHuacai Chen #define LOONGSON_PCH_ACPI_IRQ		(LOONGSON_PCH_IRQ_BASE + 47)
670603839bSHuacai Chen #define LOONGSON_PCH_LAST_IRQ		(LOONGSON_PCH_IRQ_BASE + 64 - 1)
680603839bSHuacai Chen 
690603839bSHuacai Chen #define LOONGSON_MSI_IRQ_BASE		(LOONGSON_PCH_IRQ_BASE + 64)
700603839bSHuacai Chen #define LOONGSON_MSI_LAST_IRQ		(LOONGSON_PCH_IRQ_BASE + 256 - 1)
710603839bSHuacai Chen 
720603839bSHuacai Chen #define GSI_MIN_LPC_IRQ		LOONGSON_LPC_IRQ_BASE
730603839bSHuacai Chen #define GSI_MAX_LPC_IRQ		(LOONGSON_LPC_IRQ_BASE + 16 - 1)
740603839bSHuacai Chen #define GSI_MIN_CPU_IRQ		LOONGSON_CPU_IRQ_BASE
750603839bSHuacai Chen #define GSI_MAX_CPU_IRQ		(LOONGSON_CPU_IRQ_BASE + 48 - 1)
760603839bSHuacai Chen #define GSI_MIN_PCH_IRQ		LOONGSON_PCH_IRQ_BASE
770603839bSHuacai Chen #define GSI_MAX_PCH_IRQ		(LOONGSON_PCH_IRQ_BASE + 256 - 1)
780603839bSHuacai Chen 
790603839bSHuacai Chen extern int find_pch_pic(u32 gsi);
800603839bSHuacai Chen extern int eiointc_get_node(int id);
810603839bSHuacai Chen 
820603839bSHuacai Chen static inline void eiointc_enable(void)
830603839bSHuacai Chen {
840603839bSHuacai Chen 	uint64_t misc;
850603839bSHuacai Chen 
860603839bSHuacai Chen 	misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
870603839bSHuacai Chen 	misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
880603839bSHuacai Chen 	iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
890603839bSHuacai Chen }
900603839bSHuacai Chen 
910603839bSHuacai Chen struct acpi_madt_lio_pic;
920603839bSHuacai Chen struct acpi_madt_eio_pic;
930603839bSHuacai Chen struct acpi_madt_ht_pic;
940603839bSHuacai Chen struct acpi_madt_bio_pic;
950603839bSHuacai Chen struct acpi_madt_msi_pic;
960603839bSHuacai Chen struct acpi_madt_lpc_pic;
970603839bSHuacai Chen 
980603839bSHuacai Chen struct irq_domain *loongarch_cpu_irq_init(void);
990603839bSHuacai Chen 
1000603839bSHuacai Chen struct irq_domain *liointc_acpi_init(struct irq_domain *parent,
1010603839bSHuacai Chen 					struct acpi_madt_lio_pic *acpi_liointc);
1020603839bSHuacai Chen struct irq_domain *eiointc_acpi_init(struct irq_domain *parent,
1030603839bSHuacai Chen 					struct acpi_madt_eio_pic *acpi_eiointc);
1040603839bSHuacai Chen 
1050603839bSHuacai Chen struct irq_domain *htvec_acpi_init(struct irq_domain *parent,
1060603839bSHuacai Chen 					struct acpi_madt_ht_pic *acpi_htvec);
1070603839bSHuacai Chen struct irq_domain *pch_lpc_acpi_init(struct irq_domain *parent,
1080603839bSHuacai Chen 					struct acpi_madt_lpc_pic *acpi_pchlpc);
1090603839bSHuacai Chen struct irq_domain *pch_msi_acpi_init(struct irq_domain *parent,
1100603839bSHuacai Chen 					struct acpi_madt_msi_pic *acpi_pchmsi);
1110603839bSHuacai Chen struct irq_domain *pch_pic_acpi_init(struct irq_domain *parent,
1120603839bSHuacai Chen 					struct acpi_madt_bio_pic *acpi_pchpic);
1130603839bSHuacai Chen 
1140603839bSHuacai Chen extern struct acpi_madt_lio_pic *acpi_liointc;
1150603839bSHuacai Chen extern struct acpi_madt_eio_pic *acpi_eiointc[MAX_IO_PICS];
1160603839bSHuacai Chen 
1170603839bSHuacai Chen extern struct acpi_madt_ht_pic *acpi_htintc;
1180603839bSHuacai Chen extern struct acpi_madt_lpc_pic *acpi_pchlpc;
1190603839bSHuacai Chen extern struct acpi_madt_msi_pic *acpi_pchmsi[MAX_IO_PICS];
1200603839bSHuacai Chen extern struct acpi_madt_bio_pic *acpi_pchpic[MAX_IO_PICS];
1210603839bSHuacai Chen 
1220603839bSHuacai Chen extern struct irq_domain *cpu_domain;
1230603839bSHuacai Chen extern struct irq_domain *liointc_domain;
1240603839bSHuacai Chen extern struct irq_domain *pch_lpc_domain;
1250603839bSHuacai Chen extern struct irq_domain *pch_msi_domain[MAX_IO_PICS];
1260603839bSHuacai Chen extern struct irq_domain *pch_pic_domain[MAX_IO_PICS];
1270603839bSHuacai Chen 
128*46859ac8SHuacai Chen extern irqreturn_t loongson3_ipi_interrupt(int irq, void *dev);
129*46859ac8SHuacai Chen 
1300603839bSHuacai Chen #include <asm-generic/irq.h>
1310603839bSHuacai Chen 
1320603839bSHuacai Chen #endif /* _ASM_IRQ_H */
133