diff options
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-loongarch-cpu.c | 30 | ||||
-rw-r--r-- | drivers/irqchip/irq-loongson-eiointc.c | 62 | ||||
-rw-r--r-- | drivers/irqchip/irq-loongson-pch-pic.c | 18 |
3 files changed, 69 insertions, 41 deletions
diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c index 741612ba6a52..fdec3e9cfacf 100644 --- a/drivers/irqchip/irq-loongarch-cpu.c +++ b/drivers/irqchip/irq-loongarch-cpu.c @@ -92,18 +92,16 @@ static const struct irq_domain_ops loongarch_cpu_intc_irq_domain_ops = { .xlate = irq_domain_xlate_onecell, }; -static int __init -liointc_parse_madt(union acpi_subtable_headers *header, - const unsigned long end) +static int __init liointc_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) { struct acpi_madt_lio_pic *liointc_entry = (struct acpi_madt_lio_pic *)header; return liointc_acpi_init(irq_domain, liointc_entry); } -static int __init -eiointc_parse_madt(union acpi_subtable_headers *header, - const unsigned long end) +static int __init eiointc_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) { struct acpi_madt_eio_pic *eiointc_entry = (struct acpi_madt_eio_pic *)header; @@ -112,16 +110,24 @@ eiointc_parse_madt(union acpi_subtable_headers *header, static int __init acpi_cascade_irqdomain_init(void) { - acpi_table_parse_madt(ACPI_MADT_TYPE_LIO_PIC, - liointc_parse_madt, 0); - acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC, - eiointc_parse_madt, 0); + int r; + + r = acpi_table_parse_madt(ACPI_MADT_TYPE_LIO_PIC, liointc_parse_madt, 0); + if (r < 0) + return r; + + r = acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC, eiointc_parse_madt, 0); + if (r < 0) + return r; + return 0; } static int __init cpuintc_acpi_init(union acpi_subtable_headers *header, const unsigned long end) { + int ret; + if (irq_domain) return 0; @@ -139,9 +145,9 @@ static int __init cpuintc_acpi_init(union acpi_subtable_headers *header, set_handle_irq(&handle_cpu_irq); acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id); acpi_set_gsi_to_irq_fallback(lpic_gsi_to_irq); - acpi_cascade_irqdomain_init(); + ret = acpi_cascade_irqdomain_init(); - return 0; + return ret; } IRQCHIP_ACPI_DECLARE(cpuintc_v1, ACPI_MADT_TYPE_CORE_PIC, diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 16e9af8d8b1e..ac04aeaa2d30 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -279,9 +279,6 @@ static void acpi_set_vec_parent(int node, struct irq_domain *parent, struct acpi { int i; - if (cpu_has_flatmode) - node = cpu_to_node(node * CORES_PER_EIO_NODE); - for (i = 0; i < MAX_IO_PICS; i++) { if (node == vec_group[i].node) { vec_group[i].parent = parent; @@ -301,9 +298,8 @@ static struct irq_domain *acpi_get_vec_parent(int node, struct acpi_vector_group return NULL; } -static int __init -pch_pic_parse_madt(union acpi_subtable_headers *header, - const unsigned long end) +static int __init pch_pic_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) { struct acpi_madt_bio_pic *pchpic_entry = (struct acpi_madt_bio_pic *)header; unsigned int node = (pchpic_entry->address >> 44) & 0xf; @@ -312,37 +308,51 @@ pch_pic_parse_madt(union acpi_subtable_headers *header, if (parent) return pch_pic_acpi_init(parent, pchpic_entry); - return -EINVAL; + return 0; } -static int __init -pch_msi_parse_madt(union acpi_subtable_headers *header, - const unsigned long end) +static int __init pch_msi_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) { + struct irq_domain *parent; struct acpi_madt_msi_pic *pchmsi_entry = (struct acpi_madt_msi_pic *)header; - struct irq_domain *parent = acpi_get_vec_parent(eiointc_priv[nr_pics - 1]->node, msi_group); + int node; + + if (cpu_has_flatmode) + node = cpu_to_node(eiointc_priv[nr_pics - 1]->node * CORES_PER_EIO_NODE); + else + node = eiointc_priv[nr_pics - 1]->node; + + parent = acpi_get_vec_parent(node, msi_group); if (parent) return pch_msi_acpi_init(parent, pchmsi_entry); - return -EINVAL; + return 0; } static int __init acpi_cascade_irqdomain_init(void) { - acpi_table_parse_madt(ACPI_MADT_TYPE_BIO_PIC, - pch_pic_parse_madt, 0); - acpi_table_parse_madt(ACPI_MADT_TYPE_MSI_PIC, - pch_msi_parse_madt, 1); + int r; + + r = acpi_table_parse_madt(ACPI_MADT_TYPE_BIO_PIC, pch_pic_parse_madt, 0); + if (r < 0) + return r; + + r = acpi_table_parse_madt(ACPI_MADT_TYPE_MSI_PIC, pch_msi_parse_madt, 1); + if (r < 0) + return r; + return 0; } int __init eiointc_acpi_init(struct irq_domain *parent, struct acpi_madt_eio_pic *acpi_eiointc) { - int i, parent_irq; + int i, ret, parent_irq; unsigned long node_map; struct eiointc_priv *priv; + int node; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) @@ -380,15 +390,21 @@ int __init eiointc_acpi_init(struct irq_domain *parent, parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade); irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv); - cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING, + if (nr_pics == 1) { + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING, "irqchip/loongarch/intc:starting", eiointc_router_init, NULL); + } - acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, pch_group); - acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, msi_group); - acpi_cascade_irqdomain_init(); - - return 0; + if (cpu_has_flatmode) + node = cpu_to_node(acpi_eiointc->node * CORES_PER_EIO_NODE); + else + node = acpi_eiointc->node; + acpi_set_vec_parent(node, priv->eiointc_domain, pch_group); + acpi_set_vec_parent(node, priv->eiointc_domain, msi_group); + ret = acpi_cascade_irqdomain_init(); + + return ret; out_free_handle: irq_domain_free_fwnode(priv->domain_handle); diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index 03493cda65a3..679e2b68e6e9 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -328,9 +328,8 @@ int find_pch_pic(u32 gsi) return -1; } -static int __init -pch_lpc_parse_madt(union acpi_subtable_headers *header, - const unsigned long end) +static int __init pch_lpc_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) { struct acpi_madt_lpc_pic *pchlpc_entry = (struct acpi_madt_lpc_pic *)header; @@ -339,8 +338,12 @@ pch_lpc_parse_madt(union acpi_subtable_headers *header, static int __init acpi_cascade_irqdomain_init(void) { - acpi_table_parse_madt(ACPI_MADT_TYPE_LPC_PIC, - pch_lpc_parse_madt, 0); + int r; + + r = acpi_table_parse_madt(ACPI_MADT_TYPE_LPC_PIC, pch_lpc_parse_madt, 0); + if (r < 0) + return r; + return 0; } @@ -350,6 +353,9 @@ int __init pch_pic_acpi_init(struct irq_domain *parent, int ret, vec_base; struct fwnode_handle *domain_handle; + if (find_pch_pic(acpi_pchpic->gsi_base) >= 0) + return 0; + vec_base = acpi_pchpic->gsi_base - GSI_MIN_PCH_IRQ; domain_handle = irq_domain_alloc_fwnode(&acpi_pchpic->address); @@ -367,7 +373,7 @@ int __init pch_pic_acpi_init(struct irq_domain *parent, } if (acpi_pchpic->id == 0) - acpi_cascade_irqdomain_init(); + ret = acpi_cascade_irqdomain_init(); return ret; } |