Skip to content

Commit 0fa72ed

Browse files
author
Marc Zyngier
committed
Merge branch irq/loongarch into irq/irqchip-next
* irq/loongarch: : . : Merge the long awaited IRQ support for the LoongArch architecture. : : From the cover letter: : : "Currently, LoongArch based processors (e.g. Loongson-3A5000) : can only work together with LS7A chipsets. The irq chips in : LoongArch computers include CPUINTC (CPU Core Interrupt : Controller), LIOINTC (Legacy I/O Interrupt Controller), : EIOINTC (Extended I/O Interrupt Controller), PCH-PIC (Main : Interrupt Controller in LS7A chipset), PCH-LPC (LPC Interrupt : Controller in LS7A chipset) and PCH-MSI (MSI Interrupt Controller)." : : Note that this comes with non-official, arch private ACPICA : definitions until the official ACPICA update is realeased. : . irqchip / ACPI: Introduce ACPI_IRQ_MODEL_LPIC for LoongArch irqchip: Add LoongArch CPU interrupt controller support irqchip: Add Loongson Extended I/O interrupt controller support irqchip/loongson-liointc: Add ACPI init support irqchip/loongson-pch-msi: Add ACPI init support irqchip/loongson-pch-pic: Add ACPI init support irqchip: Add Loongson PCH LPC controller support LoongArch: Prepare to support multiple pch-pic and pch-msi irqdomain LoongArch: Use ACPI_GENERIC_GSI for gsi handling genirq/generic_chip: Export irq_unmap_generic_chip ACPI: irq: Allow acpi_gsi_to_irq() to have an arch-specific fallback APCI: irq: Add support for multiple GSI domains LoongArch: Provisionally add ACPICA data structures Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 2b0d7ab + e8bba72 commit 0fa72ed

File tree

23 files changed

+1450
-279
lines changed

23 files changed

+1450
-279
lines changed

arch/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
config LOONGARCH
33
bool
44
default y
5+
select ACPI_GENERIC_GSI if ACPI
56
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
67
select ARCH_BINFMT_ELF_STATE
78
select ARCH_ENABLE_MEMORY_HOTPLUG

arch/loongarch/include/asm/acpi.h

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,148 @@ static inline bool acpi_has_cpu_in_madt(void)
3131

3232
extern struct list_head acpi_wakeup_device_list;
3333

34+
/*
35+
* Temporary definitions until the core ACPICA code gets updated (see
36+
* 1656837932-18257-1-git-send-email-lvjianmin@loongson.cn and its
37+
* follow-ups for the "rationale").
38+
*
39+
* Once the "legal reasons" are cleared and that the code is merged,
40+
* this can be dropped entierely.
41+
*/
42+
#if (ACPI_CA_VERSION == 0x20220331 && !defined(LOONGARCH_ACPICA_EXT))
43+
44+
#define LOONGARCH_ACPICA_EXT 1
45+
46+
#define ACPI_MADT_TYPE_CORE_PIC 17
47+
#define ACPI_MADT_TYPE_LIO_PIC 18
48+
#define ACPI_MADT_TYPE_HT_PIC 19
49+
#define ACPI_MADT_TYPE_EIO_PIC 20
50+
#define ACPI_MADT_TYPE_MSI_PIC 21
51+
#define ACPI_MADT_TYPE_BIO_PIC 22
52+
#define ACPI_MADT_TYPE_LPC_PIC 23
53+
54+
/* Values for Version field above */
55+
56+
enum acpi_madt_core_pic_version {
57+
ACPI_MADT_CORE_PIC_VERSION_NONE = 0,
58+
ACPI_MADT_CORE_PIC_VERSION_V1 = 1,
59+
ACPI_MADT_CORE_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
60+
};
61+
62+
enum acpi_madt_lio_pic_version {
63+
ACPI_MADT_LIO_PIC_VERSION_NONE = 0,
64+
ACPI_MADT_LIO_PIC_VERSION_V1 = 1,
65+
ACPI_MADT_LIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
66+
};
67+
68+
enum acpi_madt_eio_pic_version {
69+
ACPI_MADT_EIO_PIC_VERSION_NONE = 0,
70+
ACPI_MADT_EIO_PIC_VERSION_V1 = 1,
71+
ACPI_MADT_EIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
72+
};
73+
74+
enum acpi_madt_ht_pic_version {
75+
ACPI_MADT_HT_PIC_VERSION_NONE = 0,
76+
ACPI_MADT_HT_PIC_VERSION_V1 = 1,
77+
ACPI_MADT_HT_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
78+
};
79+
80+
enum acpi_madt_bio_pic_version {
81+
ACPI_MADT_BIO_PIC_VERSION_NONE = 0,
82+
ACPI_MADT_BIO_PIC_VERSION_V1 = 1,
83+
ACPI_MADT_BIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
84+
};
85+
86+
enum acpi_madt_msi_pic_version {
87+
ACPI_MADT_MSI_PIC_VERSION_NONE = 0,
88+
ACPI_MADT_MSI_PIC_VERSION_V1 = 1,
89+
ACPI_MADT_MSI_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
90+
};
91+
92+
enum acpi_madt_lpc_pic_version {
93+
ACPI_MADT_LPC_PIC_VERSION_NONE = 0,
94+
ACPI_MADT_LPC_PIC_VERSION_V1 = 1,
95+
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
96+
};
97+
98+
#pragma pack(1)
99+
100+
/* Core Interrupt Controller */
101+
102+
struct acpi_madt_core_pic {
103+
struct acpi_subtable_header header;
104+
u8 version;
105+
u32 processor_id;
106+
u32 core_id;
107+
u32 flags;
108+
};
109+
110+
/* Legacy I/O Interrupt Controller */
111+
112+
struct acpi_madt_lio_pic {
113+
struct acpi_subtable_header header;
114+
u8 version;
115+
u64 address;
116+
u16 size;
117+
u8 cascade[2];
118+
u32 cascade_map[2];
119+
};
120+
121+
/* Extend I/O Interrupt Controller */
122+
123+
struct acpi_madt_eio_pic {
124+
struct acpi_subtable_header header;
125+
u8 version;
126+
u8 cascade;
127+
u8 node;
128+
u64 node_map;
129+
};
130+
131+
/* HT Interrupt Controller */
132+
133+
struct acpi_madt_ht_pic {
134+
struct acpi_subtable_header header;
135+
u8 version;
136+
u64 address;
137+
u16 size;
138+
u8 cascade[8];
139+
};
140+
141+
/* Bridge I/O Interrupt Controller */
142+
143+
struct acpi_madt_bio_pic {
144+
struct acpi_subtable_header header;
145+
u8 version;
146+
u64 address;
147+
u16 size;
148+
u16 id;
149+
u16 gsi_base;
150+
};
151+
152+
/* MSI Interrupt Controller */
153+
154+
struct acpi_madt_msi_pic {
155+
struct acpi_subtable_header header;
156+
u8 version;
157+
u64 msg_address;
158+
u32 start;
159+
u32 count;
160+
};
161+
162+
/* LPC Interrupt Controller */
163+
164+
struct acpi_madt_lpc_pic {
165+
struct acpi_subtable_header header;
166+
u8 version;
167+
u64 address;
168+
u16 size;
169+
u8 cascade;
170+
};
171+
172+
#pragma pack()
173+
174+
#endif
175+
34176
#endif /* !CONFIG_ACPI */
35177

