From 05f79d73b7a11bef25ac5d500dd61d850c030989 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 May 2022 13:56:48 +0200 Subject: [PATCH] 5.17-stable patches added patches: pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch pci-aardvark-add-support-for-masking-msi-interrupts.patch pci-aardvark-add-support-for-pme-interrupts.patch pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch pci-aardvark-don-t-mask-irq-when-mapping.patch pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch pci-aardvark-enable-msi-x-support.patch pci-aardvark-fix-setting-msi-address.patch pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch pci-aardvark-update-comment-about-link-going-down-after-link-up.patch pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch --- ...for-err-interrupt-on-emulated-bridge.patch | 106 +++++++++++ ...d-support-for-masking-msi-interrupts.patch | 125 +++++++++++++ ...dvark-add-support-for-pme-interrupts.patch | 54 ++++++ ..._domain_irq-when-processing-intx-irq.patch | 38 ++++ ...aardvark-don-t-mask-irq-when-mapping.patch | 35 ++++ ...be_unused-from-advk_pcie_disable_phy.patch | 35 ++++ .../pci-aardvark-enable-msi-x-support.patch | 46 +++++ ...pci-aardvark-fix-setting-msi-address.patch | 99 ++++++++++ ...for-pme-requester-on-emulated-bridge.patch | 177 ++++++++++++++++++ ...-structures-static-driver-structures.patch | 100 ++++++++++ ...-structure-a-static-driver-structure.patch | 71 +++++++ ...pci_exp_rtsta_pme-on-emulated-bridge.patch | 59 ++++++ ...ctor-unmasking-summary-msi-interrupt.patch | 52 +++++ ...ask_ack-callback-for-intx-interrupts.patch | 37 ++++ ...core_int_-macros-with-pci_interrupt_.patch | 48 +++++ ...rite-irq-code-to-chained-irq-handler.patch | 133 +++++++++++++ ...-about-link-going-down-after-link-up.patch | 41 ++++ ...ead-of-of_node_to_fwnode-dev-of_node.patch | 47 +++++ ...a-interrupt-for-emulated-root-bridge.patch | 168 +++++++++++++++++ queue-5.17/series | 19 ++ 20 files changed, 1490 insertions(+) create mode 100644 queue-5.17/pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch create mode 100644 queue-5.17/pci-aardvark-add-support-for-masking-msi-interrupts.patch create mode 100644 queue-5.17/pci-aardvark-add-support-for-pme-interrupts.patch create mode 100644 queue-5.17/pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch create mode 100644 queue-5.17/pci-aardvark-don-t-mask-irq-when-mapping.patch create mode 100644 queue-5.17/pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch create mode 100644 queue-5.17/pci-aardvark-enable-msi-x-support.patch create mode 100644 queue-5.17/pci-aardvark-fix-setting-msi-address.patch create mode 100644 queue-5.17/pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch create mode 100644 queue-5.17/pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch create mode 100644 queue-5.17/pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch create mode 100644 queue-5.17/pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch create mode 100644 queue-5.17/pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch create mode 100644 queue-5.17/pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch create mode 100644 queue-5.17/pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch create mode 100644 queue-5.17/pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch create mode 100644 queue-5.17/pci-aardvark-update-comment-about-link-going-down-after-link-up.patch create mode 100644 queue-5.17/pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch create mode 100644 queue-5.17/pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch diff --git a/queue-5.17/pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch b/queue-5.17/pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch new file mode 100644 index 00000000000..d2749e9516c --- /dev/null +++ b/queue-5.17/pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch @@ -0,0 +1,106 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:44 +0200 +Subject: PCI: aardvark: Add support for ERR interrupt on emulated bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-12-kabel@kernel.org> + +From: Pali Rohár + +commit 3ebfefa396ebee21061fd5fa36073368ed2cd467 upstream. + +ERR interrupt is triggered when corresponding bit is unmasked in both ISR0 +and PCI_EXP_DEVCTL registers. Unmasking ERR bits in PCI_EXP_DEVCTL register +is not enough. This means that currently the ERR interrupt is never +triggered. + +Unmask ERR bits in ISR0 register at driver probe time. ERR interrupt is not +triggered until ERR bits are unmasked also in PCI_EXP_DEVCTL register, +which is done by AER driver. So it is safe to unconditionally unmask all +ERR bits in aardvark probe. + +Aardvark HW sets PCI_ERR_ROOT_AER_IRQ to zero and when corresponding bits +in ISR0 and PCI_EXP_DEVCTL are enabled, the HW triggers a generic interrupt +on GIC. Chain this interrupt to PCIe interrupt 0 with +generic_handle_domain_irq() to allow processing of ERR interrupts. + +Link: https://lore.kernel.org/r/20220110015018.26359-14-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 35 +++++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -98,6 +98,10 @@ + #define PCIE_MSG_PM_PME_MASK BIT(7) + #define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44) + #define PCIE_ISR0_MSI_INT_PENDING BIT(24) ++#define PCIE_ISR0_CORR_ERR BIT(11) ++#define PCIE_ISR0_NFAT_ERR BIT(12) ++#define PCIE_ISR0_FAT_ERR BIT(13) ++#define PCIE_ISR0_ERR_MASK GENMASK(13, 11) + #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) + #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) + #define PCIE_ISR0_ALL_MASK GENMASK(31, 0) +@@ -778,11 +782,15 @@ advk_pci_bridge_emul_base_conf_read(stru + case PCI_INTERRUPT_LINE: { + /* + * From the whole 32bit register we support reading from HW only +- * one bit: PCI_BRIDGE_CTL_BUS_RESET. ++ * two bits: PCI_BRIDGE_CTL_BUS_RESET and PCI_BRIDGE_CTL_SERR. + * Other bits are retrieved only from emulated config buffer. + */ + __le32 *cfgspace = (__le32 *)&bridge->conf; + u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]); ++ if (advk_readl(pcie, PCIE_ISR0_MASK_REG) & PCIE_ISR0_ERR_MASK) ++ val &= ~(PCI_BRIDGE_CTL_SERR << 16); ++ else ++ val |= PCI_BRIDGE_CTL_SERR << 16; + if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN) + val |= PCI_BRIDGE_CTL_BUS_RESET << 16; + else +@@ -808,6 +816,19 @@ advk_pci_bridge_emul_base_conf_write(str + break; + + case PCI_INTERRUPT_LINE: ++ /* ++ * According to Figure 6-3: Pseudo Logic Diagram for Error ++ * Message Controls in PCIe base specification, SERR# Enable bit ++ * in Bridge Control register enable receiving of ERR_* messages ++ */ ++ if (mask & (PCI_BRIDGE_CTL_SERR << 16)) { ++ u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); ++ if (new & (PCI_BRIDGE_CTL_SERR << 16)) ++ val &= ~PCIE_ISR0_ERR_MASK; ++ else ++ val |= PCIE_ISR0_ERR_MASK; ++ advk_writel(pcie, val, PCIE_ISR0_MASK_REG); ++ } + if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { + u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); + if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16)) +@@ -1455,6 +1476,18 @@ static void advk_pcie_handle_int(struct + isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); + isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); + ++ /* Process ERR interrupt */ ++ if (isr0_status & PCIE_ISR0_ERR_MASK) { ++ advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG); ++ ++ /* ++ * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use ++ * PCIe interrupt 0 ++ */ ++ if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) ++ dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n"); ++ } ++ + /* Process MSI interrupts */ + if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) + advk_pcie_handle_msi(pcie); diff --git a/queue-5.17/pci-aardvark-add-support-for-masking-msi-interrupts.patch b/queue-5.17/pci-aardvark-add-support-for-masking-msi-interrupts.patch new file mode 100644 index 00000000000..b13d9a07d7f --- /dev/null +++ b/queue-5.17/pci-aardvark-add-support-for-masking-msi-interrupts.patch @@ -0,0 +1,125 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:41 +0200 +Subject: PCI: aardvark: Add support for masking MSI interrupts +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-9-kabel@kernel.org> + +From: Pali Rohár + +commit e77d9c90691071769cd2b86ef097f7d07167dc3b upstream. + +We should not unmask MSIs at setup, but only when kernel asks for them +to be unmasked. + +At setup, mask all MSIs, and implement IRQ chip callbacks for masking +and unmasking particular MSIs. + +Link: https://lore.kernel.org/r/20220110015018.26359-11-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 54 ++++++++++++++++++++++++++++++---- + 1 file changed, 49 insertions(+), 5 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -274,6 +274,7 @@ struct advk_pcie { + raw_spinlock_t irq_lock; + struct irq_domain *msi_domain; + struct irq_domain *msi_inner_domain; ++ raw_spinlock_t msi_irq_lock; + DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); + struct mutex msi_used_lock; + u16 msi_msg; +@@ -570,12 +571,10 @@ static void advk_pcie_setup_hw(struct ad + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); + advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); + +- /* Disable All ISR0/1 Sources */ ++ /* Disable All ISR0/1 and MSI Sources */ + advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG); + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); +- +- /* Unmask all MSIs */ +- advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG); ++ advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG); + + /* Unmask summary MSI interrupt */ + reg = advk_readl(pcie, PCIE_ISR0_MASK_REG); +@@ -1191,10 +1190,52 @@ static int advk_msi_set_affinity(struct + return -EINVAL; + } + ++static void advk_msi_irq_mask(struct irq_data *d) ++{ ++ struct advk_pcie *pcie = d->domain->host_data; ++ irq_hw_number_t hwirq = irqd_to_hwirq(d); ++ unsigned long flags; ++ u32 mask; ++ ++ raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags); ++ mask = advk_readl(pcie, PCIE_MSI_MASK_REG); ++ mask |= BIT(hwirq); ++ advk_writel(pcie, mask, PCIE_MSI_MASK_REG); ++ raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags); ++} ++ ++static void advk_msi_irq_unmask(struct irq_data *d) ++{ ++ struct advk_pcie *pcie = d->domain->host_data; ++ irq_hw_number_t hwirq = irqd_to_hwirq(d); ++ unsigned long flags; ++ u32 mask; ++ ++ raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags); ++ mask = advk_readl(pcie, PCIE_MSI_MASK_REG); ++ mask &= ~BIT(hwirq); ++ advk_writel(pcie, mask, PCIE_MSI_MASK_REG); ++ raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags); ++} ++ ++static void advk_msi_top_irq_mask(struct irq_data *d) ++{ ++ pci_msi_mask_irq(d); ++ irq_chip_mask_parent(d); ++} ++ ++static void advk_msi_top_irq_unmask(struct irq_data *d) ++{ ++ pci_msi_unmask_irq(d); ++ irq_chip_unmask_parent(d); ++} ++ + static struct irq_chip advk_msi_bottom_irq_chip = { + .name = "MSI", + .irq_compose_msi_msg = advk_msi_irq_compose_msi_msg, + .irq_set_affinity = advk_msi_set_affinity, ++ .irq_mask = advk_msi_irq_mask, ++ .irq_unmask = advk_msi_irq_unmask, + }; + + static int advk_msi_irq_domain_alloc(struct irq_domain *domain, +@@ -1284,7 +1325,9 @@ static const struct irq_domain_ops advk_ + }; + + static struct irq_chip advk_msi_irq_chip = { +- .name = "advk-MSI", ++ .name = "advk-MSI", ++ .irq_mask = advk_msi_top_irq_mask, ++ .irq_unmask = advk_msi_top_irq_unmask, + }; + + static struct msi_domain_info advk_msi_domain_info = { +@@ -1298,6 +1341,7 @@ static int advk_pcie_init_msi_irq_domain + struct device *dev = &pcie->pdev->dev; + phys_addr_t msi_msg_phys; + ++ raw_spin_lock_init(&pcie->msi_irq_lock); + mutex_init(&pcie->msi_used_lock); + + msi_msg_phys = virt_to_phys(&pcie->msi_msg); diff --git a/queue-5.17/pci-aardvark-add-support-for-pme-interrupts.patch b/queue-5.17/pci-aardvark-add-support-for-pme-interrupts.patch new file mode 100644 index 00000000000..a47ad19e333 --- /dev/null +++ b/queue-5.17/pci-aardvark-add-support-for-pme-interrupts.patch @@ -0,0 +1,54 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:46 +0200 +Subject: PCI: aardvark: Add support for PME interrupts +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-14-kabel@kernel.org> + +From: Pali Rohár + +commit 0fc75d87454195885bd1a81fc7e6ce92572b6109 upstream. + +Currently enabling PCI_EXP_RTSTA_PME bit in PCI_EXP_RTCTL register does +nothing. This is because PCIe PME driver expects to receive PCIe interrupt +defined in PCI_EXP_FLAGS_IRQ register, but aardvark hardware does not +trigger PCIe INTx/MSI interrupt for PME event, rather it triggers custom +aardvark interrupt which this driver is not processing yet. + +Fix this issue by handling PME interrupt in advk_pcie_handle_int() and +chaining it to PCIe interrupt 0 with generic_handle_domain_irq() (since +aardvark sets PCI_EXP_FLAGS_IRQ to zero). With this change PCIe PME driver +finally starts receiving PME interrupt. + +Link: https://lore.kernel.org/r/20220110015018.26359-17-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1478,6 +1478,18 @@ static void advk_pcie_handle_int(struct + isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); + isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); + ++ /* Process PME interrupt */ ++ if (isr0_status & PCIE_MSG_PM_PME_MASK) { ++ /* ++ * Do not clear PME interrupt bit in ISR0, it is cleared by IRQ ++ * receiver by writing to the PCI_EXP_RTSTA register of emulated ++ * root bridge. Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ, ++ * so use PCIe interrupt 0. ++ */ ++ if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) ++ dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n"); ++ } ++ + /* Process ERR interrupt */ + if (isr0_status & PCIE_ISR0_ERR_MASK) { + advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG); diff --git a/queue-5.17/pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch b/queue-5.17/pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch new file mode 100644 index 00000000000..c31e0722039 --- /dev/null +++ b/queue-5.17/pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch @@ -0,0 +1,38 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:36 +0200 +Subject: PCI: aardvark: Check return value of generic_handle_domain_irq() when processing INTx IRQ +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-4-kabel@kernel.org> + +From: Pali Rohár + +commit 51f96e287c6f003d3bb29672811c757c5fbf0028 upstream. + +It is possible that we receive spurious INTx interrupt. Check for the +return value of generic_handle_domain_irq() when processing INTx IRQ. + +Link: https://lore.kernel.org/r/20220110015018.26359-6-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1427,7 +1427,9 @@ static void advk_pcie_handle_int(struct + advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), + PCIE_ISR1_REG); + +- generic_handle_domain_irq(pcie->irq_domain, i); ++ if (generic_handle_domain_irq(pcie->irq_domain, i) == -EINVAL) ++ dev_err_ratelimited(&pcie->pdev->dev, "unexpected INT%c IRQ\n", ++ (char)i + 'A'); + } + } + diff --git a/queue-5.17/pci-aardvark-don-t-mask-irq-when-mapping.patch b/queue-5.17/pci-aardvark-don-t-mask-irq-when-mapping.patch new file mode 100644 index 00000000000..2f39d5f82b4 --- /dev/null +++ b/queue-5.17/pci-aardvark-don-t-mask-irq-when-mapping.patch @@ -0,0 +1,35 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:50 +0200 +Subject: PCI: aardvark: Don't mask irq when mapping +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-18-kabel@kernel.org> + +From: Pali Rohár + +commit befa71000160b39c1bf6cdfca6837bb5e9d372d7 upstream. + +By default, all Legacy INTx interrupts are masked, so there is no need to +mask this interrupt during irq_map() callback. + +Link: https://lore.kernel.org/r/20220110015018.26359-21-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1330,7 +1330,6 @@ static int advk_pcie_irq_map(struct irq_ + { + struct advk_pcie *pcie = h->host_data; + +- advk_pcie_irq_mask(irq_get_irq_data(virq)); + irq_set_status_flags(virq, IRQ_LEVEL); + irq_set_chip_and_handler(virq, &pcie->irq_chip, + handle_level_irq); diff --git a/queue-5.17/pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch b/queue-5.17/pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch new file mode 100644 index 00000000000..9307dd21bd3 --- /dev/null +++ b/queue-5.17/pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch @@ -0,0 +1,35 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:51 +0200 +Subject: PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy() +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-19-kabel@kernel.org> + +From: "Marek Behún" + +commit 0c36ab437e1d94b6628b006a1d48f05ea3b0b222 upstream. + +This function is now always used in driver remove method, drop the +__maybe_unused attribute. + +Link: https://lore.kernel.org/r/20220110015018.26359-22-kabel@kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1603,7 +1603,7 @@ static int advk_pcie_map_irq(const struc + return of_irq_parse_and_map_pci(dev, slot, pin); + } + +-static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie) ++static void advk_pcie_disable_phy(struct advk_pcie *pcie) + { + phy_power_off(pcie->phy); + phy_exit(pcie->phy); diff --git a/queue-5.17/pci-aardvark-enable-msi-x-support.patch b/queue-5.17/pci-aardvark-enable-msi-x-support.patch new file mode 100644 index 00000000000..e7dcbd181f5 --- /dev/null +++ b/queue-5.17/pci-aardvark-enable-msi-x-support.patch @@ -0,0 +1,46 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:43 +0200 +Subject: PCI: aardvark: Enable MSI-X support +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-11-kabel@kernel.org> + +From: Pali Rohár + +commit 754e449889b22fc3c34235e8836f08f51121d307 upstream. + +According to PCI 3.0 specification, sending both MSI and MSI-X interrupts +is done by DWORD memory write operation to doorbell message address. The +write operation for MSI has zero upper 16 bits and the MSI interrupt number +in the lower 16 bits, while the write operation for MSI-X contains a 32-bit +value from MSI-X table. + +Since the driver only uses interrupt numbers from range 0..31, the upper +16 bits of the DWORD memory write operation to doorbell message address +are zero even for MSI-X interrupts. Thus we can enable MSI-X interrupts. + +Testing proves that kernel can correctly receive MSI-X interrupts from PCIe +cards which supports both MSI and MSI-X interrupts. + +Link: https://lore.kernel.org/r/20220110015018.26359-13-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1337,7 +1337,7 @@ static struct irq_chip advk_msi_irq_chip + + static struct msi_domain_info advk_msi_domain_info = { + .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | +- MSI_FLAG_MULTI_PCI_MSI, ++ MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX, + .chip = &advk_msi_irq_chip, + }; + diff --git a/queue-5.17/pci-aardvark-fix-setting-msi-address.patch b/queue-5.17/pci-aardvark-fix-setting-msi-address.patch new file mode 100644 index 00000000000..d3c24e20205 --- /dev/null +++ b/queue-5.17/pci-aardvark-fix-setting-msi-address.patch @@ -0,0 +1,99 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:42 +0200 +Subject: PCI: aardvark: Fix setting MSI address +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-10-kabel@kernel.org> + +From: Pali Rohár + +commit 46ad3dc4171b5ee1d12267d70112563d5760210a upstream. + +MSI address for receiving MSI interrupts needs to be correctly set before +enabling processing of MSI interrupts. + +Move code for setting PCIE_MSI_ADDR_LOW_REG and PCIE_MSI_ADDR_HIGH_REG +from advk_pcie_init_msi_irq_domain() to advk_pcie_setup_hw(), before +enabling PCIE_CORE_CTRL2_MSI_ENABLE. + +After this we can remove the now unused member msi_msg, which was used +only for MSI doorbell address. MSI address can be any address which cannot +be used to DMA to. So change it to the address of the main struct advk_pcie. + +Link: https://lore.kernel.org/r/20220110015018.26359-12-kabel@kernel.org +Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Acked-by: Marc Zyngier +Cc: stable@vger.kernel.org # f21a8b1b6837 ("PCI: aardvark: Move to MSI handling using generic MSI support") +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -277,7 +277,6 @@ struct advk_pcie { + raw_spinlock_t msi_irq_lock; + DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); + struct mutex msi_used_lock; +- u16 msi_msg; + int link_gen; + struct pci_bridge_emul bridge; + struct gpio_desc *reset_gpio; +@@ -472,6 +471,7 @@ static void advk_pcie_disable_ob_win(str + + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { ++ phys_addr_t msi_addr; + u32 reg; + int i; + +@@ -560,6 +560,11 @@ static void advk_pcie_setup_hw(struct ad + reg |= LANE_COUNT_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + ++ /* Set MSI address */ ++ msi_addr = virt_to_phys(pcie); ++ advk_writel(pcie, lower_32_bits(msi_addr), PCIE_MSI_ADDR_LOW_REG); ++ advk_writel(pcie, upper_32_bits(msi_addr), PCIE_MSI_ADDR_HIGH_REG); ++ + /* Enable MSI */ + reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); + reg |= PCIE_CORE_CTRL2_MSI_ENABLE; +@@ -1177,10 +1182,10 @@ static void advk_msi_irq_compose_msi_msg + struct msi_msg *msg) + { + struct advk_pcie *pcie = irq_data_get_irq_chip_data(data); +- phys_addr_t msi_msg = virt_to_phys(&pcie->msi_msg); ++ phys_addr_t msi_addr = virt_to_phys(pcie); + +- msg->address_lo = lower_32_bits(msi_msg); +- msg->address_hi = upper_32_bits(msi_msg); ++ msg->address_lo = lower_32_bits(msi_addr); ++ msg->address_hi = upper_32_bits(msi_addr); + msg->data = data->hwirq; + } + +@@ -1339,18 +1344,10 @@ static struct msi_domain_info advk_msi_d + static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) + { + struct device *dev = &pcie->pdev->dev; +- phys_addr_t msi_msg_phys; + + raw_spin_lock_init(&pcie->msi_irq_lock); + mutex_init(&pcie->msi_used_lock); + +- msi_msg_phys = virt_to_phys(&pcie->msi_msg); +- +- advk_writel(pcie, lower_32_bits(msi_msg_phys), +- PCIE_MSI_ADDR_LOW_REG); +- advk_writel(pcie, upper_32_bits(msi_msg_phys), +- PCIE_MSI_ADDR_HIGH_REG); +- + pcie->msi_inner_domain = + irq_domain_add_linear(NULL, MSI_IRQ_NUM, + &advk_msi_domain_ops, pcie); diff --git a/queue-5.17/pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch b/queue-5.17/pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch new file mode 100644 index 00000000000..9f8fa52329e --- /dev/null +++ b/queue-5.17/pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch @@ -0,0 +1,177 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:47 +0200 +Subject: PCI: aardvark: Fix support for PME requester on emulated bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-15-kabel@kernel.org> + +From: Pali Rohár + +commit 273ddd86d67694e3639e3bfe337a96d8861798b8 upstream. + +Enable aardvark PME interrupt unconditionally by unmasking it and read PME +requester ID to emulated bridge config space immediately after receiving +interrupt. + +PME requester ID is stored in the PCIE_MSG_LOG_REG register, which contains +the last inbound message. So when new inbound message is received by HW +(including non-PM), the content in PCIE_MSG_LOG_REG register is replaced by +a new value. + +PCIe specification mandates that subsequent PMEs are kept pending until the +PME Status Register bit is cleared by software by writing a 1b. + +Support for masking/unmasking PME interrupt on emulated bridge via +PCI_EXP_RTCTL_PMEIE bit is now implemented only in emulated bridge config +space, to ensure that we do not miss any aardvark PME interrupt. + +Reading of PCI_EXP_RTCAP and PCI_EXP_RTSTA registers is simplified as final +value is now always stored into emulated bridge config space by the +interrupt handler, so there is no need to implement support for these +registers in read_pcie callback. + +Clearing of W1C bit PCI_EXP_RTSTA_PME is now also simplified as it is done +by pci-bridge-emul.c code for emulated bridge config space. So there is no +need to implement support for clearing this bit in write_pcie callback. + +Link: https://lore.kernel.org/r/20220110015018.26359-18-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 91 ++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 41 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -590,6 +590,11 @@ static void advk_pcie_setup_hw(struct ad + reg &= ~PCIE_ISR0_MSI_INT_PENDING; + advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); + ++ /* Unmask PME interrupt for processing of PME requester */ ++ reg = advk_readl(pcie, PCIE_ISR0_MASK_REG); ++ reg &= ~PCIE_MSG_PM_PME_MASK; ++ advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); ++ + /* Enable summary interrupt for GIC SPI source */ + reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); + advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); +@@ -856,22 +861,11 @@ advk_pci_bridge_emul_pcie_conf_read(stru + *value = PCI_EXP_SLTSTA_PDS << 16; + return PCI_BRIDGE_EMUL_HANDLED; + +- case PCI_EXP_RTCTL: { +- u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); +- *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE; +- *value |= le16_to_cpu(bridge->pcie_conf.rootctl) & PCI_EXP_RTCTL_CRSSVE; +- *value |= PCI_EXP_RTCAP_CRSVIS << 16; +- return PCI_BRIDGE_EMUL_HANDLED; +- } +- +- case PCI_EXP_RTSTA: { +- u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG); +- u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG); +- *value = msglog >> 16; +- if (isr0 & PCIE_MSG_PM_PME_MASK) +- *value |= PCI_EXP_RTSTA_PME; +- return PCI_BRIDGE_EMUL_HANDLED; +- } ++ /* ++ * PCI_EXP_RTCTL and PCI_EXP_RTSTA are also supported, but do not need ++ * to be handled here, because their values are stored in emulated ++ * config space buffer, and we read them from there when needed. ++ */ + + case PCI_EXP_LNKCAP: { + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); +@@ -925,22 +919,19 @@ advk_pci_bridge_emul_pcie_conf_write(str + advk_pcie_wait_for_retrain(pcie); + break; + +- case PCI_EXP_RTCTL: +- /* Only mask/unmask PME interrupt */ +- if (mask & PCI_EXP_RTCTL_PMEIE) { +- u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); +- if (new & PCI_EXP_RTCTL_PMEIE) +- val &= ~PCIE_MSG_PM_PME_MASK; +- else +- val |= PCIE_MSG_PM_PME_MASK; +- advk_writel(pcie, val, PCIE_ISR0_MASK_REG); +- } ++ case PCI_EXP_RTCTL: { ++ u16 rootctl = le16_to_cpu(bridge->pcie_conf.rootctl); ++ /* Only emulation of PMEIE and CRSSVE bits is provided */ ++ rootctl &= PCI_EXP_RTCTL_PMEIE | PCI_EXP_RTCTL_CRSSVE; ++ bridge->pcie_conf.rootctl = cpu_to_le16(rootctl); + break; ++ } + +- case PCI_EXP_RTSTA: +- if (new & PCI_EXP_RTSTA_PME) +- advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG); +- break; ++ /* ++ * PCI_EXP_RTSTA is also supported, but does not need to be handled ++ * here, because its value is stored in emulated config space buffer, ++ * and we write it there when needed. ++ */ + + case PCI_EXP_DEVCTL: + case PCI_EXP_DEVCTL2: +@@ -1443,6 +1434,32 @@ static void advk_pcie_remove_irq_domain( + irq_domain_remove(pcie->irq_domain); + } + ++static void advk_pcie_handle_pme(struct advk_pcie *pcie) ++{ ++ u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16; ++ ++ advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG); ++ ++ /* ++ * PCIE_MSG_LOG_REG contains the last inbound message, so store ++ * the requester ID only when PME was not asserted yet. ++ * Also do not trigger PME interrupt when PME is still asserted. ++ */ ++ if (!(le32_to_cpu(pcie->bridge.pcie_conf.rootsta) & PCI_EXP_RTSTA_PME)) { ++ pcie->bridge.pcie_conf.rootsta = cpu_to_le32(requester | PCI_EXP_RTSTA_PME); ++ ++ /* ++ * Trigger PME interrupt only if PMEIE bit in Root Control is set. ++ * Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ, so use PCIe interrupt 0. ++ */ ++ if (!(le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & PCI_EXP_RTCTL_PMEIE)) ++ return; ++ ++ if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) ++ dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n"); ++ } ++} ++ + static void advk_pcie_handle_msi(struct advk_pcie *pcie) + { + u32 msi_val, msi_mask, msi_status, msi_idx; +@@ -1478,17 +1495,9 @@ static void advk_pcie_handle_int(struct + isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); + isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); + +- /* Process PME interrupt */ +- if (isr0_status & PCIE_MSG_PM_PME_MASK) { +- /* +- * Do not clear PME interrupt bit in ISR0, it is cleared by IRQ +- * receiver by writing to the PCI_EXP_RTSTA register of emulated +- * root bridge. Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ, +- * so use PCIe interrupt 0. +- */ +- if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) +- dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n"); +- } ++ /* Process PME interrupt as the first one to do not miss PME requester id */ ++ if (isr0_status & PCIE_MSG_PM_PME_MASK) ++ advk_pcie_handle_pme(pcie); + + /* Process ERR interrupt */ + if (isr0_status & PCIE_ISR0_ERR_MASK) { diff --git a/queue-5.17/pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch b/queue-5.17/pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch new file mode 100644 index 00000000000..f37c17978ac --- /dev/null +++ b/queue-5.17/pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch @@ -0,0 +1,100 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:37 +0200 +Subject: PCI: aardvark: Make MSI irq_chip structures static driver structures +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-5-kabel@kernel.org> + +From: "Marek Behún" + +commit c3cb8e51839adc0aaef478c47665443d02f5aa07 upstream. + +In [1] it was agreed that we should use struct irq_chip as a global +static struct in the driver. Even though the structure currently +contains a dynamic member (parent_device), In [2] the plans to kill it +and make the structure completely static were set out. + +Convert Aardvark's priv->msi_bottom_irq_chip and priv->msi_irq_chip to +static driver structure. + +[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/ +[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/ + +Link: https://lore.kernel.org/r/20220110015018.26359-7-kabel@kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -274,8 +274,6 @@ struct advk_pcie { + raw_spinlock_t irq_lock; + struct irq_domain *msi_domain; + struct irq_domain *msi_inner_domain; +- struct irq_chip msi_bottom_irq_chip; +- struct irq_chip msi_irq_chip; + struct msi_domain_info msi_domain_info; + DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); + struct mutex msi_used_lock; +@@ -1192,6 +1190,12 @@ static int advk_msi_set_affinity(struct + return -EINVAL; + } + ++static struct irq_chip advk_msi_bottom_irq_chip = { ++ .name = "MSI", ++ .irq_compose_msi_msg = advk_msi_irq_compose_msi_msg, ++ .irq_set_affinity = advk_msi_set_affinity, ++}; ++ + static int advk_msi_irq_domain_alloc(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs, void *args) +@@ -1208,7 +1212,7 @@ static int advk_msi_irq_domain_alloc(str + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, +- &pcie->msi_bottom_irq_chip, ++ &advk_msi_bottom_irq_chip, + domain->host_data, handle_simple_irq, + NULL, NULL); + +@@ -1278,29 +1282,23 @@ static const struct irq_domain_ops advk_ + .xlate = irq_domain_xlate_onecell, + }; + ++static struct irq_chip advk_msi_irq_chip = { ++ .name = "advk-MSI", ++}; ++ + static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) + { + struct device *dev = &pcie->pdev->dev; + struct device_node *node = dev->of_node; +- struct irq_chip *bottom_ic, *msi_ic; + struct msi_domain_info *msi_di; + phys_addr_t msi_msg_phys; + + mutex_init(&pcie->msi_used_lock); + +- bottom_ic = &pcie->msi_bottom_irq_chip; +- +- bottom_ic->name = "MSI"; +- bottom_ic->irq_compose_msi_msg = advk_msi_irq_compose_msi_msg; +- bottom_ic->irq_set_affinity = advk_msi_set_affinity; +- +- msi_ic = &pcie->msi_irq_chip; +- msi_ic->name = "advk-MSI"; +- + msi_di = &pcie->msi_domain_info; + msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI; +- msi_di->chip = msi_ic; ++ msi_di->chip = &advk_msi_irq_chip; + + msi_msg_phys = virt_to_phys(&pcie->msi_msg); + diff --git a/queue-5.17/pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch b/queue-5.17/pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch new file mode 100644 index 00000000000..cc5a90618cb --- /dev/null +++ b/queue-5.17/pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch @@ -0,0 +1,71 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:38 +0200 +Subject: PCI: aardvark: Make msi_domain_info structure a static driver structure +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-6-kabel@kernel.org> + +From: "Marek Behún" + +commit 26bcd54e4a5cd51ec12d06fdc30e22863ed4c422 upstream. + +Make Aardvark's msi_domain_info structure into a private driver structure. +Domain info is same for every potential instatination of a controller. + +Link: https://lore.kernel.org/r/20220110015018.26359-8-kabel@kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -274,7 +274,6 @@ struct advk_pcie { + raw_spinlock_t irq_lock; + struct irq_domain *msi_domain; + struct irq_domain *msi_inner_domain; +- struct msi_domain_info msi_domain_info; + DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); + struct mutex msi_used_lock; + u16 msi_msg; +@@ -1286,20 +1285,20 @@ static struct irq_chip advk_msi_irq_chip + .name = "advk-MSI", + }; + ++static struct msi_domain_info advk_msi_domain_info = { ++ .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | ++ MSI_FLAG_MULTI_PCI_MSI, ++ .chip = &advk_msi_irq_chip, ++}; ++ + static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) + { + struct device *dev = &pcie->pdev->dev; + struct device_node *node = dev->of_node; +- struct msi_domain_info *msi_di; + phys_addr_t msi_msg_phys; + + mutex_init(&pcie->msi_used_lock); + +- msi_di = &pcie->msi_domain_info; +- msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | +- MSI_FLAG_MULTI_PCI_MSI; +- msi_di->chip = &advk_msi_irq_chip; +- + msi_msg_phys = virt_to_phys(&pcie->msi_msg); + + advk_writel(pcie, lower_32_bits(msi_msg_phys), +@@ -1315,7 +1314,8 @@ static int advk_pcie_init_msi_irq_domain + + pcie->msi_domain = + pci_msi_create_irq_domain(of_node_to_fwnode(node), +- msi_di, pcie->msi_inner_domain); ++ &advk_msi_domain_info, ++ pcie->msi_inner_domain); + if (!pcie->msi_domain) { + irq_domain_remove(pcie->msi_inner_domain); + return -ENOMEM; diff --git a/queue-5.17/pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch b/queue-5.17/pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch new file mode 100644 index 00000000000..88335ce4a91 --- /dev/null +++ b/queue-5.17/pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch @@ -0,0 +1,59 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:45 +0200 +Subject: PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME on emulated bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-13-kabel@kernel.org> + +From: Pali Rohár + +commit 7122bcb33295228c882c0aa32a04b2547beba2c3 upstream. + +To optimize advk_pci_bridge_emul_pcie_conf_write() code, touch +PCIE_ISR0_REG and PCIE_ISR0_MASK_REG registers only when it is really +needed, when processing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME bits. + +Link: https://lore.kernel.org/r/20220110015018.26359-16-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -925,19 +925,21 @@ advk_pci_bridge_emul_pcie_conf_write(str + advk_pcie_wait_for_retrain(pcie); + break; + +- case PCI_EXP_RTCTL: { ++ case PCI_EXP_RTCTL: + /* Only mask/unmask PME interrupt */ +- u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) & +- ~PCIE_MSG_PM_PME_MASK; +- if ((new & PCI_EXP_RTCTL_PMEIE) == 0) +- val |= PCIE_MSG_PM_PME_MASK; +- advk_writel(pcie, val, PCIE_ISR0_MASK_REG); ++ if (mask & PCI_EXP_RTCTL_PMEIE) { ++ u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); ++ if (new & PCI_EXP_RTCTL_PMEIE) ++ val &= ~PCIE_MSG_PM_PME_MASK; ++ else ++ val |= PCIE_MSG_PM_PME_MASK; ++ advk_writel(pcie, val, PCIE_ISR0_MASK_REG); ++ } + break; +- } + + case PCI_EXP_RTSTA: +- new = (new & PCI_EXP_RTSTA_PME) >> 9; +- advk_writel(pcie, new, PCIE_ISR0_REG); ++ if (new & PCI_EXP_RTSTA_PME) ++ advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG); + break; + + case PCI_EXP_DEVCTL: diff --git a/queue-5.17/pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch b/queue-5.17/pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch new file mode 100644 index 00000000000..dfc7d70f2b5 --- /dev/null +++ b/queue-5.17/pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch @@ -0,0 +1,52 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:40 +0200 +Subject: PCI: aardvark: Refactor unmasking summary MSI interrupt +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-8-kabel@kernel.org> + +From: Pali Rohár + +commit 4689c0916320f112a8a33f2689d3addc3262f02c upstream. + +Refactor the masking of ISR0/1 Sources and unmasking of summary MSI interrupt +so that it corresponds to the comments: +- first mask all ISR0/1 +- then unmask all MSIs +- then unmask summary MSI interrupt + +Link: https://lore.kernel.org/r/20220110015018.26359-10-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -571,15 +571,17 @@ static void advk_pcie_setup_hw(struct ad + advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); + + /* Disable All ISR0/1 Sources */ +- reg = PCIE_ISR0_ALL_MASK; +- reg &= ~PCIE_ISR0_MSI_INT_PENDING; +- advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); +- ++ advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG); + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); + + /* Unmask all MSIs */ + advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG); + ++ /* Unmask summary MSI interrupt */ ++ reg = advk_readl(pcie, PCIE_ISR0_MASK_REG); ++ reg &= ~PCIE_ISR0_MSI_INT_PENDING; ++ advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); ++ + /* Enable summary interrupt for GIC SPI source */ + reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); + advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); diff --git a/queue-5.17/pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch b/queue-5.17/pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch new file mode 100644 index 00000000000..3f9cb1ae897 --- /dev/null +++ b/queue-5.17/pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch @@ -0,0 +1,37 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:49 +0200 +Subject: PCI: aardvark: Remove irq_mask_ack() callback for INTx interrupts +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-17-kabel@kernel.org> + +From: Pali Rohár + +commit b08e5b53d17be58eb2311d6790a84fe2c200ee47 upstream. + +Callback for irq_mask_ack() is the same as for irq_mask(). As there is no +special handling for irq_ack(), there is no need to define irq_mask_ack() +too. + +Link: https://lore.kernel.org/r/20220110015018.26359-20-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Acked-by: Marc Zyngier +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1413,7 +1413,6 @@ static int advk_pcie_init_irq_domain(str + } + + irq_chip->irq_mask = advk_pcie_irq_mask; +- irq_chip->irq_mask_ack = advk_pcie_irq_mask; + irq_chip->irq_unmask = advk_pcie_irq_unmask; + + pcie->irq_domain = diff --git a/queue-5.17/pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch b/queue-5.17/pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch new file mode 100644 index 00000000000..be844ce1d47 --- /dev/null +++ b/queue-5.17/pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch @@ -0,0 +1,48 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:34 +0200 +Subject: PCI: aardvark: Replace custom PCIE_CORE_INT_* macros with PCI_INTERRUPT_* +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-2-kabel@kernel.org> + +From: Pali Rohár + +commit 1d86abf1f89672a70f2ab65f6000299feb1f1781 upstream. + +Header file linux/pci.h defines enum pci_interrupt_pin with corresponding +PCI_INTERRUPT_* values. + +Link: https://lore.kernel.org/r/20220110015018.26359-2-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Bjorn Helgaas +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -38,10 +38,6 @@ + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK BIT(7) + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV BIT(8) +-#define PCIE_CORE_INT_A_ASSERT_ENABLE 1 +-#define PCIE_CORE_INT_B_ASSERT_ENABLE 2 +-#define PCIE_CORE_INT_C_ASSERT_ENABLE 3 +-#define PCIE_CORE_INT_D_ASSERT_ENABLE 4 + /* PIO registers base address and register offsets */ + #define PIO_BASE_ADDR 0x4000 + #define PIO_CTRL (PIO_BASE_ADDR + 0x0) +@@ -961,7 +957,7 @@ static int advk_sw_pci_bridge_init(struc + bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); + + /* Support interrupt A for MSI feature */ +- bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; ++ bridge->conf.intpin = PCI_INTERRUPT_INTA; + + /* Aardvark HW provides PCIe Capability structure in version 2 */ + bridge->pcie_conf.cap = cpu_to_le16(2); diff --git a/queue-5.17/pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch b/queue-5.17/pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch new file mode 100644 index 00000000000..6d5e7070fcd --- /dev/null +++ b/queue-5.17/pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch @@ -0,0 +1,133 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:35 +0200 +Subject: PCI: aardvark: Rewrite IRQ code to chained IRQ handler +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-3-kabel@kernel.org> + +From: Pali Rohár + +commit 1571d67dc190e50c6c56e8f88cdc39f7cc53166e upstream. + +Rewrite the code to use irq_set_chained_handler_and_data() handler with +chained_irq_enter() and chained_irq_exit() processing instead of using +devm_request_irq(). + +advk_pcie_irq_handler() reads IRQ status bits and calls other functions +based on which bits are set. These functions then read its own IRQ status +bits and calls other aardvark functions based on these bits. Finally +generic_handle_domain_irq() with translated linux IRQ numbers are called. + +Link: https://lore.kernel.org/r/20220110015018.26359-5-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 48 ++++++++++++++++++---------------- + 1 file changed, 26 insertions(+), 22 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -268,6 +268,7 @@ struct advk_pcie { + u32 actions; + } wins[OB_WIN_COUNT]; + u8 wins_count; ++ int irq; + struct irq_domain *irq_domain; + struct irq_chip irq_chip; + raw_spinlock_t irq_lock; +@@ -1430,21 +1431,26 @@ static void advk_pcie_handle_int(struct + } + } + +-static irqreturn_t advk_pcie_irq_handler(int irq, void *arg) ++static void advk_pcie_irq_handler(struct irq_desc *desc) + { +- struct advk_pcie *pcie = arg; +- u32 status; ++ struct advk_pcie *pcie = irq_desc_get_handler_data(desc); ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ u32 val, mask, status; + +- status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); +- if (!(status & PCIE_IRQ_CORE_INT)) +- return IRQ_NONE; ++ chained_irq_enter(chip, desc); + +- advk_pcie_handle_int(pcie); ++ val = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); ++ mask = advk_readl(pcie, HOST_CTRL_INT_MASK_REG); ++ status = val & ((~mask) & PCIE_IRQ_ALL_MASK); + +- /* Clear interrupt */ +- advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); ++ if (status & PCIE_IRQ_CORE_INT) { ++ advk_pcie_handle_int(pcie); + +- return IRQ_HANDLED; ++ /* Clear interrupt */ ++ advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); ++ } ++ ++ chained_irq_exit(chip, desc); + } + + static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie) +@@ -1511,7 +1517,7 @@ static int advk_pcie_probe(struct platfo + struct advk_pcie *pcie; + struct pci_host_bridge *bridge; + struct resource_entry *entry; +- int ret, irq; ++ int ret; + + bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie)); + if (!bridge) +@@ -1597,17 +1603,9 @@ static int advk_pcie_probe(struct platfo + if (IS_ERR(pcie->base)) + return PTR_ERR(pcie->base); + +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) +- return irq; +- +- ret = devm_request_irq(dev, irq, advk_pcie_irq_handler, +- IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie", +- pcie); +- if (ret) { +- dev_err(dev, "Failed to register interrupt\n"); +- return ret; +- } ++ pcie->irq = platform_get_irq(pdev, 0); ++ if (pcie->irq < 0) ++ return pcie->irq; + + pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, + "reset-gpios", 0, +@@ -1656,11 +1654,14 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ irq_set_chained_handler_and_data(pcie->irq, advk_pcie_irq_handler, pcie); ++ + bridge->sysdata = pcie; + bridge->ops = &advk_pcie_ops; + + ret = pci_host_probe(bridge); + if (ret < 0) { ++ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL); + advk_pcie_remove_msi_irq_domain(pcie); + advk_pcie_remove_irq_domain(pcie); + return ret; +@@ -1708,6 +1709,9 @@ static int advk_pcie_remove(struct platf + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); + advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); + ++ /* Remove IRQ handler */ ++ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL); ++ + /* Remove IRQ domains */ + advk_pcie_remove_msi_irq_domain(pcie); + advk_pcie_remove_irq_domain(pcie); diff --git a/queue-5.17/pci-aardvark-update-comment-about-link-going-down-after-link-up.patch b/queue-5.17/pci-aardvark-update-comment-about-link-going-down-after-link-up.patch new file mode 100644 index 00000000000..fd81f48ea4a --- /dev/null +++ b/queue-5.17/pci-aardvark-update-comment-about-link-going-down-after-link-up.patch @@ -0,0 +1,41 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:52 +0200 +Subject: PCI: aardvark: Update comment about link going down after link-up +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-20-kabel@kernel.org> + +From: "Marek Behún" + +commit 92f4ffecc4170ce29e67a1f8d51c168c3de95fb2 upstream. + +Update the comment about what happens when link goes down after we have +checked for link-up. If a PIO request is done while link-down, we have +a serious problem. + +Link: https://lore.kernel.org/r/20220110015018.26359-23-kabel@kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -998,8 +998,12 @@ static bool advk_pcie_valid_device(struc + return false; + + /* +- * If the link goes down after we check for link-up, nothing bad +- * happens but the config access times out. ++ * If the link goes down after we check for link-up, we have a problem: ++ * if a PIO request is executed while link-down, the whole controller ++ * gets stuck in a non-functional state, and even after link comes up ++ * again, PIO requests won't work anymore, and a reset of the whole PCIe ++ * controller is needed. Therefore we need to prevent sending PIO ++ * requests while the link is down. + */ + if (!pci_is_root_bus(bus) && !advk_pcie_link_up(pcie)) + return false; diff --git a/queue-5.17/pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch b/queue-5.17/pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch new file mode 100644 index 00000000000..8ebd61b8e6c --- /dev/null +++ b/queue-5.17/pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch @@ -0,0 +1,47 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:39 +0200 +Subject: PCI: aardvark: Use dev_fwnode() instead of of_node_to_fwnode(dev->of_node) +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-7-kabel@kernel.org> + +From: "Marek Behún" + +commit 222af78532fa299cd9b1008e49c347b7f5a45c17 upstream. + +Use simple + dev_fwnode(dev) +instead of + struct device_node *node = dev->of_node; + of_node_to_fwnode(node) +especially since the node variable is not used elsewhere in the function. + +Link: https://lore.kernel.org/r/20220110015018.26359-9-kabel@kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -1294,7 +1294,6 @@ static struct msi_domain_info advk_msi_d + static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) + { + struct device *dev = &pcie->pdev->dev; +- struct device_node *node = dev->of_node; + phys_addr_t msi_msg_phys; + + mutex_init(&pcie->msi_used_lock); +@@ -1313,7 +1312,7 @@ static int advk_pcie_init_msi_irq_domain + return -ENOMEM; + + pcie->msi_domain = +- pci_msi_create_irq_domain(of_node_to_fwnode(node), ++ pci_msi_create_irq_domain(dev_fwnode(dev), + &advk_msi_domain_info, + pcie->msi_inner_domain); + if (!pcie->msi_domain) { diff --git a/queue-5.17/pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch b/queue-5.17/pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch new file mode 100644 index 00000000000..733df3fd85f --- /dev/null +++ b/queue-5.17/pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch @@ -0,0 +1,168 @@ +From foo@baz Tue May 10 01:48:44 PM CEST 2022 +From: "Marek Behún" +Date: Wed, 4 May 2022 18:58:48 +0200 +Subject: PCI: aardvark: Use separate INTA interrupt for emulated root bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: stable@vger.kernel.org, pali@kernel.org, "Marek Behún" +Message-ID: <20220504165852.30089-16-kabel@kernel.org> + +From: Pali Rohár + +commit 815bc313686783e3a1823ec0efc332c70e6bd976 upstream. + +Emulated root bridge currently provides only one Legacy INTA interrupt +which is used for reporting PCIe PME and ERR events and handled by kernel +PCIe PME and AER drivers. + +Aardvark HW reports these PME and ERR events separately, so there is no +need to mix real INTA interrupt and emulated INTA interrupt for PCIe PME +and AER drivers. + +Register a new advk-RP (as in Root Port) irq chip and a new irq domain +for emulated root bridge and use this new separate irq domain for +providing INTA interrupt from emulated root bridge for PME and ERR events. + +The real INTA interrupt from real devices is now separate. + +A custom map_irq callback function on PCI host bridge structure is used to +allocate IRQ mapping for emulated root bridge from new irq domain. Original +callback of_irq_parse_and_map_pci() is used for all other devices as before. + +Link: https://lore.kernel.org/r/20220110015018.26359-19-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 69 +++++++++++++++++++++++++++++++++- + 1 file changed, 67 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -273,6 +273,7 @@ struct advk_pcie { + } wins[OB_WIN_COUNT]; + u8 wins_count; + int irq; ++ struct irq_domain *rp_irq_domain; + struct irq_domain *irq_domain; + struct irq_chip irq_chip; + raw_spinlock_t irq_lock; +@@ -1434,6 +1435,44 @@ static void advk_pcie_remove_irq_domain( + irq_domain_remove(pcie->irq_domain); + } + ++static struct irq_chip advk_rp_irq_chip = { ++ .name = "advk-RP", ++}; ++ ++static int advk_pcie_rp_irq_map(struct irq_domain *h, ++ unsigned int virq, irq_hw_number_t hwirq) ++{ ++ struct advk_pcie *pcie = h->host_data; ++ ++ irq_set_chip_and_handler(virq, &advk_rp_irq_chip, handle_simple_irq); ++ irq_set_chip_data(virq, pcie); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops advk_pcie_rp_irq_domain_ops = { ++ .map = advk_pcie_rp_irq_map, ++ .xlate = irq_domain_xlate_onecell, ++}; ++ ++static int advk_pcie_init_rp_irq_domain(struct advk_pcie *pcie) ++{ ++ pcie->rp_irq_domain = irq_domain_add_linear(NULL, 1, ++ &advk_pcie_rp_irq_domain_ops, ++ pcie); ++ if (!pcie->rp_irq_domain) { ++ dev_err(&pcie->pdev->dev, "Failed to add Root Port IRQ domain\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static void advk_pcie_remove_rp_irq_domain(struct advk_pcie *pcie) ++{ ++ irq_domain_remove(pcie->rp_irq_domain); ++} ++ + static void advk_pcie_handle_pme(struct advk_pcie *pcie) + { + u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16; +@@ -1455,7 +1494,7 @@ static void advk_pcie_handle_pme(struct + if (!(le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & PCI_EXP_RTCTL_PMEIE)) + return; + +- if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) ++ if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL) + dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n"); + } + } +@@ -1507,7 +1546,7 @@ static void advk_pcie_handle_int(struct + * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use + * PCIe interrupt 0 + */ +- if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL) ++ if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL) + dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n"); + } + +@@ -1551,6 +1590,21 @@ static void advk_pcie_irq_handler(struct + chained_irq_exit(chip, desc); + } + ++static int advk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ struct advk_pcie *pcie = dev->bus->sysdata; ++ ++ /* ++ * Emulated root bridge has its own emulated irq chip and irq domain. ++ * Argument pin is the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD) and ++ * hwirq for irq_create_mapping() is indexed from zero. ++ */ ++ if (pci_is_root_bus(dev->bus)) ++ return irq_create_mapping(pcie->rp_irq_domain, pin - 1); ++ else ++ return of_irq_parse_and_map_pci(dev, slot, pin); ++} ++ + static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie) + { + phy_power_off(pcie->phy); +@@ -1752,14 +1806,24 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ ret = advk_pcie_init_rp_irq_domain(pcie); ++ if (ret) { ++ dev_err(dev, "Failed to initialize irq\n"); ++ advk_pcie_remove_msi_irq_domain(pcie); ++ advk_pcie_remove_irq_domain(pcie); ++ return ret; ++ } ++ + irq_set_chained_handler_and_data(pcie->irq, advk_pcie_irq_handler, pcie); + + bridge->sysdata = pcie; + bridge->ops = &advk_pcie_ops; ++ bridge->map_irq = advk_pcie_map_irq; + + ret = pci_host_probe(bridge); + if (ret < 0) { + irq_set_chained_handler_and_data(pcie->irq, NULL, NULL); ++ advk_pcie_remove_rp_irq_domain(pcie); + advk_pcie_remove_msi_irq_domain(pcie); + advk_pcie_remove_irq_domain(pcie); + return ret; +@@ -1811,6 +1875,7 @@ static int advk_pcie_remove(struct platf + irq_set_chained_handler_and_data(pcie->irq, NULL, NULL); + + /* Remove IRQ domains */ ++ advk_pcie_remove_rp_irq_domain(pcie); + advk_pcie_remove_msi_irq_domain(pcie); + advk_pcie_remove_irq_domain(pcie); + diff --git a/queue-5.17/series b/queue-5.17/series index a676c8adbf3..3345d05e524 100644 --- a/queue-5.17/series +++ b/queue-5.17/series @@ -120,3 +120,22 @@ kvm-lapic-enable-timer-posted-interrupt-only-when-mw.patch selftest-vm-verify-mmap-addr-in-mremap_test.patch selftest-vm-verify-remap-destination-address-in-mrem.patch mmc-rtsx-add-74-clocks-in-power-on-flow.patch +pci-aardvark-replace-custom-pcie_core_int_-macros-with-pci_interrupt_.patch +pci-aardvark-rewrite-irq-code-to-chained-irq-handler.patch +pci-aardvark-check-return-value-of-generic_handle_domain_irq-when-processing-intx-irq.patch +pci-aardvark-make-msi-irq_chip-structures-static-driver-structures.patch +pci-aardvark-make-msi_domain_info-structure-a-static-driver-structure.patch +pci-aardvark-use-dev_fwnode-instead-of-of_node_to_fwnode-dev-of_node.patch +pci-aardvark-refactor-unmasking-summary-msi-interrupt.patch +pci-aardvark-add-support-for-masking-msi-interrupts.patch +pci-aardvark-fix-setting-msi-address.patch +pci-aardvark-enable-msi-x-support.patch +pci-aardvark-add-support-for-err-interrupt-on-emulated-bridge.patch +pci-aardvark-optimize-writing-pci_exp_rtctl_pmeie-and-pci_exp_rtsta_pme-on-emulated-bridge.patch +pci-aardvark-add-support-for-pme-interrupts.patch +pci-aardvark-fix-support-for-pme-requester-on-emulated-bridge.patch +pci-aardvark-use-separate-inta-interrupt-for-emulated-root-bridge.patch +pci-aardvark-remove-irq_mask_ack-callback-for-intx-interrupts.patch +pci-aardvark-don-t-mask-irq-when-mapping.patch +pci-aardvark-drop-__maybe_unused-from-advk_pcie_disable_phy.patch +pci-aardvark-update-comment-about-link-going-down-after-link-up.patch -- 2.47.3