mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
kernel: bump 5.15 to 5.15.39 (#9389)
Signed-off-by: aakkll <94471752+aakkll@users.noreply.github.com>
This commit is contained in:
parent
0b8b34215f
commit
a7446d2806
@ -1,2 +1,2 @@
|
|||||||
LINUX_VERSION-5.15 = .38
|
LINUX_VERSION-5.15 = .39
|
||||||
LINUX_KERNEL_HASH-5.15.38 = 7e415d420990b88bfec038d56e920b9b28f99d54f31dbbd7aa82e66acca11052
|
LINUX_KERNEL_HASH-5.15.39 = 888641634f9e0e38cd0efcfec92ea3c126d381b24a514740d3fe3dc9988fd7ad
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
From 9319230ac147067652b58fe849ffe0ceec098665 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Tue, 30 Nov 2021 18:29:03 +0100
|
|
||||||
Subject: [PATCH] PCI: pci-bridge-emul: Add description for class_revision
|
|
||||||
field
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
The current assignment to the class_revision member
|
|
||||||
|
|
||||||
class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
|
|
||||||
|
|
||||||
can make the reader think that class is at high 16 bits of the member and
|
|
||||||
revision at low 16 bits.
|
|
||||||
|
|
||||||
In reality, class is at high 24 bits, but the class for PCI Bridge Normal
|
|
||||||
Decode is PCI_CLASS_BRIDGE_PCI << 8.
|
|
||||||
|
|
||||||
Change the assignment and add a comment to make this clearer.
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/r/20211130172913.9727-2-kabel@kernel.org
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
||||||
---
|
|
||||||
drivers/pci/pci-bridge-emul.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/drivers/pci/pci-bridge-emul.c
|
|
||||||
+++ b/drivers/pci/pci-bridge-emul.c
|
|
||||||
@@ -284,7 +284,11 @@ int pci_bridge_emul_init(struct pci_brid
|
|
||||||
{
|
|
||||||
BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END);
|
|
||||||
|
|
||||||
- bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
|
|
||||||
+ /*
|
|
||||||
+ * class_revision: Class is high 24 bits and revision is low 8 bit of this member,
|
|
||||||
+ * while class for PCI Bridge Normal Decode has the 24-bit value: PCI_CLASS_BRIDGE_PCI << 8
|
|
||||||
+ */
|
|
||||||
+ bridge->conf.class_revision |= cpu_to_le32((PCI_CLASS_BRIDGE_PCI << 8) << 8);
|
|
||||||
bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
|
|
||||||
bridge->conf.cache_line_size = 0x10;
|
|
||||||
bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST);
|
|
@ -21,9 +21,9 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/pci-bridge-emul.c
|
--- a/drivers/pci/pci-bridge-emul.c
|
||||||
+++ b/drivers/pci/pci-bridge-emul.c
|
+++ b/drivers/pci/pci-bridge-emul.c
|
||||||
@@ -270,6 +270,49 @@ struct pci_bridge_reg_behavior pcie_cap_
|
@@ -313,6 +313,49 @@ struct pci_bridge_reg_behavior pcie_cap_
|
||||||
.ro = GENMASK(15, 0) | PCI_EXP_RTSTA_PENDING,
|
[PCI_EXP_SLTCTL2 / 4] = {
|
||||||
.w1c = PCI_EXP_RTSTA_PME,
|
/* Both Slot control 2 and Slot status 2 registers are reserved. */
|
||||||
},
|
},
|
||||||
+
|
+
|
||||||
+ [PCI_EXP_DEVCAP2 / 4] = {
|
+ [PCI_EXP_DEVCAP2 / 4] = {
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
From 1d3e170344dff2cef8827db6c09909b78cbc11d7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Tue, 30 Nov 2021 18:29:05 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Add support for DEVCAP2, DEVCTL2, LNKCAP2 and
|
|
||||||
LNKCTL2 registers on emulated bridge
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
PCI aardvark hardware supports access to DEVCAP2, DEVCTL2, LNKCAP2 and
|
|
||||||
LNKCTL2 configuration registers of PCIe core via PCIE_CORE_PCIEXP_CAP.
|
|
||||||
Export them via emulated software root bridge.
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/r/20211130172913.9727-4-kabel@kernel.org
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 15 +++++++++++----
|
|
||||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
|
||||||
@@ -876,8 +876,13 @@ advk_pci_bridge_emul_pcie_conf_read(stru
|
|
||||||
|
|
||||||
case PCI_EXP_DEVCAP:
|
|
||||||
case PCI_EXP_DEVCTL:
|
|
||||||
+ case PCI_EXP_DEVCAP2:
|
|
||||||
+ case PCI_EXP_DEVCTL2:
|
|
||||||
+ case PCI_EXP_LNKCAP2:
|
|
||||||
+ case PCI_EXP_LNKCTL2:
|
|
||||||
*value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
|
|
||||||
return PCI_BRIDGE_EMUL_HANDLED;
|
|
||||||
+
|
|
||||||
default:
|
|
||||||
return PCI_BRIDGE_EMUL_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
@@ -891,10 +896,6 @@ advk_pci_bridge_emul_pcie_conf_write(str
|
|
||||||
struct advk_pcie *pcie = bridge->data;
|
|
||||||
|
|
||||||
switch (reg) {
|
|
||||||
- case PCI_EXP_DEVCTL:
|
|
||||||
- advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
case PCI_EXP_LNKCTL:
|
|
||||||
advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
|
|
||||||
if (new & PCI_EXP_LNKCTL_RL)
|
|
||||||
@@ -916,6 +917,12 @@ advk_pci_bridge_emul_pcie_conf_write(str
|
|
||||||
advk_writel(pcie, new, PCIE_ISR0_REG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
+ case PCI_EXP_DEVCTL:
|
|
||||||
+ case PCI_EXP_DEVCTL2:
|
|
||||||
+ case PCI_EXP_LNKCTL2:
|
|
||||||
+ advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
From 7d8dc1f7cd007a7ce94c5b4c20d63a8b8d6d7751 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Tue, 30 Nov 2021 18:29:06 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Clear all MSIs at setup
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
We already clear all the other interrupts (ISR0, ISR1, HOST_CTRL_INT).
|
|
||||||
|
|
||||||
Define a new macro PCIE_MSI_ALL_MASK and do the same clearing for MSIs,
|
|
||||||
to ensure that we don't start receiving spurious interrupts.
|
|
||||||
|
|
||||||
Use this new mask in advk_pcie_handle_msi();
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/r/20211130172913.9727-5-kabel@kernel.org
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 6 ++++--
|
|
||||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
|
||||||
@@ -115,6 +115,7 @@
|
|
||||||
#define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54)
|
|
||||||
#define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58)
|
|
||||||
#define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C)
|
|
||||||
+#define PCIE_MSI_ALL_MASK GENMASK(31, 0)
|
|
||||||
#define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C)
|
|
||||||
#define PCIE_MSI_DATA_MASK GENMASK(15, 0)
|
|
||||||
|
|
||||||
@@ -570,6 +571,7 @@ static void advk_pcie_setup_hw(struct ad
|
|
||||||
advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
|
|
||||||
|
|
||||||
/* Clear all interrupts */
|
|
||||||
+ advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_STATUS_REG);
|
|
||||||
advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG);
|
|
||||||
advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
|
|
||||||
advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
|
|
||||||
@@ -582,7 +584,7 @@ static void advk_pcie_setup_hw(struct ad
|
|
||||||
advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
|
|
||||||
|
|
||||||
/* Unmask all MSIs */
|
|
||||||
- advk_writel(pcie, 0, PCIE_MSI_MASK_REG);
|
|
||||||
+ advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
|
|
||||||
|
|
||||||
/* Enable summary interrupt for GIC SPI source */
|
|
||||||
reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
|
|
||||||
@@ -1389,7 +1391,7 @@ static void advk_pcie_handle_msi(struct
|
|
||||||
|
|
||||||
msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
|
|
||||||
msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
|
|
||||||
- msi_status = msi_val & ~msi_mask;
|
|
||||||
+ msi_status = msi_val & ((~msi_mask) & PCIE_MSI_ALL_MASK);
|
|
||||||
|
|
||||||
for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) {
|
|
||||||
if (!(BIT(msi_idx) & msi_status))
|
|
@ -1,34 +0,0 @@
|
|||||||
From a4ca7948e1d47275f8f3e5023243440c40561916 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Tue, 30 Nov 2021 18:29:07 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Comment actions in driver remove method
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Add two more comments into the advk_pcie_remove() method.
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/r/20211130172913.9727-6-kabel@kernel.org
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
|
||||||
@@ -1681,11 +1681,13 @@ static int advk_pcie_remove(struct platf
|
|
||||||
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
+ /* Remove PCI bus with all devices */
|
|
||||||
pci_lock_rescan_remove();
|
|
||||||
pci_stop_root_bus(bridge->bus);
|
|
||||||
pci_remove_root_bus(bridge->bus);
|
|
||||||
pci_unlock_rescan_remove();
|
|
||||||
|
|
||||||
+ /* Remove IRQ domains */
|
|
||||||
advk_pcie_remove_msi_irq_domain(pcie);
|
|
||||||
advk_pcie_remove_irq_domain(pcie);
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From a46f2f6dd4093438d9615dfbf5c0fea2a9835dba Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Tue, 30 Nov 2021 18:29:08 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Disable bus mastering when unbinding driver
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Ensure that after driver unbind PCIe cards are not able to forward
|
|
||||||
memory and I/O requests in the upstream direction.
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/r/20211130172913.9727-7-kabel@kernel.org
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
|
||||||
@@ -1679,6 +1679,7 @@ static int advk_pcie_remove(struct platf
|
|
||||||
{
|
|
||||||
struct advk_pcie *pcie = platform_get_drvdata(pdev);
|
|
||||||
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
|
|
||||||
+ u32 val;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Remove PCI bus with all devices */
|
|
||||||
@@ -1687,6 +1688,11 @@ static int advk_pcie_remove(struct platf
|
|
||||||
pci_remove_root_bus(bridge->bus);
|
|
||||||
pci_unlock_rescan_remove();
|
|
||||||
|
|
||||||
+ /* Disable Root Bridge I/O space, memory space and bus mastering */
|
|
||||||
+ val = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
|
|
||||||
+ val &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
|
||||||
+ advk_writel(pcie, val, PCIE_CORE_CMD_STATUS_REG);
|
|
||||||
+
|
|
||||||
/* Remove IRQ domains */
|
|
||||||
advk_pcie_remove_msi_irq_domain(pcie);
|
|
||||||
advk_pcie_remove_irq_domain(pcie);
|
|
@ -18,9 +18,9 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1693,6 +1693,27 @@ static int advk_pcie_remove(struct platf
|
@@ -1878,6 +1878,27 @@ static int advk_pcie_remove(struct platf
|
||||||
val &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
/* Remove IRQ handler */
|
||||||
advk_writel(pcie, val, PCIE_CORE_CMD_STATUS_REG);
|
irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
|
||||||
|
|
||||||
+ /* Disable MSI */
|
+ /* Disable MSI */
|
||||||
+ val = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
|
+ val = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
|
||||||
@ -44,5 +44,5 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
+ advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
|
+ advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
|
||||||
+
|
+
|
||||||
/* Remove IRQ domains */
|
/* Remove IRQ domains */
|
||||||
|
advk_pcie_remove_rp_irq_domain(pcie);
|
||||||
advk_pcie_remove_msi_irq_domain(pcie);
|
advk_pcie_remove_msi_irq_domain(pcie);
|
||||||
advk_pcie_remove_irq_domain(pcie);
|
|
||||||
|
@ -21,9 +21,9 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1718,6 +1718,9 @@ static int advk_pcie_remove(struct platf
|
@@ -1916,6 +1916,9 @@ static int advk_pcie_remove(struct platf
|
||||||
advk_pcie_remove_msi_irq_domain(pcie);
|
val &= ~LINK_TRAINING_EN;
|
||||||
advk_pcie_remove_irq_domain(pcie);
|
advk_writel(pcie, val, PCIE_CORE_CTRL0_REG);
|
||||||
|
|
||||||
+ /* Free config space for emulated root bridge */
|
+ /* Free config space for emulated root bridge */
|
||||||
+ pci_bridge_emul_cleanup(&pcie->bridge);
|
+ pci_bridge_emul_cleanup(&pcie->bridge);
|
||||||
|
@ -20,7 +20,7 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1721,6 +1721,10 @@ static int advk_pcie_remove(struct platf
|
@@ -1919,6 +1919,10 @@ static int advk_pcie_remove(struct platf
|
||||||
/* Free config space for emulated root bridge */
|
/* Free config space for emulated root bridge */
|
||||||
pci_bridge_emul_cleanup(&pcie->bridge);
|
pci_bridge_emul_cleanup(&pcie->bridge);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1725,6 +1725,11 @@ static int advk_pcie_remove(struct platf
|
@@ -1923,6 +1923,11 @@ static int advk_pcie_remove(struct platf
|
||||||
if (pcie->reset_gpio)
|
if (pcie->reset_gpio)
|
||||||
gpiod_set_value_cansleep(pcie->reset_gpio, 1);
|
gpiod_set_value_cansleep(pcie->reset_gpio, 1);
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1734,6 +1734,9 @@ static int advk_pcie_remove(struct platf
|
@@ -1640,6 +1640,9 @@ static int advk_pcie_enable_phy(struct a
|
||||||
for (i = 0; i < OB_WIN_COUNT; i++)
|
return ret;
|
||||||
advk_pcie_disable_ob_win(pcie, i);
|
}
|
||||||
|
|
||||||
+ /* Disable phy */
|
+ /* Disable phy */
|
||||||
+ advk_pcie_disable_phy(pcie);
|
+ advk_pcie_disable_phy(pcie);
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
From 43f3f187e6f62ca40802afe39495c8a3e20b4bfa Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Mon, 10 Jan 2022 01:50:50 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Replace custom PCIE_CORE_INT_* macros with
|
|
||||||
PCI_INTERRUPT_*
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Header file linux/pci.h defines enum pci_interrupt_pin with corresponding
|
|
||||||
PCI_INTERRUPT_* values.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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);
|
|
@ -1,125 +0,0 @@
|
|||||||
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(-)
|
|
||||||
|
|
||||||
--- 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;
|
|
||||||
@@ -1432,21 +1433,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)
|
|
||||||
@@ -1513,7 +1519,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)
|
|
||||||
@@ -1599,17 +1605,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,
|
|
||||||
@@ -1658,11 +1656,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;
|
|
||||||
@@ -1710,6 +1711,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);
|
|
@ -1,31 +0,0 @@
|
|||||||
From 69c1f2c6f45a556361fd8e8d2d4eb20e2c8d3d95 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Thu, 18 Mar 2021 17:04:32 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Check return value of
|
|
||||||
generic_handle_domain_irq() when processing INTx IRQ
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
It is possible that we receive spurious INTx interrupt. Check for the
|
|
||||||
return value of generic_handle_domain_irq() when processing INTx IRQ.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1429,7 +1429,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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
|||||||
From 5eb36a6b9508da442aac80f4df23e3951bbfa7aa Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 10 Jan 2022 00:03:41 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Make MSI irq_chip structures static driver
|
|
||||||
structures
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Marc Zyngier says [1] 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), Marc says [2] that he plans
|
|
||||||
to kill it and make the structure completely static.
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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;
|
|
||||||
@@ -1194,6 +1192,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)
|
|
||||||
@@ -1210,7 +1214,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);
|
|
||||||
|
|
||||||
@@ -1280,29 +1284,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);
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
From c092ab8994f1f777054c0179a9deb40b87ee606f Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 10 Jan 2022 00:10:46 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Make msi_domain_info structure a static driver
|
|
||||||
structure
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Make Aardvark's msi_domain_info structure into a private driver structure.
|
|
||||||
Domain info is same for every potential instatination of a controller.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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;
|
|
||||||
@@ -1288,20 +1287,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),
|
|
||||||
@@ -1317,7 +1316,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;
|
|
@ -1,40 +0,0 @@
|
|||||||
From 59029739d42b439628e2f64f3d8f2db9be97deff Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 10 Jan 2022 00:15:17 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Use dev_fwnode() instead of
|
|
||||||
of_node_to_fwnode(dev->of_node)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1296,7 +1296,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);
|
|
||||||
@@ -1315,7 +1314,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) {
|
|
@ -1,44 +0,0 @@
|
|||||||
From 98feaf97bc64fc640a6c5b1394cd18fc7cd7dac8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Sun, 28 Mar 2021 14:34:49 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Refactor unmasking summary MSI interrupt
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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);
|
|
@ -1,117 +0,0 @@
|
|||||||
From 7f353accca6e4a3222991c65b1a6801503973bd3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Fri, 2 Jul 2021 16:44:10 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Add support for masking MSI interrupts
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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);
|
|
||||||
@@ -1193,10 +1192,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,
|
|
||||||
@@ -1286,7 +1327,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 = {
|
|
||||||
@@ -1300,6 +1343,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);
|
|
@ -1,91 +0,0 @@
|
|||||||
From fa73c200f181436eab859374657c53a73778d8ad Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Fri, 26 Mar 2021 17:35:44 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Fix setting MSI address
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Acked-by: Marc Zyngier <maz@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Cc: stable@vger.kernel.org # f21a8b1b6837 ("PCI: aardvark: Move to MSI handling using generic MSI support")
|
|
||||||
---
|
|
||||||
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;
|
|
||||||
@@ -1179,10 +1184,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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1341,18 +1346,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);
|
|
@ -1,38 +0,0 @@
|
|||||||
From 735a4ac9782b96fbe1543c578aa8334364f21abd Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Fri, 2 Apr 2021 14:05:24 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Enable MSI-X support
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1339,7 +1339,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,
|
|
||||||
};
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
|||||||
From 7f3e55a3890fa26d15e2e4e90213962d1a7f6df9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Fri, 12 Feb 2021 20:32:55 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Add support for ERR interrupt on emulated
|
|
||||||
bridge
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 36 ++++++++++++++++++++++++++-
|
|
||||||
1 file changed, 35 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))
|
|
||||||
@@ -1457,6 +1478,19 @@ 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
|
|
||||||
+ */
|
|
||||||
+ virq = irq_find_mapping(pcie->irq_domain, 0);
|
|
||||||
+ if (generic_handle_irq(virq) == -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);
|
|
@ -1,52 +0,0 @@
|
|||||||
From 3fe0073d116d9902df08761c1cf0d733dd4c38fc Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Wed, 8 Dec 2021 06:03:50 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and
|
|
||||||
PCI_EXP_RTSTA_PME on emulated bridge
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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:
|
|
@ -25,23 +25,26 @@ Signed-off-by: Marek Behún <kabel@kernel.org>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1480,6 +1480,19 @@ static void advk_pcie_handle_int(struct
|
@@ -1411,6 +1538,22 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
|
||||||
isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
|
isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
|
||||||
isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
|
isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
|
||||||
|
|
||||||
+ /* Process PME interrupt */
|
+ /* Process PME interrupt as the first one to do not miss PME requester id */
|
||||||
+ if (isr0_status & PCIE_MSG_PM_PME_MASK) {
|
+ if (isr0_status & PCIE_MSG_PM_PME_MASK)
|
||||||
|
+ advk_pcie_handle_pme(pcie);
|
||||||
|
+
|
||||||
|
+ /* Process ERR interrupt */
|
||||||
|
+ if (isr0_status & PCIE_ISR0_ERR_MASK) {
|
||||||
|
+ advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG);
|
||||||
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * Do not clear PME interrupt bit in ISR0, it is cleared by IRQ
|
+ * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use
|
||||||
+ * receiver by writing to the PCI_EXP_RTSTA register of emulated
|
+ * PCIe interrupt 0
|
||||||
+ * root bridge. Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ,
|
|
||||||
+ * so use PCIe interrupt 0.
|
|
||||||
+ */
|
+ */
|
||||||
+ virq = irq_find_mapping(pcie->irq_domain, 0);
|
+ if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL)
|
||||||
+ if (generic_handle_irq(virq) == -EINVAL)
|
+ dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
|
||||||
+ dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
/* Process ERR interrupt */
|
/* Process MSI interrupts */
|
||||||
if (isr0_status & PCIE_ISR0_ERR_MASK) {
|
if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
|
||||||
advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG);
|
advk_pcie_handle_msi(pcie);
|
||||||
|
@ -1,173 +0,0 @@
|
|||||||
From 68727b545332327b4c2f9c0f8d006be8970e7832 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Fri, 19 Feb 2021 14:22:22 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Fix support for PME requester on emulated
|
|
||||||
bridge
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/pci/controller/pci-aardvark.c | 94 +++++++++++++++------------
|
|
||||||
1 file changed, 52 insertions(+), 42 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:
|
|
||||||
@@ -1445,6 +1436,34 @@ 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;
|
|
||||||
+ int virq;
|
|
||||||
+
|
|
||||||
+ 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;
|
|
||||||
+
|
|
||||||
+ virq = irq_find_mapping(pcie->irq_domain, 0);
|
|
||||||
+ if (generic_handle_irq(virq) == -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;
|
|
||||||
@@ -1480,18 +1499,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.
|
|
||||||
- */
|
|
||||||
- virq = irq_find_mapping(pcie->irq_domain, 0);
|
|
||||||
- if (generic_handle_irq(virq) == -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) {
|
|
@ -1,161 +0,0 @@
|
|||||||
From db305233136f5aa2444a8287a279384e8458c458 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Thu, 1 Apr 2021 20:12:48 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Use separate INTA interrupt for emulated root
|
|
||||||
bridge
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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;
|
|
||||||
@@ -1436,6 +1437,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;
|
|
||||||
@@ -1458,7 +1497,7 @@ static void advk_pcie_handle_pme(struct
|
|
||||||
if (!(le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & PCI_EXP_RTCTL_PMEIE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
- virq = irq_find_mapping(pcie->irq_domain, 0);
|
|
||||||
+ virq = irq_find_mapping(pcie->rp_irq_domain, 0);
|
|
||||||
if (generic_handle_irq(virq) == -EINVAL)
|
|
||||||
dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
|
|
||||||
}
|
|
||||||
@@ -1511,7 +1550,7 @@ static void advk_pcie_handle_int(struct
|
|
||||||
* Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use
|
|
||||||
* PCIe interrupt 0
|
|
||||||
*/
|
|
||||||
- virq = irq_find_mapping(pcie->irq_domain, 0);
|
|
||||||
+ virq = irq_find_mapping(pcie->rp_irq_domain, 0);
|
|
||||||
if (generic_handle_irq(virq) == -EINVAL)
|
|
||||||
dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
|
|
||||||
}
|
|
||||||
@@ -1556,6 +1595,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);
|
|
||||||
@@ -1757,14 +1811,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;
|
|
||||||
@@ -1816,6 +1880,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);
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
From 8c9eef96e24f34ff8b62b230700416b822691a37 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Thu, 1 Apr 2021 14:24:12 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Remove irq_mask_ack callback for INTx
|
|
||||||
interrupts
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Acked-by: Marc Zyngier <maz@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1415,7 +1415,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 =
|
|
@ -1,27 +0,0 @@
|
|||||||
From dc01fca5a9d9c09ce9a3fb2bc2e7715c37ff3bd9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
|
||||||
Date: Thu, 1 Apr 2021 14:30:06 +0200
|
|
||||||
Subject: [PATCH] PCI: aardvark: Don't mask irq when mapping
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
By default, all Legacy INTx interrupts are masked, so there is no need to
|
|
||||||
mask this interrupt during irq_map callback.
|
|
||||||
|
|
||||||
Signed-off-by: Pali Rohár <pali@kernel.org>
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1332,7 +1332,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);
|
|
@ -1,28 +0,0 @@
|
|||||||
From a511c99262ce19ee06908d27212b39ec4c5aeb17 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Wed, 8 Dec 2021 04:40:29 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Drop __maybe_unused from
|
|
||||||
advk_pcie_disable_phy()
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This function is now always used in driver remove method, drop the
|
|
||||||
__maybe_unused attribute.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@@ -1608,7 +1608,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);
|
|
@ -1,35 +0,0 @@
|
|||||||
From bafda858364003a70b9cda84282f9761587f8033 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 10 Jan 2022 00:47:38 +0100
|
|
||||||
Subject: [PATCH] PCI: aardvark: Update comment about link going down after
|
|
||||||
link-up
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
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;
|
|
@ -23,7 +23,7 @@ Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|||||||
|
|
||||||
--- a/drivers/pci/controller/pci-aardvark.c
|
--- a/drivers/pci/controller/pci-aardvark.c
|
||||||
+++ b/drivers/pci/controller/pci-aardvark.c
|
+++ b/drivers/pci/controller/pci-aardvark.c
|
||||||
@@ -1625,9 +1625,7 @@ static int advk_pcie_enable_phy(struct a
|
@@ -1634,9 +1634,7 @@ static int advk_pcie_enable_phy(struct a
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = phy_power_on(pcie->phy);
|
ret = phy_power_on(pcie->phy);
|
||||||
|
Loading…
Reference in New Issue
Block a user