36178
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT

arch/loongarch/include/asm/irq.h

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ static inline bool on_irq_stack(int cpu, unsigned long sp)
3535
return (low <= sp && sp <= high);
3636
}
3737

38-
int get_ipi_irq(void);
39-
int get_pmc_irq(void);
40-
int get_timer_irq(void);
4138
void spurious_interrupt(void);
4239

4340
#define NR_IRQS_LEGACY 16
@@ -48,6 +45,14 @@ void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool exclude_sel
4845
#define MAX_IO_PICS 2
4946
#define NR_IRQS (64 + (256 * MAX_IO_PICS))
5047

48+
struct acpi_vector_group {
49+
int node;
50+
int pci_segment;
51+
struct irq_domain *parent;
52+
};
53+
extern struct acpi_vector_group pch_group[MAX_IO_PICS];
54+
extern struct acpi_vector_group msi_group[MAX_IO_PICS];
55+
5156
#define CORES_PER_EIO_NODE 4
5257

5358
#define LOONGSON_CPU_UART0_VEC 10 /* CPU UART0 */
@@ -79,37 +84,36 @@ void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool exclude_sel
7984
extern int find_pch_pic(u32 gsi);
8085
extern int eiointc_get_node(int id);
8186

82-
static inline void eiointc_enable(void)
83-
{
84-
uint64_t misc;
85-
86-
misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
87-
misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
88-
iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
89-
}
90-
9187
struct acpi_madt_lio_pic;
9288
struct acpi_madt_eio_pic;
9389
struct acpi_madt_ht_pic;
9490
struct acpi_madt_bio_pic;
9591
struct acpi_madt_msi_pic;
9692
struct acpi_madt_lpc_pic;
9793

