Skip to content

Commit 63ab33c

Browse files
author
Marc Zyngier
committed
Merge branch irq/loongarch-acpi into irq/irqchip-next
* irq/loongarch-acpi: : . : More APCI fixes and improvements for the LoongArch architecture: : : - Work around trigger type for INTx interrupts described : via ACPI (Jianmin Lv). : : - ACPI support got the HTVEC controller (Huacai Chen) : : - Suspend/resume across the board (Huacai Chen) : : - Fixes and random cleanups : . irqchip/loongarch: Adjust acpi_cascade_irqdomain_init() and sub-routines irqchip/loongson-pch-lpc: Add suspend/resume support irqchip/loongson-pch-pic: Add suspend/resume support irqchip/loongson-eiointc: Add suspend/resume support irqchip/loongson-htvec: Add suspend/resume support irqchip/loongson-htvec: Add ACPI init support irqchip/loongson-liointc: Support to set IRQ type for ACPI path irqchip/loongson-pch-pic: Support to set IRQ type for ACPI path irqchip/loongson-pch-pic: Fix translate callback for DT path ACPI / PCI: fix LPIC IRQ model default PCI IRQ polarity Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 247f34f + 3d12938 commit 63ab33c

9 files changed

Lines changed: 337 additions & 74 deletions

File tree

arch/loongarch/include/asm/irq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int liointc_acpi_init(struct irq_domain *parent,
9393
int eiointc_acpi_init(struct irq_domain *parent,
9494
struct acpi_madt_eio_pic *acpi_eiointc);
9595

96-
struct irq_domain *htvec_acpi_init(struct irq_domain *parent,
96+
int htvec_acpi_init(struct irq_domain *parent,
9797
struct acpi_madt_ht_pic *acpi_htvec);
9898
int pch_lpc_acpi_init(struct irq_domain *parent,
9999
struct acpi_madt_lpc_pic *acpi_pchlpc);

drivers/acpi/pci_irq.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
387387
u8 pin;
388388
int triggering = ACPI_LEVEL_SENSITIVE;
389389
/*
390-
* On ARM systems with the GIC interrupt model, level interrupts
390+
* On ARM systems with the GIC interrupt model, or LoongArch
391+
* systems with the LPIC interrupt model, level interrupts
391392
* are always polarity high by specification; PCI legacy
392393
* IRQs lines are inverted before reaching the interrupt
393394
* controller and must therefore be considered active high
394395
* as default.
395396
*/
396-
int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ?
397+
int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ||
398+
acpi_irq_model == ACPI_IRQ_MODEL_LPIC ?
397399
ACPI_ACTIVE_HIGH : ACPI_ACTIVE_LOW;
398400
char *link = NULL;
399401
char link_desc[16];

drivers/irqchip/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ config IRQ_LOONGARCH_CPU
576576
select GENERIC_IRQ_CHIP
577577
select IRQ_DOMAIN
578578
select GENERIC_IRQ_EFFECTIVE_AFF_MASK
579+
select LOONGSON_HTVEC
579580
select LOONGSON_LIOINTC
580581
select LOONGSON_EIOINTC
581582
select LOONGSON_PCH_PIC

drivers/irqchip/irq-loongarch-cpu.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,16 @@ static const struct irq_domain_ops loongarch_cpu_intc_irq_domain_ops = {
9292
.xlate = irq_domain_xlate_onecell,
9393
};
9494

95-
static int __init
96-
liointc_parse_madt(union acpi_subtable_headers *header,
97-
const unsigned long end)
95+
static int __init liointc_parse_madt(union acpi_subtable_headers *header,
96+
const unsigned long end)
9897
{
9998
struct acpi_madt_lio_pic *liointc_entry = (struct acpi_madt_lio_pic *)header;
10099

101100
return liointc_acpi_init(irq_domain, liointc_entry);
102101
}
103102

104-
static int __init
105-
eiointc_parse_madt(union acpi_subtable_headers *header,
106-
const unsigned long end)
103+
static int __init eiointc_parse_madt(union acpi_subtable_headers *header,
104+
const unsigned long end)
107105
{
108106
struct acpi_madt_eio_pic *eiointc_entry = (struct acpi_madt_eio_pic *)header;
109107

@@ -112,16 +110,24 @@ eiointc_parse_madt(union acpi_subtable_headers *header,
112110

113111
static int __init acpi_cascade_irqdomain_init(void)
114112
{
115-
acpi_table_parse_madt(ACPI_MADT_TYPE_LIO_PIC,
116-
liointc_parse_madt, 0);
117-
acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC,
118-
eiointc_parse_madt, 0);
113+
int r;
114+
115+
r = acpi_table_parse_madt(ACPI_MADT_TYPE_LIO_PIC, liointc_parse_madt, 0);
116+
if (r < 0)
117+
return r;
118+
119+
r = acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC, eiointc_parse_madt, 0);
120+
if (r < 0)
121+
return r;
122+
119123
return 0;
120124
}
121125

122126
static int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
123127
const unsigned long end)
124128
{
129+
int ret;
130+
125131
if (irq_domain)
126132
return 0;
127133

@@ -139,9 +145,9 @@ static int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
139145
set_handle_irq(&handle_cpu_irq);
140146
acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id);
141147
acpi_set_gsi_to_irq_fallback(lpic_gsi_to_irq);
142-
acpi_cascade_irqdomain_init();
148+
ret = acpi_cascade_irqdomain_init();
143149

144-
return 0;
150+
return ret;
145151
}
146152

