blob: 5cf486c78be35f1609088f5cb7a6c0693b5e6ff6 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
2index 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