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 /drivers/pci/host | |
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>
Diffstat (limited to 'drivers/pci/host')
-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, |