Skip to content

Commit 760d7e7

Browse files
zhangtianyang-ztyKAGA-KOKO
authored andcommitted
Loongarch: Support loongarch avec
Introduce the advanced extended interrupt controllers. This feature will allow each core to have 256 independent interrupt vectors and MSI interrupts can be independently routed to any vector on any CPU. [ tglx: Fixed up coding style. Made on/offline functions void ] Co-developed-by: Jianmin Lv <[email protected]> Signed-off-by: Jianmin Lv <[email protected]> Co-developed-by: Liupu Wang <[email protected]> Signed-off-by: Liupu Wang <[email protected]> Signed-off-by: Tianyang Zhang <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 986b6ad commit 760d7e7

File tree

14 files changed

+517
-10
lines changed

14 files changed

+517
-10
lines changed

arch/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ config LOONGARCH
8383
select GENERIC_ENTRY
8484
select GENERIC_GETTIMEOFDAY
8585
select GENERIC_IOREMAP if !ARCH_IOREMAP
86+
select GENERIC_IRQ_MATRIX_ALLOCATOR
8687
select GENERIC_IRQ_MULTI_HANDLER
8788
select GENERIC_IRQ_PROBE
8889
select GENERIC_IRQ_SHOW

arch/loongarch/include/asm/cpu-features.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@
6565
#define cpu_has_guestid cpu_opt(LOONGARCH_CPU_GUESTID)
6666
#define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR)
6767
#define cpu_has_ptw cpu_opt(LOONGARCH_CPU_PTW)
68+
#define cpu_has_avecint cpu_opt(LOONGARCH_CPU_AVECINT)
6869

6970
#endif /* __ASM_CPU_FEATURES_H */