98-
struct irq_domain *loongarch_cpu_irq_init(void);
99-
100-
struct irq_domain *liointc_acpi_init(struct irq_domain *parent,
94+
int liointc_acpi_init(struct irq_domain *parent,
10195
struct acpi_madt_lio_pic *acpi_liointc);
102-
struct irq_domain *eiointc_acpi_init(struct irq_domain *parent,
96+
int eiointc_acpi_init(struct irq_domain *parent,
10397
struct acpi_madt_eio_pic *acpi_eiointc);
10498

10599
struct irq_domain *htvec_acpi_init(struct irq_domain *parent,
106100
struct acpi_madt_ht_pic *acpi_htvec);
107-
struct irq_domain *pch_lpc_acpi_init(struct irq_domain *parent,
101+
int pch_lpc_acpi_init(struct irq_domain *parent,
108102
struct acpi_madt_lpc_pic *acpi_pchlpc);
109-
struct irq_domain *pch_msi_acpi_init(struct irq_domain *parent,
103+
#if IS_ENABLED(CONFIG_LOONGSON_PCH_MSI)
104+
int pch_msi_acpi_init(struct irq_domain *parent,
110105
struct acpi_madt_msi_pic *acpi_pchmsi);
111-
struct irq_domain *pch_pic_acpi_init(struct irq_domain *parent,
106+
#else
107+
static inline int pch_msi_acpi_init(struct irq_domain *parent,
108+
struct acpi_madt_msi_pic *acpi_pchmsi)
109+
{
110+
return 0;
111+
}
112+
#endif
113+
int pch_pic_acpi_init(struct irq_domain *parent,
112114
struct acpi_madt_bio_pic *acpi_pchpic);
115+
int find_pch_pic(u32 gsi);
116+
struct fwnode_handle *get_pch_msi_handle(int pci_segment);
113117

114118
extern struct acpi_madt_lio_pic *acpi_liointc;
115119
extern struct acpi_madt_eio_pic *acpi_eiointc[MAX_IO_PICS];
@@ -119,11 +123,10 @@ extern struct acpi_madt_lpc_pic *acpi_pchlpc;
119123
extern struct acpi_madt_msi_pic *acpi_pchmsi[MAX_IO_PICS];
120124
extern struct acpi_madt_bio_pic *acpi_pchpic[MAX_IO_PICS];
121125

122-
extern struct irq_domain *cpu_domain;
123-
extern struct irq_domain *liointc_domain;
124-
extern struct irq_domain *pch_lpc_domain;
125-
extern struct irq_domain *pch_msi_domain[MAX_IO_PICS];
126-
extern struct irq_domain *pch_pic_domain[MAX_IO_PICS];
126+
extern struct fwnode_handle *cpuintc_handle;
127+
extern struct fwnode_handle *liointc_handle;
128+
extern struct fwnode_handle *pch_lpc_handle;
129+
extern struct fwnode_handle *pch_pic_handle[MAX_IO_PICS];
127130

128131
extern irqreturn_t loongson3_ipi_interrupt(int irq, void *dev);
129132

arch/loongarch/kernel/acpi.c

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,78 +25,13 @@ EXPORT_SYMBOL(acpi_pci_disabled);
2525
int acpi_strict = 1; /* We have no workarounds on LoongArch */
2626
int num_processors;
2727
int disabled_cpus;
28-
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
2928

3029
u64 acpi_saved_sp;
3130

3231
#define MAX_CORE_PIC 256
3332

3433
#define PREFIX "ACPI: "
3534

36-
int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
37-
{
38-
if (irqp != NULL)
39-
*irqp = acpi_register_gsi(NULL, gsi, -1, -1);
40-
return (*irqp >= 0) ? 0 : -EINVAL;
41-
}
42-
EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
43-
44-
int acpi_isa_irq_to_gsi(unsigned int isa_irq, u32 *gsi)
45-
{
46-
if (gsi)
47-
*gsi = isa_irq;
48-
return 0;
49-
}
50-
51-
/*
52-
* success: return IRQ number (>=0)
53-
* failure: return < 0
54-
*/
55-
int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
56-
{
57-
struct irq_fwspec fwspec;
58-
59-
switch (gsi) {
60-
case GSI_MIN_CPU_IRQ ... GSI_MAX_CPU_IRQ:
61-
fwspec.fwnode = liointc_domain->fwnode;
62-
fwspec.param[0] = gsi - GSI_MIN_CPU_IRQ;
63-
fwspec.param_count = 1;
64-
65-
return irq_create_fwspec_mapping(&fwspec);
66-
67-
case GSI_MIN_LPC_IRQ ... GSI_MAX_LPC_IRQ:
68-
if (!pch_lpc_domain)
69-
return -EINVAL;
70-
71-
fwspec.fwnode = pch_lpc_domain->fwnode;
72-
fwspec.param[0] = gsi - GSI_MIN_LPC_IRQ;
73-
fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
74-
fwspec.param_count = 2;
75-
76-
return irq_create_fwspec_mapping(&fwspec);
77-
78-
case GSI_MIN_PCH_IRQ ... GSI_MAX_PCH_IRQ:
79-
if (!pch_pic_domain[0])
80-
return -EINVAL;
81-
82-
fwspec.fwnode = pch_pic_domain[0]->fwnode;
83-
fwspec.param[0] = gsi - GSI_MIN_PCH_IRQ;
84-
fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
85-
fwspec.param_count = 2;
86-
87-
return irq_create_fwspec_mapping(&fwspec);
88-
}
89-
90-
return -EINVAL;
91-
}
92-
EXPORT_SYMBOL_GPL(acpi_register_gsi);
93-
94-
void acpi_unregister_gsi(u32 gsi)
95-
{
96-
97-
}
98-
EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
99-
10035
void __init __iomem * __acpi_map_table(unsigned long phys, unsigned long size)
10136
{
10237

0 commit comments

Comments
 (0)