diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h index ee52fb1e99631653e3e40d6998afd159a7e5986d..eefb30c33ba33e1de9153676e8653d851bfa1c6c 100644 --- a/arch/loongarch/include/asm/setup.h +++ b/arch/loongarch/include/asm/setup.h @@ -12,6 +12,7 @@ #define VECSIZE 0x200 +extern bool disable_pci_irq_limit; extern unsigned long eentry; extern unsigned long tlbrentry; extern char init_command_line[COMMAND_LINE_SIZE]; diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c index 5c9dcc488e21ee08a6a717753bd654053f88bd3c..b9202fdb6d925047f56ace77e415219a337c9f45 100644 --- a/drivers/irqchip/irq-loongarch-avec.c +++ b/drivers/irqchip/irq-loongarch-avec.c @@ -30,6 +30,7 @@ struct pending_list { struct list_head head; }; +bool disable_pci_irq_limit; static struct cpumask intersect_mask; static DEFINE_PER_CPU(struct pending_list, pending_list); #endif @@ -83,7 +84,7 @@ static void avecintc_sync(struct avecintc_data *adata) plist = per_cpu_ptr(&pending_list, adata->prev_cpu); list_add_tail(&adata->entry, &plist->head); adata->moving = 1; - smp_ops.send_ipi_single(adata->prev_cpu, SMP_CLEAR_VECTOR); + smp_ops.send_ipi_single(adata->prev_cpu, ACTION_CLEAR_VECTOR); } } @@ -132,6 +133,7 @@ static int avecintc_set_affinity(struct irq_data *data, const struct cpumask *de static int avecintc_cpu_online(unsigned int cpu) { + long value; if (!loongarch_avec.vector_matrix) return 0; @@ -141,6 +143,10 @@ static int avecintc_cpu_online(unsigned int cpu) pending_list_init(cpu); + value = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC); + value |= IOCSR_MISC_FUNC_AVEC_EN; + iocsr_write64(value, LOONGARCH_IOCSR_MISC_FUNC); + raw_spin_unlock(&loongarch_avec.lock); return 0; @@ -193,7 +199,7 @@ void complete_irq_moving(void) } if (isr & (1UL << (vector % VECTORS_PER_REG))) { - smp_ops.send_ipi_single(cpu, SMP_CLEAR_VECTOR); + smp_ops.send_ipi_single(cpu, ACTION_CLEAR_VECTOR); continue; } list_del(&adata->entry); @@ -365,6 +371,7 @@ static int __init avecintc_init(struct irq_domain *parent) int ret, parent_irq; unsigned long value; + disable_pci_irq_limit = true; raw_spin_lock_init(&loongarch_avec.lock); loongarch_avec.fwnode = irq_domain_alloc_named_fwnode("AVECINTC"); diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index e6ac06d94fb592ec779d5e695c1958839a6ff0a6..3bd6b9d20b091152822027ad673d6715dcf37a2b 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -409,6 +409,8 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, } #ifdef CONFIG_LOONGARCH +#include + static unsigned int pci_irq_numbers = 32; static int __init pci_irq_limit(char *str) @@ -430,9 +432,11 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, int rc; #ifdef CONFIG_LOONGARCH - if (maxvec > 32) { - maxvec = pci_irq_numbers; - minvec = min_t(int, pci_irq_numbers, minvec); + if (!disable_pci_irq_limit) { + if (maxvec > 32) { + maxvec = pci_irq_numbers; + minvec = min_t(int, pci_irq_numbers, minvec); + } } #endif @@ -807,9 +811,11 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int int hwsize, rc, nvec = maxvec; #ifdef CONFIG_LOONGARCH - if (maxvec > 32) { - nvec = pci_irq_numbers; - minvec = min_t(int, pci_irq_numbers, minvec); + if (!disable_pci_irq_limit) { + if (maxvec > 32) { + nvec = pci_irq_numbers; + minvec = min_t(int, pci_irq_numbers, minvec); + } } #endif