arch/loongarch/include/asm/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ enum cpu_type_enum {
9999
#define CPU_FEATURE_GUESTID 24 /* CPU has GuestID feature */
100100
#define CPU_FEATURE_HYPERVISOR 25 /* CPU has hypervisor (running in VM) */
101101
#define CPU_FEATURE_PTW 26 /* CPU has hardware page table walker */
102+
#define CPU_FEATURE_AVECINT 27 /* CPU has avec interrupt */
102103

103104
#define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
104105
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
@@ -127,5 +128,6 @@ enum cpu_type_enum {
127128
#define LOONGARCH_CPU_GUESTID BIT_ULL(CPU_FEATURE_GUESTID)
128129
#define LOONGARCH_CPU_HYPERVISOR BIT_ULL(CPU_FEATURE_HYPERVISOR)
129130
#define LOONGARCH_CPU_PTW BIT_ULL(CPU_FEATURE_PTW)
131+
#define LOONGARCH_CPU_AVECINT BIT_ULL(CPU_FEATURE_AVECINT)
130132

131133
#endif /* _ASM_CPU_H */

arch/loongarch/include/asm/hw_irq.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99

1010
extern atomic_t irq_err_count;
1111

12+
/*
13+
* 256 vectors Map:
14+
*
15+
* 0 - 15: mapping legacy IPs, e.g. IP0-12.
16+
* 16 - 255: mapping a vector for external IRQ.
17+
*
18+
*/
19+
#define NR_VECTORS 256
20+
#define IRQ_MATRIX_BITS NR_VECTORS
21+
#define NR_LEGACY_VECTORS 16
1222
/*
1323
* interrupt-retrigger: NOP for now. This may not be appropriate for all
1424
* machines, we'll see ...

arch/loongarch/include/asm/irq.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extern struct acpi_vector_group msi_group[MAX_IO_PICS];
6565
#define LOONGSON_LPC_LAST_IRQ (LOONGSON_LPC_IRQ_BASE + 15)
6666

6767
#define LOONGSON_CPU_IRQ_BASE 16
68-
#define LOONGSON_CPU_LAST_IRQ (LOONGSON_CPU_IRQ_BASE + 14)
68+
#define LOONGSON_CPU_LAST_IRQ (LOONGSON_CPU_IRQ_BASE + 15)
6969

7070
#define LOONGSON_PCH_IRQ_BASE 64
7171
#define LOONGSON_PCH_ACPI_IRQ (LOONGSON_PCH_IRQ_BASE + 47)
@@ -101,6 +101,16 @@ int pch_msi_acpi_init(struct irq_domain *parent,
101101
struct acpi_madt_msi_pic *acpi_pchmsi);
102102
int pch_pic_acpi_init(struct irq_domain *parent,
103103
struct acpi_madt_bio_pic *acpi_pchpic);
104+
105+
#ifdef CONFIG_ACPI
106+
int __init pch_msi_acpi_init_v2(struct irq_domain *parent,
107+
struct acpi_madt_msi_pic *pch_msi_entry);
108+
int __init loongarch_avec_acpi_init(struct irq_domain *parent);
109+
void complete_irq_moving(void);
110+
void loongarch_avec_offline_cpu(unsigned int cpu);
111+
void loongarch_avec_online_cpu(unsigned int cpu);
112+
#endif
113+
104114
int find_pch_pic(u32 gsi);
105115
struct fwnode_handle *get_pch_msi_handle(int pci_segment);
106116

arch/loongarch/include/asm/loongarch.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
#define CPUCFG1_RPLV BIT(23)
7373
#define CPUCFG1_HUGEPG BIT(24)
7474
#define CPUCFG1_CRC32 BIT(25)
75-
#define CPUCFG1_MSGINT BIT(26)
7675

7776
#define LOONGARCH_CPUCFG2 0x2
7877
#define CPUCFG2_FP BIT(0)
@@ -252,8 +251,8 @@
252251
#define CSR_ESTAT_EXC_WIDTH 6
253252
#define CSR_ESTAT_EXC (_ULCAST_(0x3f) << CSR_ESTAT_EXC_SHIFT)
254253
#define CSR_ESTAT_IS_SHIFT 0
255-
#define CSR_ESTAT_IS_WIDTH 14
256-
#define CSR_ESTAT_IS (_ULCAST_(0x3fff) << CSR_ESTAT_IS_SHIFT)
254+
#define CSR_ESTAT_IS_WIDTH 15
255+
#define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT)
257256

258257
#define LOONGARCH_CSR_ERA 0x6 /* ERA */
259258

@@ -999,10 +998,18 @@
999998
#define CSR_FWPC_SKIP_SHIFT 16
1000999
#define CSR_FWPC_SKIP (_ULCAST_(1) << CSR_FWPC_SKIP_SHIFT)
10011000

1001+
#define LOONGARCH_CSR_IRR0 0xa0
1002+
#define LOONGARCH_CSR_IRR1 0xa1
1003+
#define LOONGARCH_CSR_IRR2 0xa2
1004+
#define LOONGARCH_CSR_IRR3 0xa3
1005+
#define LOONGARCH_CSR_IRR_BASE LOONGARCH_CSR_IRR0
1006+
1007+
#define LOONGARCH_CSR_ILR 0xa4
1008+
10021009
/*
10031010
* CSR_ECFG IM
10041011
*/
1005-
#define ECFG0_IM 0x00001fff
1012+
#define ECFG0_IM 0x00005fff
10061013
#define ECFGB_SIP0 0
10071014
#define ECFGF_SIP0 (_ULCAST_(1) << ECFGB_SIP0)
10081015
#define ECFGB_SIP1 1
@@ -1045,6 +1052,7 @@
10451052
#define IOCSRF_EIODECODE BIT_ULL(9)
10461053
#define IOCSRF_FLATMODE BIT_ULL(10)
10471054
#define IOCSRF_VM BIT_ULL(11)
1055+
#define IOCSRF_AVEC BIT_ULL(15)
10481056

10491057
#define LOONGARCH_IOCSR_VENDOR 0x10
10501058

@@ -1055,6 +1063,7 @@
10551063
#define LOONGARCH_IOCSR_MISC_FUNC 0x420
10561064
#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21)
10571065
#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48)
1066+
#define IOCSR_MISC_FUNC_AVEC_EN BIT_ULL(51)
10581067

10591068
#define LOONGARCH_IOCSR_CPUTEMP 0x428
10601069

@@ -1375,9 +1384,10 @@ __BUILD_CSR_OP(tlbidx)
13751384
#define INT_TI 11 /* Timer */
13761385
#define INT_IPI 12
13771386
#define INT_NMI 13
1387+
#define INT_AVEC 14
13781388

13791389
/* ExcCodes corresponding to interrupts */
1380-
#define EXCCODE_INT_NUM (INT_NMI + 1)
1390+
#define EXCCODE_INT_NUM (INT_AVEC + 1)
13811391
#define EXCCODE_INT_START 64
13821392
#define EXCCODE_INT_END (EXCCODE_INT_START + EXCCODE_INT_NUM - 1)
13831393

arch/loongarch/include/asm/smp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ extern int __cpu_logical_map[NR_CPUS];
6969
#define ACTION_BOOT_CPU 0
7070
#define ACTION_RESCHEDULE 1
7171
#define ACTION_CALL_FUNCTION 2
72+
#define ACTION_CLEAR_VECT 3
7273
#define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU)
7374
#define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE)
7475
#define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION)
76+
#define SMP_CLEAR_VECT BIT(ACTION_CLEAR_VECT)
7577

7678
struct secondary_data {
7779
unsigned long stack;

arch/loongarch/kernel/cpu-probe.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
106106
elf_hwcap |= HWCAP_LOONGARCH_CRC32;
107107
}
108108

109-
110109
config = read_cpucfg(LOONGARCH_CPUCFG2);
111110
if (config & CPUCFG2_LAM) {
112111
c->options |= LOONGARCH_CPU_LAM;
@@ -176,6 +175,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
176175
c->options |= LOONGARCH_CPU_EIODECODE;
177176
if (config & IOCSRF_VM)
178177
c->options |= LOONGARCH_CPU_HYPERVISOR;
178+
if (config & IOCSRF_AVEC)
179+
c->options |= LOONGARCH_CPU_AVECINT;
179180

180181
config = csr_read32(LOONGARCH_CSR_ASID);
181182
config = (config & CSR_ASID_BIT) >> CSR_ASID_BIT_SHIFT;

arch/loongarch/kernel/smp.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
234234
per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++;
235235
}
236236

237+
if (action & SMP_CLEAR_VECT)
238+
complete_irq_moving();
239+
237240
return IRQ_HANDLED;
238241
}
239242

@@ -388,6 +391,7 @@ int loongson_cpu_disable(void)
388391
irq_migrate_all_off_this_cpu();
389392
clear_csr_ecfg(ECFG0_IM);
390393
local_irq_restore(flags);
394+
loongarch_avec_offline_cpu(cpu);
391395
local_flush_tlb_all();
392396

393397
return 0;
@@ -566,6 +570,7 @@ asmlinkage void start_secondary(void)
566570
* early is dangerous.
567571
*/
568572
WARN_ON_ONCE(!irqs_disabled());
573+
loongarch_avec_online_cpu(cpu);
569574
loongson_smp_finish();
570575

571576
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);

drivers/irqchip/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
109109
obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
110110
obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o
111111
obj-$(CONFIG_TI_PRUSS_INTC) += irq-pruss-intc.o
112-
obj-$(CONFIG_IRQ_LOONGARCH_CPU) += irq-loongarch-cpu.o
112+
obj-$(CONFIG_IRQ_LOONGARCH_CPU) += irq-loongarch-cpu.o irq-loongarch-avec.o
113113
obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o
114114
obj-$(CONFIG_LOONGSON_EIOINTC) += irq-loongson-eiointc.o
115115
obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o

0 commit comments

Comments
 (0)