diff options
| author | Honghui Zhang <honghui.zhang@mediatek.com> | 2018-05-04 01:47:33 -0400 |
|---|---|---|
| committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2018-05-21 09:43:45 -0400 |
| commit | 42fe2f91b4ebc07c815fb334ea1262e6dc23bf77 (patch) | |
| tree | 02144824061d7dce83d3fe2d945deac0b99c1cd9 | |
| parent | 101c92dc80c8947b92addb34c11ea7a47a1d2561 (diff) | |
PCI: mediatek: Implement chained IRQ handling setup
Implement irq_chip based solution for IRQs management in order to
comply with IRQ framework.
Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
| -rw-r--r-- | drivers/pci/host/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-mediatek.c | 206 |
2 files changed, 116 insertions, 91 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 0d0177ce436c..e2f323a52843 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
| @@ -194,6 +194,7 @@ config PCIE_MEDIATEK | |||
| 194 | depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST) | 194 | depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST) |
| 195 | depends on OF | 195 | depends on OF |
| 196 | depends on PCI | 196 | depends on PCI |
| 197 | depends on PCI_MSI_IRQ_DOMAIN | ||
| 197 | select PCIEPORTBUS | 198 | select PCIEPORTBUS |
| 198 | help | 199 | help |
| 199 | Say Y here if you want to enable PCIe controller support on | 200 | Say Y here if you want to enable PCIe controller support on |
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index c3dc5499d1b7..dabf10869bcd 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c | |||
| @@ -11,8 +11,10 @@ | |||
| 11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 12 | #include <linux/iopoll.h> | 12 | #include <linux/iopoll.h> |
| 13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
| 14 | #include <linux/irqchip/chained_irq.h> | ||
| 14 | #include <linux/irqdomain.h> | 15 | #include <linux/irqdomain.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/msi.h> | ||
| 16 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
| 17 | #include <linux/of_pci.h> | 19 | #include <linux/of_pci.h> |
| 18 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
| @@ -130,14 +132,12 @@ struct mtk_pcie_port; | |||
| 130 | /** | 132 | /** |
| 131 | * struct mtk_pcie_soc - differentiate between host generations | 133 | * struct mtk_pcie_soc - differentiate between host generations |
| 132 | * @need_fix_class_id: whether this host's class ID needed to be fixed or not | 134 | * @need_fix_class_id: whether this host's class ID needed to be fixed or not |
| 133 | * @has_msi: whether this host supports MSI interrupts or not | ||
| 134 | * @ops: pointer to configuration access functions | 135 | * @ops: pointer to configuration access functions |
| 135 | * @startup: pointer to controller setting functions | 136 | * @startup: pointer to controller setting functions |
| 136 | * @setup_irq: pointer to initialize IRQ functions | 137 | * @setup_irq: pointer to initialize IRQ functions |
| 137 | */ | 138 | */ |
| 138 | struct mtk_pcie_soc { | 139 | struct mtk_pcie_soc { |
| 139 | bool need_fix_class_id; | 140 | bool need_fix_class_id; |
| 140 | bool has_msi; | ||
| 141 | struct pci_ops *ops; | 141 | struct pci_ops *ops; |
| 142 | int (*startup)(struct mtk_pcie_port *port); | 142 | int (*startup)(struct mtk_pcie_port *port); |
| 143 | int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node); | 143 | int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node); |
| @@ -161,7 +161,9 @@ struct mtk_pcie_soc { | |||
| 161 | * @lane: lane count | 161 | * @lane: lane count |
| 162 | * @slot: port slot | 162 | * @slot: port slot |
| 163 | * @irq_domain: legacy INTx IRQ domain | 163 | * @irq_domain: legacy INTx IRQ domain |
| 164 | * @inner_domain: inner IRQ domain | ||
| 164 | * @msi_domain: MSI IRQ domain | 165 | * @msi_domain: MSI IRQ domain |
| 166 | * @lock: protect the msi_irq_in_use bitmap | ||
| 165 | * @msi_irq_in_use: bit map for assigned MSI IRQ | 167 | * @msi_irq_in_use: bit map for assigned MSI IRQ |
| 166 | */ | 168 | */ |
| 167 | struct mtk_pcie_port { | 169 | struct mtk_pcie_port { |
| @@ -179,7 +181,9 @@ struct mtk_pcie_port { | |||
| 179 | u32 lane; | 181 | u32 lane; |
| 180 | u32 slot; | 182 | u32 slot; |
| 181 | struct irq_domain *irq_domain; | 183 | struct irq_domain *irq_domain; |
| 184 | struct irq_domain *inner_domain; | ||
| 182 | struct irq_domain *msi_domain; | 185 | struct irq_domain *msi_domain; |
| 186 | struct mutex lock; | ||
| 183 | DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); | 187 | DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); |
| 184 | }; | 188 | }; |
| 185 | 189 | ||
| @@ -446,103 +450,130 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | |||
| 446 | return 0; | 450 | return 0; |
| 447 | } | 451 | } |
| 448 | 452 | ||
| 449 | static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port) | 453 | static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) |
| 450 | { | 454 | { |
| 451 | int msi; | 455 | struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); |
| 456 | phys_addr_t addr; | ||
| 452 | 457 | ||
| 453 | msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); | 458 | /* MT2712/MT7622 only support 32-bit MSI addresses */ |
| 454 | if (msi < MTK_MSI_IRQS_NUM) | 459 | addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); |
| 455 | set_bit(msi, port->msi_irq_in_use); | 460 | msg->address_hi = 0; |
| 456 | else | 461 | msg->address_lo = lower_32_bits(addr); |
| 457 | return -ENOSPC; | 462 | |
| 463 | msg->data = data->hwirq; | ||
| 458 | 464 | ||
| 459 | return msi; | 465 | dev_dbg(port->pcie->dev, "msi#%d address_hi %#x address_lo %#x\n", |
| 466 | (int)data->hwirq, msg->address_hi, msg->address_lo); | ||
| 460 | } | 467 | } |
| 461 | 468 | ||
| 462 | static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq) | 469 | static int mtk_msi_set_affinity(struct irq_data *irq_data, |
| 470 | const struct cpumask *mask, bool force) | ||
| 463 | { | 471 | { |
| 464 | clear_bit(hwirq, port->msi_irq_in_use); | 472 | return -EINVAL; |
| 465 | } | 473 | } |
| 466 | 474 | ||
| 467 | static int mtk_pcie_msi_setup_irq(struct msi_controller *chip, | 475 | static void mtk_msi_ack_irq(struct irq_data *data) |
| 468 | struct pci_dev *pdev, struct msi_desc *desc) | ||
| 469 | { | 476 | { |
| 470 | struct mtk_pcie_port *port; | 477 | struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); |
| 471 | struct msi_msg msg; | 478 | u32 hwirq = data->hwirq; |
| 472 | unsigned int irq; | ||
| 473 | int hwirq; | ||
| 474 | phys_addr_t msg_addr; | ||
| 475 | 479 | ||
| 476 | port = mtk_pcie_find_port(pdev->bus, pdev->devfn); | 480 | writel(1 << hwirq, port->base + PCIE_IMSI_STATUS); |
| 477 | if (!port) | 481 | } |
| 478 | return -EINVAL; | ||
| 479 | 482 | ||
| 480 | hwirq = mtk_pcie_msi_alloc(port); | 483 | static struct irq_chip mtk_msi_bottom_irq_chip = { |
| 481 | if (hwirq < 0) | 484 | .name = "MTK MSI", |
| 482 | return hwirq; | 485 | .irq_compose_msi_msg = mtk_compose_msi_msg, |
| 486 | .irq_set_affinity = mtk_msi_set_affinity, | ||
| 487 | .irq_ack = mtk_msi_ack_irq, | ||
| 488 | }; | ||
| 483 | 489 | ||
| 484 | irq = irq_create_mapping(port->msi_domain, hwirq); | 490 | static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
| 485 | if (!irq) { | 491 | unsigned int nr_irqs, void *args) |
| 486 | mtk_pcie_msi_free(port, hwirq); | 492 | { |
| 487 | return -EINVAL; | 493 | struct mtk_pcie_port *port = domain->host_data; |
| 488 | } | 494 | unsigned long bit; |
| 489 | 495 | ||
| 490 | chip->dev = &pdev->dev; | 496 | WARN_ON(nr_irqs != 1); |
| 497 | mutex_lock(&port->lock); | ||
| 491 | 498 | ||
| 492 | irq_set_msi_desc(irq, desc); | 499 | bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); |
| 500 | if (bit >= MTK_MSI_IRQS_NUM) { | ||
| 501 | mutex_unlock(&port->lock); | ||
| 502 | return -ENOSPC; | ||
| 503 | } | ||
| 493 | 504 | ||
| 494 | /* MT2712/MT7622 only support 32-bit MSI addresses */ | 505 | __set_bit(bit, port->msi_irq_in_use); |
| 495 | msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); | 506 | |
| 496 | msg.address_hi = 0; | 507 | mutex_unlock(&port->lock); |
| 497 | msg.address_lo = lower_32_bits(msg_addr); | ||
| 498 | msg.data = hwirq; | ||
| 499 | 508 | ||
| 500 | pci_write_msi_msg(irq, &msg); | 509 | irq_domain_set_info(domain, virq, bit, &mtk_msi_bottom_irq_chip, |
| 510 | domain->host_data, handle_edge_irq, | ||
| 511 | NULL, NULL); | ||
| 501 | 512 | ||
| 502 | return 0; | 513 | return 0; |
| 503 | } | 514 | } |
| 504 | 515 | ||
| 505 | static void mtk_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) | 516 | static void mtk_pcie_irq_domain_free(struct irq_domain *domain, |
| 517 | unsigned int virq, unsigned int nr_irqs) | ||
| 506 | { | 518 | { |
| 507 | struct pci_dev *pdev = to_pci_dev(chip->dev); | 519 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
| 508 | struct irq_data *d = irq_get_irq_data(irq); | 520 | struct mtk_pcie_port *port = irq_data_get_irq_chip_data(d); |
| 509 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
| 510 | struct mtk_pcie_port *port; | ||
| 511 | 521 | ||
| 512 | port = mtk_pcie_find_port(pdev->bus, pdev->devfn); | 522 | mutex_lock(&port->lock); |
| 513 | if (!port) | 523 | |
| 514 | return; | 524 | if (!test_bit(d->hwirq, port->msi_irq_in_use)) |
| 525 | dev_err(port->pcie->dev, "trying to free unused MSI#%lu\n", | ||
| 526 | d->hwirq); | ||
| 527 | else | ||
| 528 | __clear_bit(d->hwirq, port->msi_irq_in_use); | ||
| 529 | |||
| 530 | mutex_unlock(&port->lock); | ||
| 515 | 531 | ||
| 516 | irq_dispose_mapping(irq); | 532 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); |
| 517 | mtk_pcie_msi_free(port, hwirq); | ||
| 518 | } | 533 | } |
| 519 | 534 | ||
| 520 | static struct msi_controller mtk_pcie_msi_chip = { | 535 | static const struct irq_domain_ops msi_domain_ops = { |
| 521 | .setup_irq = mtk_pcie_msi_setup_irq, | 536 | .alloc = mtk_pcie_irq_domain_alloc, |
| 522 | .teardown_irq = mtk_msi_teardown_irq, | 537 | .free = mtk_pcie_irq_domain_free, |
| 523 | }; | 538 | }; |
| 524 | 539 | ||
| 525 | static struct irq_chip mtk_msi_irq_chip = { | 540 | static struct irq_chip mtk_msi_irq_chip = { |
| 526 | .name = "MTK PCIe MSI", | 541 | .name = "MTK PCIe MSI", |
| 527 | .irq_enable = pci_msi_unmask_irq, | 542 | .irq_ack = irq_chip_ack_parent, |
| 528 | .irq_disable = pci_msi_mask_irq, | 543 | .irq_mask = pci_msi_mask_irq, |
| 529 | .irq_mask = pci_msi_mask_irq, | 544 | .irq_unmask = pci_msi_unmask_irq, |
| 530 | .irq_unmask = pci_msi_unmask_irq, | ||
| 531 | }; | 545 | }; |
| 532 | 546 | ||
| 533 | static int mtk_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | 547 | static struct msi_domain_info mtk_msi_domain_info = { |
| 534 | irq_hw_number_t hwirq) | 548 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | |
| 549 | MSI_FLAG_PCI_MSIX), | ||
| 550 | .chip = &mtk_msi_irq_chip, | ||
| 551 | }; | ||
| 552 | |||
| 553 | static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port) | ||
| 535 | { | 554 | { |
| 536 | irq_set_chip_and_handler(irq, &mtk_msi_irq_chip, handle_simple_irq); | 555 | struct fwnode_handle *fwnode = of_node_to_fwnode(port->pcie->dev->of_node); |
| 537 | irq_set_chip_data(irq, domain->host_data); | 556 | |
| 557 | mutex_init(&port->lock); | ||
| 558 | |||
| 559 | port->inner_domain = irq_domain_create_linear(fwnode, MTK_MSI_IRQS_NUM, | ||
| 560 | &msi_domain_ops, port); | ||
| 561 | if (!port->inner_domain) { | ||
| 562 | dev_err(port->pcie->dev, "failed to create IRQ domain\n"); | ||
| 563 | return -ENOMEM; | ||
| 564 | } | ||
| 565 | |||
| 566 | port->msi_domain = pci_msi_create_irq_domain(fwnode, &mtk_msi_domain_info, | ||
| 567 | port->inner_domain); | ||
| 568 | if (!port->msi_domain) { | ||
| 569 | dev_err(port->pcie->dev, "failed to create MSI domain\n"); | ||
| 570 | irq_domain_remove(port->inner_domain); | ||
| 571 | return -ENOMEM; | ||
| 572 | } | ||
| 538 | 573 | ||
| 539 | return 0; | 574 | return 0; |
| 540 | } | 575 | } |
| 541 | 576 | ||
| 542 | static const struct irq_domain_ops msi_domain_ops = { | ||
| 543 | .map = mtk_pcie_msi_map, | ||
| 544 | }; | ||
| 545 | |||
| 546 | static void mtk_pcie_enable_msi(struct mtk_pcie_port *port) | 577 | static void mtk_pcie_enable_msi(struct mtk_pcie_port *port) |
| 547 | { | 578 | { |
| 548 | u32 val; | 579 | u32 val; |
| @@ -575,6 +606,7 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port, | |||
| 575 | { | 606 | { |
| 576 | struct device *dev = port->pcie->dev; | 607 | struct device *dev = port->pcie->dev; |
| 577 | struct device_node *pcie_intc_node; | 608 | struct device_node *pcie_intc_node; |
| 609 | int ret; | ||
| 578 | 610 | ||
| 579 | /* Setup INTx */ | 611 | /* Setup INTx */ |
| 580 | pcie_intc_node = of_get_next_child(node, NULL); | 612 | pcie_intc_node = of_get_next_child(node, NULL); |
| @@ -591,27 +623,28 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port, | |||
| 591 | } | 623 | } |
| 592 | 624 | ||
| 593 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 625 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
| 594 | port->msi_domain = irq_domain_add_linear(node, MTK_MSI_IRQS_NUM, | 626 | ret = mtk_pcie_allocate_msi_domains(port); |
| 595 | &msi_domain_ops, | 627 | if (ret) |
| 596 | &mtk_pcie_msi_chip); | 628 | return ret; |
| 597 | if (!port->msi_domain) { | 629 | |
| 598 | dev_err(dev, "failed to create MSI IRQ domain\n"); | ||
| 599 | return -ENODEV; | ||
| 600 | } | ||
| 601 | mtk_pcie_enable_msi(port); | 630 | mtk_pcie_enable_msi(port); |
| 602 | } | 631 | } |
| 603 | 632 | ||
| 604 | return 0; | 633 | return 0; |
| 605 | } | 634 | } |
| 606 | 635 | ||
| 607 | static irqreturn_t mtk_pcie_intr_handler(int irq, void *data) | 636 | static void mtk_pcie_intr_handler(struct irq_desc *desc) |
| 608 | { | 637 | { |
| 609 | struct mtk_pcie_port *port = (struct mtk_pcie_port *)data; | 638 | struct mtk_pcie_port *port = irq_desc_get_handler_data(desc); |
| 639 | struct irq_chip *irqchip = irq_desc_get_chip(desc); | ||
| 610 | unsigned long status; | 640 | unsigned long status; |
| 611 | u32 virq; | 641 | u32 virq; |
| 612 | u32 bit = INTX_SHIFT; | 642 | u32 bit = INTX_SHIFT; |
| 613 | 643 | ||
| 614 | while ((status = readl(port->base + PCIE_INT_STATUS)) & INTX_MASK) { | 644 | chained_irq_enter(irqchip, desc); |
| 645 | |||
| 646 | status = readl(port->base + PCIE_INT_STATUS); | ||
| 647 | if (status & INTX_MASK) { | ||
| 615 | for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { | 648 | for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { |
| 616 | /* Clear the INTx */ | 649 | /* Clear the INTx */ |
| 617 | writel(1 << bit, port->base + PCIE_INT_STATUS); | 650 | writel(1 << bit, port->base + PCIE_INT_STATUS); |
| @@ -622,14 +655,12 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void *data) | |||
| 622 | } | 655 | } |
| 623 | 656 | ||
| 624 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 657 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
| 625 | while ((status = readl(port->base + PCIE_INT_STATUS)) & MSI_STATUS) { | 658 | if (status & MSI_STATUS){ |
| 626 | unsigned long imsi_status; | 659 | unsigned long imsi_status; |
| 627 | 660 | ||
| 628 | while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { | 661 | while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { |
| 629 | for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { | 662 | for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { |
| 630 | /* Clear the MSI */ | 663 | virq = irq_find_mapping(port->inner_domain, bit); |
| 631 | writel(1 << bit, port->base + PCIE_IMSI_STATUS); | ||
| 632 | virq = irq_find_mapping(port->msi_domain, bit); | ||
| 633 | generic_handle_irq(virq); | 664 | generic_handle_irq(virq); |
| 634 | } | 665 | } |
| 635 | } | 666 | } |
| @@ -638,7 +669,9 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void *data) | |||
| 638 | } | 669 | } |
| 639 | } | 670 | } |
| 640 | 671 | ||
| 641 | return IRQ_HANDLED; | 672 | chained_irq_exit(irqchip, desc); |
| 673 | |||
| 674 | return; | ||
| 642 | } | 675 | } |
| 643 | 676 | ||
| 644 | static int mtk_pcie_setup_irq(struct mtk_pcie_port *port, | 677 | static int mtk_pcie_setup_irq(struct mtk_pcie_port *port, |
| @@ -649,20 +682,15 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port, | |||
| 649 | struct platform_device *pdev = to_platform_device(dev); | 682 | struct platform_device *pdev = to_platform_device(dev); |
| 650 | int err, irq; | 683 | int err, irq; |
| 651 | 684 | ||
| 652 | irq = platform_get_irq(pdev, port->slot); | ||
| 653 | err = devm_request_irq(dev, irq, mtk_pcie_intr_handler, | ||
| 654 | IRQF_SHARED, "mtk-pcie", port); | ||
| 655 | if (err) { | ||
| 656 | dev_err(dev, "unable to request IRQ %d\n", irq); | ||
| 657 | return err; | ||
| 658 | } | ||
| 659 | |||
| 660 | err = mtk_pcie_init_irq_domain(port, node); | 685 | err = mtk_pcie_init_irq_domain(port, node); |
| 661 | if (err) { | 686 | if (err) { |
| 662 | dev_err(dev, "failed to init PCIe IRQ domain\n"); | 687 | dev_err(dev, "failed to init PCIe IRQ domain\n"); |
| 663 | return err; | 688 | return err; |
| 664 | } | 689 | } |
| 665 | 690 | ||
| 691 | irq = platform_get_irq(pdev, port->slot); | ||
| 692 | irq_set_chained_handler_and_data(irq, mtk_pcie_intr_handler, port); | ||
| 693 | |||
| 666 | return 0; | 694 | return 0; |
| 667 | } | 695 | } |
| 668 | 696 | ||
| @@ -1096,8 +1124,6 @@ static int mtk_pcie_register_host(struct pci_host_bridge *host) | |||
| 1096 | host->map_irq = of_irq_parse_and_map_pci; | 1124 | host->map_irq = of_irq_parse_and_map_pci; |
| 1097 | host->swizzle_irq = pci_common_swizzle; | 1125 | host->swizzle_irq = pci_common_swizzle; |
| 1098 | host->sysdata = pcie; | 1126 | host->sysdata = pcie; |
| 1099 | if (IS_ENABLED(CONFIG_PCI_MSI) && pcie->soc->has_msi) | ||
| 1100 | host->msi = &mtk_pcie_msi_chip; | ||
| 1101 | 1127 | ||
| 1102 | err = pci_scan_root_bus_bridge(host); | 1128 | err = pci_scan_root_bus_bridge(host); |
| 1103 | if (err < 0) | 1129 | if (err < 0) |
| @@ -1159,7 +1185,6 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { | |||
| 1159 | }; | 1185 | }; |
| 1160 | 1186 | ||
| 1161 | static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = { | 1187 | static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = { |
| 1162 | .has_msi = true, | ||
| 1163 | .ops = &mtk_pcie_ops_v2, | 1188 | .ops = &mtk_pcie_ops_v2, |
| 1164 | .startup = mtk_pcie_startup_port_v2, | 1189 | .startup = mtk_pcie_startup_port_v2, |
| 1165 | .setup_irq = mtk_pcie_setup_irq, | 1190 | .setup_irq = mtk_pcie_setup_irq, |
| @@ -1167,7 +1192,6 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = { | |||
| 1167 | 1192 | ||
| 1168 | static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = { | 1193 | static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = { |
| 1169 | .need_fix_class_id = true, | 1194 | .need_fix_class_id = true, |
| 1170 | .has_msi = true, | ||
| 1171 | .ops = &mtk_pcie_ops_v2, | 1195 | .ops = &mtk_pcie_ops_v2, |
| 1172 | .startup = mtk_pcie_startup_port_v2, | 1196 | .startup = mtk_pcie_startup_port_v2, |
| 1173 | .setup_irq = mtk_pcie_setup_irq, | 1197 | .setup_irq = mtk_pcie_setup_irq, |