147153
IRQCHIP_ACPI_DECLARE(cpuintc_v1, ACPI_MADT_TYPE_CORE_PIC,

drivers/irqchip/irq-loongson-eiointc.c

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/of_address.h>
1818
#include <linux/of_irq.h>
1919
#include <linux/of_platform.h>
20+
#include <linux/syscore_ops.h>
2021

2122
#define EIOINTC_REG_NODEMAP 0x14a0
2223
#define EIOINTC_REG_IPMAP 0x14c0
@@ -301,9 +302,39 @@ static struct irq_domain *acpi_get_vec_parent(int node, struct acpi_vector_group
301302
return NULL;
302303
}
303304

304-
static int __init
305-
pch_pic_parse_madt(union acpi_subtable_headers *header,
306-
const unsigned long end)
305+
static int eiointc_suspend(void)
306+
{
307+
return 0;
308+
}
309+
310+
static void eiointc_resume(void)
311+
{
312+
int i, j;
313+
struct irq_desc *desc;
314+
struct irq_data *irq_data;
315+
316+
eiointc_router_init(0);
317+
318+
for (i = 0; i < nr_pics; i++) {
319+
for (j = 0; j < VEC_COUNT; j++) {
320+
desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
321+
if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
322+
raw_spin_lock(&desc->lock);
323+
irq_data = &desc->irq_data;
324+
eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0);
325+
raw_spin_unlock(&desc->lock);
326+
}
327+
}
328+
}
329+
}
330+
331+
static struct syscore_ops eiointc_syscore_ops = {
332+
.suspend = eiointc_suspend,
333+
.resume = eiointc_resume,
334+
};
335+
336+
static int __init pch_pic_parse_madt(union acpi_subtable_headers *header,
337+
const unsigned long end)
307338
{
308339
struct acpi_madt_bio_pic *pchpic_entry = (struct acpi_madt_bio_pic *)header;
309340
unsigned int node = (pchpic_entry->address >> 44) & 0xf;
@@ -315,9 +346,8 @@ pch_pic_parse_madt(union acpi_subtable_headers *header,
315346
return -EINVAL;
316347
}
317348

318-
static int __init
319-
pch_msi_parse_madt(union acpi_subtable_headers *header,
320-
const unsigned long end)
349+
static int __init pch_msi_parse_madt(union acpi_subtable_headers *header,
350+
const unsigned long end)
321351
{
322352
struct acpi_madt_msi_pic *pchmsi_entry = (struct acpi_madt_msi_pic *)header;
323353
struct irq_domain *parent = acpi_get_vec_parent(eiointc_priv[nr_pics - 1]->node, msi_group);
@@ -330,17 +360,23 @@ pch_msi_parse_madt(union acpi_subtable_headers *header,
330360

331361
static int __init acpi_cascade_irqdomain_init(void)
332362
{
333-
acpi_table_parse_madt(ACPI_MADT_TYPE_BIO_PIC,
334-
pch_pic_parse_madt, 0);
335-
acpi_table_parse_madt(ACPI_MADT_TYPE_MSI_PIC,
336-
pch_msi_parse_madt, 1);
363+
int r;
364+
365+
r = acpi_table_parse_madt(ACPI_MADT_TYPE_BIO_PIC, pch_pic_parse_madt, 0);
366+
if (r < 0)
367+
return r;
368+
369+
r = acpi_table_parse_madt(ACPI_MADT_TYPE_MSI_PIC, pch_msi_parse_madt, 1);
370+
if (r < 0)
371+
return r;
372+
337373
return 0;
338374
}
339375

340376
int __init eiointc_acpi_init(struct irq_domain *parent,
341377
struct acpi_madt_eio_pic *acpi_eiointc)
342378
{
343-
int i, parent_irq;
379+
int i, ret, parent_irq;
344380
unsigned long node_map;
345381
struct eiointc_priv *priv;
346382

@@ -380,15 +416,16 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
380416
parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade);
381417
irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
382418

419+
register_syscore_ops(&eiointc_syscore_ops);
383420
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
384421
"irqchip/loongarch/intc:starting",
385422
eiointc_router_init, NULL);
386423

387424
acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, pch_group);
388425
acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, msi_group);
389-
acpi_cascade_irqdomain_init();
426+
ret = acpi_cascade_irqdomain_init();
390427

391-
return 0;
428+
return ret;
392429

393430
out_free_handle:
394431
irq_domain_free_fwnode(priv->domain_handle);

0 commit comments

Comments
 (0)