aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch
diff options
context:
space:
mode:
authorMarek Behún <kabel@kernel.org>2022-01-10 02:12:45 +0100
committerChristian Lamparter <chunkeey@gmail.com>2022-01-15 17:26:55 +0100
commit080691d7b1af67205081dff5a7fc4a988e080981 (patch)
tree992b0fe2b9b326304a196a4528dea166a5f92630 /target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch
parent612e1c68016495d69dc87eac5c1b1c845532d2a7 (diff)
downloadupstream-080691d7b1af67205081dff5a7fc4a988e080981.tar.gz
upstream-080691d7b1af67205081dff5a7fc4a988e080981.tar.bz2
upstream-080691d7b1af67205081dff5a7fc4a988e080981.zip
kernel: 5.10: Backport pending pci-aardvark changes fixing MSI support
Backport Aardvark PCIe controller driver changes that fix MSI support, that were recently sent to the linux-pci mailing list [1]. These changes fix MSI and MSI-X support for this PCIe controller, which, among other things, make it possible to use NVMe drives with this PCIe controllers. [1] https://lore.kernel.org/linux-pci/20220110015018.26359-1-kabel@kernel.org/ Signed-off-by: Marek Behún <kabel@kernel.org>
Diffstat (limited to 'target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch')
-rw-r--r--target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch b/target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch
new file mode 100644
index 0000000000..fbed9cc506
--- /dev/null
+++ b/target/linux/generic/pending-5.10/850-0004-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-handler.patch
@@ -0,0 +1,130 @@
+From 0cd5141d1866afb23286fe90cd846441fe7aeb39 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Sat, 27 Mar 2021 14:44:11 +0100
+Subject: [PATCH] PCI: aardvark: Rewrite IRQ code to chained IRQ handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Marek Behún <kabel@kernel.org>
+---
+ drivers/pci/controller/pci-aardvark.c | 48 +++++++++++++++------------
+ 1 file changed, 26 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
+index e68773527171..01dfe70d9c2c 100644
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -275,6 +275,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;
+@@ -1440,21 +1441,26 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
+ }
+ }
+
+-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)
+@@ -1521,7 +1527,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
+ 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)
+@@ -1609,17 +1615,9 @@ static int advk_pcie_probe(struct platform_device *pdev)
+ 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,
+@@ -1668,11 +1666,14 @@ static int advk_pcie_probe(struct platform_device *pdev)
+ 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;
+@@ -1720,6 +1721,9 @@ static int advk_pcie_remove(struct platform_device *pdev)
+ 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);
+--
+2.34.1
+