developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 1 | diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c |
| 2 | index 2a54fa7a3..132b3204c 100644 |
| 3 | --- a/drivers/pci/controller/pcie-mediatek.c |
| 4 | +++ b/drivers/pci/controller/pcie-mediatek.c |
| 5 | @@ -446,24 +446,24 @@ static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int vir |
| 6 | unsigned int nr_irqs, void *args) |
| 7 | { |
| 8 | struct mtk_pcie_port *port = domain->host_data; |
| 9 | - unsigned long bit; |
| 10 | + int bit, i; |
| 11 | |
| 12 | - WARN_ON(nr_irqs != 1); |
| 13 | mutex_lock(&port->lock); |
| 14 | |
| 15 | - bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); |
| 16 | - if (bit >= MTK_MSI_IRQS_NUM) { |
| 17 | + bit = bitmap_find_free_region(port->msi_irq_in_use, MTK_MSI_IRQS_NUM, |
| 18 | + order_base_2(nr_irqs)); |
| 19 | + if (bit < 0) { |
| 20 | mutex_unlock(&port->lock); |
| 21 | return -ENOSPC; |
| 22 | } |
| 23 | |
| 24 | - __set_bit(bit, port->msi_irq_in_use); |
| 25 | - |
| 26 | mutex_unlock(&port->lock); |
| 27 | |
| 28 | - irq_domain_set_info(domain, virq, bit, &mtk_msi_bottom_irq_chip, |
| 29 | - domain->host_data, handle_edge_irq, |
| 30 | - NULL, NULL); |
| 31 | + for (i = 0; i < nr_irqs; i++) { |
| 32 | + irq_domain_set_info(domain, virq + i, bit + i, |
| 33 | + &mtk_msi_bottom_irq_chip, domain->host_data, |
| 34 | + handle_edge_irq, NULL, NULL); |
| 35 | + } |
| 36 | |
| 37 | return 0; |
| 38 | } |
| 39 | @@ -501,7 +501,7 @@ static struct irq_chip mtk_msi_irq_chip = { |
| 40 | |
| 41 | static struct msi_domain_info mtk_msi_domain_info = { |
| 42 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | |
| 43 | - MSI_FLAG_PCI_MSIX), |
| 44 | + MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), |
| 45 | .chip = &mtk_msi_irq_chip, |
| 46 | }; |
| 47 | |
| 48 | @@ -633,14 +633,14 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) |
| 49 | if (status & MSI_STATUS){ |
| 50 | unsigned long imsi_status; |
| 51 | |
| 52 | + /* Clear MSI interrupt status */ |
| 53 | + writel(MSI_STATUS, port->base + PCIE_INT_STATUS); |
| 54 | while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { |
| 55 | for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { |
| 56 | virq = irq_find_mapping(port->inner_domain, bit); |
| 57 | generic_handle_irq(virq); |
| 58 | } |
| 59 | } |
| 60 | - /* Clear MSI interrupt status */ |
| 61 | - writel(MSI_STATUS, port->base + PCIE_INT_STATUS); |
| 62 | } |
| 63 | } |
| 64 | |