All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] PCI: aardvark controller fixes BATCH 4
@ 2021-12-08  6:18 Marek Behún
  2021-12-08  6:18 ` [PATCH 01/17] PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy() Marek Behún
                   ` (17 more replies)
  0 siblings, 18 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

Hello Lorenzo, Marc,

this is batch 4 of patches for Aardvark PCIe controller driver.

This series mainly fixes and adds support for stuff around interrupts.
(All but the first one.)

I have rebased it sot that first come patches that change the API to the
new one, as Marc requested. Marc, could you find time to review these?

Marek

Marek Behún (1):
  PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy()

Pali Rohár (16):
  PCI: aardvark: Rewrite IRQ code to chained IRQ handler
  PCI: aardvark: Fix support for MSI interrupts
  PCI: aardvark: Fix reading MSI interrupt number
  PCI: aardvark: Refactor unmasking summary MSI interrupt
  PCI: aardvark: Add support for masking MSI interrupts
  PCI: aardvark: Fix setting MSI address
  PCI: aardvark: Enable MSI-X support
  PCI: aardvark: Add support for ERR interrupt on emulated bridge
  PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
  PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and
    PCI_EXP_RTSTA_PME on emulated bridge
  PCI: aardvark: Add support for PME interrupts
  PCI: aardvark: Fix support for PME requester on emulated bridge
  PCI: aardvark: Use separate INTA interrupt for emulated root bridge
  PCI: aardvark: Check return value of generic_handle_domain_irq() when
    processing INTx IRQ
  PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts
  PCI: aardvark: Don't mask irq when mapping

 drivers/pci/controller/pci-aardvark.c | 332 +++++++++++++++++++-------
 1 file changed, 245 insertions(+), 87 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/17] PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy()
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 02/17] PCI: aardvark: Rewrite IRQ code to chained IRQ handler Marek Behún
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index b654d06b64df..e2ab23f0837f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1467,7 +1467,7 @@ static irqreturn_t advk_pcie_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/17] PCI: aardvark: Rewrite IRQ code to chained IRQ handler
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
  2021-12-08  6:18 ` [PATCH 01/17] PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy() Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 03/17] PCI: aardvark: Fix support for MSI interrupts Marek Behún
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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_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 e2ab23f0837f..e7edbc1fd4aa 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -273,6 +273,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;
@@ -1450,21 +1451,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 advk_pcie_disable_phy(struct advk_pcie *pcie)
@@ -1531,7 +1537,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)
@@ -1617,17 +1623,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,
@@ -1676,11 +1674,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;
@@ -1728,6 +1729,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.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/17] PCI: aardvark: Fix support for MSI interrupts
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
  2021-12-08  6:18 ` [PATCH 01/17] PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy() Marek Behún
  2021-12-08  6:18 ` [PATCH 02/17] PCI: aardvark: Rewrite IRQ code to chained IRQ handler Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number Marek Behún
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

Aardvark hardware supports Multi-MSI and MSI_FLAG_MULTI_PCI_MSI is already
set for the MSI chip. But when allocating MSI interrupt numbers for
Multi-MSI, the numbers need to be properly aligned, otherwise endpoint
devices send MSI interrupt with incorrect numbers.

Fix this issue by using function bitmap_find_free_region() instead of
bitmap_find_next_zero_area().

To ensure that aligned MSI interrupt numbers are used by endpoint devices,
we cannot use Linux virtual irq numbers (as they are random and not
properly aligned). Instead we need to use the aligned hwirq numbers.

This change fixes receiving MSI interrupts on Armada 3720 boards and
allows using NVMe disks which use Multi-MSI feature with 3 interrupts.

Without this NVMe disks freeze booting as linux nvme-core.c is waiting
60s for an 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 | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index e7edbc1fd4aa..681d93a15be1 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1194,7 +1194,7 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,
 
 	msg->address_lo = lower_32_bits(msi_msg);
 	msg->address_hi = upper_32_bits(msi_msg);
-	msg->data = data->irq;
+	msg->data = data->hwirq;
 }
 
 static int advk_msi_set_affinity(struct irq_data *irq_data,
@@ -1211,15 +1211,11 @@ static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 	int hwirq, i;
 
 	mutex_lock(&pcie->msi_used_lock);
-	hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM,
-					   0, nr_irqs, 0);
-	if (hwirq >= MSI_IRQ_NUM) {
-		mutex_unlock(&pcie->msi_used_lock);
-		return -ENOSPC;
-	}
-
-	bitmap_set(pcie->msi_used, hwirq, nr_irqs);
+	hwirq = bitmap_find_free_region(pcie->msi_used, MSI_IRQ_NUM,
+					order_base_2(nr_irqs));
 	mutex_unlock(&pcie->msi_used_lock);
+	if (hwirq < 0)
+		return -ENOSPC;
 
 	for (i = 0; i < nr_irqs; i++)
 		irq_domain_set_info(domain, virq + i, hwirq + i,
@@ -1237,7 +1233,7 @@ static void advk_msi_irq_domain_free(struct irq_domain *domain,
 	struct advk_pcie *pcie = domain->host_data;
 
 	mutex_lock(&pcie->msi_used_lock);
-	bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs);
+	bitmap_release_region(pcie->msi_used, d->hwirq, order_base_2(nr_irqs));
 	mutex_unlock(&pcie->msi_used_lock);
 }
 
@@ -1414,7 +1410,9 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 		 */
 		advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
 		msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & PCIE_MSI_DATA_MASK;
-		generic_handle_irq(msi_data);
+
+		if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_data) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_data);
 	}
 
 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (2 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 03/17] PCI: aardvark: Fix support for MSI interrupts Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08 13:38     ` kernel test robot
  2021-12-08  6:18 ` [PATCH 05/17] PCI: aardvark: Refactor unmasking summary MSI interrupt Marek Behún
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

In advk_pcie_handle_msi() the authors expect that when bit i in the W1C
register PCIE_MSI_STATUS_REG is cleared, the PCIE_MSI_PAYLOAD_REG is
updated to contain the MSI number corresponding to index i.

Experiments show that this is not so, and instead PCIE_MSI_PAYLOAD_REG
always contains the number of the last received MSI, overall.

Do not read PCIE_MSI_PAYLOAD_REG register for determining MSI interrupt
number. Since Aardvark already forbids more than 32 interrupts and uses
own allocated hwirq numbers, the msi_idx already corresponds to the
received MSI number.

Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
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, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 681d93a15be1..7ea18f0ab8ad 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1394,7 +1394,6 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 {
 	u32 msi_val, msi_mask, msi_status, msi_idx;
-	u16 msi_data;
 
 	msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
 	msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
@@ -1404,15 +1403,10 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 		if (!(BIT(msi_idx) & msi_status))
 			continue;
 
-		/*
-		 * msi_idx contains bits [4:0] of the msi_data and msi_data
-		 * contains 16bit MSI interrupt number
-		 */
 		advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
-		msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & PCIE_MSI_DATA_MASK;
 
-		if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_data) == -EINVAL)
-			dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_data);
+		if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_idx) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_idx);
 	}
 
 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/17] PCI: aardvark: Refactor unmasking summary MSI interrupt
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (3 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 06/17] PCI: aardvark: Add support for masking MSI interrupts Marek Behún
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 7ea18f0ab8ad..f03dd5d8213a 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -579,15 +579,17 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/17] PCI: aardvark: Add support for masking MSI interrupts
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (4 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 05/17] PCI: aardvark: Refactor unmasking summary MSI interrupt Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 07/17] PCI: aardvark: Fix setting MSI address Marek Behún
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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 | 52 ++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index f03dd5d8213a..74b60cb2e6fd 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -281,6 +281,7 @@ struct advk_pcie {
 	struct irq_domain *msi_inner_domain;
 	struct irq_chip msi_bottom_irq_chip;
 	struct irq_chip msi_irq_chip;
+	raw_spinlock_t msi_irq_lock;
 	struct msi_domain_info msi_domain_info;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
 	struct mutex msi_used_lock;
@@ -578,12 +579,10 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	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);
@@ -1205,6 +1204,46 @@ static int advk_msi_set_affinity(struct irq_data *irq_data,
 	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 int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 				     unsigned int virq,
 				     unsigned int nr_irqs, void *args)
@@ -1299,6 +1338,7 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 	struct msi_domain_info *msi_di;
 	phys_addr_t msi_msg_phys;
 
+	raw_spin_lock_init(&pcie->msi_irq_lock);
 	mutex_init(&pcie->msi_used_lock);
 
 	bottom_ic = &pcie->msi_bottom_irq_chip;
@@ -1306,9 +1346,13 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 	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;
+	bottom_ic->irq_mask = advk_msi_irq_mask;
+	bottom_ic->irq_unmask = advk_msi_irq_unmask;
 
 	msi_ic = &pcie->msi_irq_chip;
 	msi_ic->name = "advk-MSI";
+	msi_ic->irq_mask = advk_msi_top_irq_mask;
+	msi_ic->irq_unmask = advk_msi_top_irq_unmask;
 
 	msi_di = &pcie->msi_domain_info;
 	msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/17] PCI: aardvark: Fix setting MSI address
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (5 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 06/17] PCI: aardvark: Add support for masking MSI interrupts Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 08/17] PCI: aardvark: Enable MSI-X support Marek Behún
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier
  Cc: linux-pci, pali, Marc Zyngier, Marek Behún, stable

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 74b60cb2e6fd..d518cface0a7 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -285,7 +285,6 @@ struct advk_pcie {
 	struct msi_domain_info msi_domain_info;
 	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;
@@ -480,6 +479,7 @@ static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num)
 
 static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 {
+	phys_addr_t msi_addr;
 	u32 reg;
 	int i;
 
@@ -568,6 +568,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	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;
@@ -1191,10 +1196,10 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,
 					 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;
 }
 
@@ -1336,7 +1341,6 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 	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;
 
 	raw_spin_lock_init(&pcie->msi_irq_lock);
 	mutex_init(&pcie->msi_used_lock);
@@ -1359,13 +1363,6 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 		MSI_FLAG_MULTI_PCI_MSI;
 	msi_di->chip = msi_ic;
 
-	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/17] PCI: aardvark: Enable MSI-X support
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (6 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 07/17] PCI: aardvark: Fix setting MSI address Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 09/17] PCI: aardvark: Add support for ERR interrupt on emulated bridge Marek Behún
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index d518cface0a7..24c67dc983e5 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1360,7 +1360,7 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 
 	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_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX;
 	msi_di->chip = msi_ic;
 
 	pcie->msi_inner_domain =
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/17] PCI: aardvark: Add support for ERR interrupt on emulated bridge
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (7 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 08/17] PCI: aardvark: Enable MSI-X support Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 10/17] PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit " Marek Behún
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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 | 35 ++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 24c67dc983e5..d5dcb3322d56 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -103,6 +103,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)
@@ -790,11 +794,15 @@ advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
 	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
@@ -824,6 +832,19 @@ advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 		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))
@@ -1470,6 +1491,18 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/17] PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (8 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 09/17] PCI: aardvark: Add support for ERR interrupt on emulated bridge Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 11/17] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME " Marek Behún
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

The emulated bridge returns incorrect value for PCI_EXP_RTSTA register
during readout in advk_pci_bridge_emul_pcie_conf_read() function: the
correct bit is BIT(16), but we are setting BIT(23), because the code
does
  *value = (isr0 & PCIE_MSG_PM_PME_MASK) << 16
where
  PCIE_MSG_PM_PME_MASK
is
  BIT(7).

The code should probably have been something like
  *value = (!!(isr0 & PCIE_MSG_PM_PME_MASK)) << 16,
but we are better of using an if() and using the proper macro for this
bit.

Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space")
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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index d5dcb3322d56..f7d553a63f06 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -883,7 +883,9 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 	case PCI_EXP_RTSTA: {
 		u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG);
 		u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG);
-		*value = (isr0 & PCIE_MSG_PM_PME_MASK) << 16 | (msglog >> 16);
+		*value = msglog >> 16;
+		if (isr0 & PCIE_MSG_PM_PME_MASK)
+			*value |= PCI_EXP_RTSTA_PME;
 		return PCI_BRIDGE_EMUL_HANDLED;
 	}
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/17] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME on emulated bridge
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (9 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 10/17] PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit " Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 12/17] PCI: aardvark: Add support for PME interrupts Marek Behún
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index f7d553a63f06..1c7485489632 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -942,19 +942,21 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 			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:
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 12/17] PCI: aardvark: Add support for PME interrupts
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (10 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 11/17] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME " Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge Marek Behún
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 1c7485489632..3cf454ddc005 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1495,6 +1495,18 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (11 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 12/17] PCI: aardvark: Add support for PME interrupts Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2022-01-05 11:07   ` Marek Behún
  2021-12-08  6:18 ` [PATCH 14/17] PCI: aardvark: Use separate INTA interrupt for emulated root bridge Marek Behún
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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 | 90 +++++++++++++++------------
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 3cf454ddc005..bea44bd5cc0c 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -598,6 +598,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	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);
@@ -872,22 +877,11 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 		*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);
@@ -942,22 +936,19 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 			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:
@@ -1459,6 +1450,31 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 	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) {
+			if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+				dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
+		}
+	}
+}
+
 static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 {
 	u32 msi_val, msi_mask, msi_status, msi_idx;
@@ -1495,17 +1511,9 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	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) {
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/17] PCI: aardvark: Use separate INTA interrupt for emulated root bridge
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (12 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 15/17] PCI: aardvark: Check return value of generic_handle_domain_irq() when processing INTx IRQ Marek Behún
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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-EMU 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 | 66 ++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index bea44bd5cc0c..b3e64ae8c438 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -278,6 +278,8 @@ struct advk_pcie {
 	} wins[OB_WIN_COUNT];
 	u8 wins_count;
 	int irq;
+	struct irq_domain *emul_irq_domain;
+	struct irq_chip emul_irq_chip;
 	struct irq_domain *irq_domain;
 	struct irq_chip irq_chip;
 	raw_spinlock_t irq_lock;
@@ -1450,6 +1452,40 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 	irq_domain_remove(pcie->irq_domain);
 }
 
+static int advk_pcie_emul_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, &pcie->emul_irq_chip, handle_simple_irq);
+	irq_set_chip_data(virq, pcie);
+
+	return 0;
+}
+
+static const struct irq_domain_ops advk_pcie_emul_irq_domain_ops = {
+	.map = advk_pcie_emul_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int advk_pcie_init_emul_irq_domain(struct advk_pcie *pcie)
+{
+	pcie->emul_irq_chip.name = "advk-EMU";
+	pcie->emul_irq_domain = irq_domain_add_linear(NULL, 1,
+				&advk_pcie_emul_irq_domain_ops, pcie);
+	if (!pcie->emul_irq_domain) {
+		dev_err(&pcie->pdev->dev, "Failed to add emul IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void advk_pcie_remove_emul_irq_domain(struct advk_pcie *pcie)
+{
+	irq_domain_remove(pcie->emul_irq_domain);
+}
+
 static void advk_pcie_handle_pme(struct advk_pcie *pcie)
 {
 	u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16;
@@ -1469,7 +1505,7 @@ static void advk_pcie_handle_pme(struct advk_pcie *pcie)
 		 * 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) {
-			if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+			if (generic_handle_domain_irq(pcie->emul_irq_domain, 0) == -EINVAL)
 				dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
 		}
 	}
@@ -1523,7 +1559,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 		 * 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->emul_irq_domain, 0) == -EINVAL)
 			dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
 	}
 
@@ -1565,6 +1601,21 @@ static void advk_pcie_irq_handler(struct irq_desc *desc)
 	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->emul_irq_domain, pin - 1);
+	else
+		return of_irq_parse_and_map_pci(dev, slot, pin);
+}
+
 static void advk_pcie_disable_phy(struct advk_pcie *pcie)
 {
 	phy_power_off(pcie->phy);
@@ -1766,14 +1817,24 @@ static int advk_pcie_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = advk_pcie_init_emul_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_emul_irq_domain(pcie);
 		advk_pcie_remove_msi_irq_domain(pcie);
 		advk_pcie_remove_irq_domain(pcie);
 		return ret;
@@ -1825,6 +1886,7 @@ static int advk_pcie_remove(struct platform_device *pdev)
 	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 
 	/* Remove IRQ domains */
+	advk_pcie_remove_emul_irq_domain(pcie);
 	advk_pcie_remove_msi_irq_domain(pcie);
 	advk_pcie_remove_irq_domain(pcie);
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 15/17] PCI: aardvark: Check return value of generic_handle_domain_irq() when processing INTx IRQ
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (13 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 14/17] PCI: aardvark: Use separate INTA interrupt for emulated root bridge Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 16/17] PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts Marek Behún
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index b3e64ae8c438..3cde3f761696 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1575,7 +1575,9 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 		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');
 	}
 }
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 16/17] PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (14 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 15/17] PCI: aardvark: Check return value of generic_handle_domain_irq() when processing INTx IRQ Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:18 ` [PATCH 17/17] PCI: aardvark: Don't mask irq when mapping Marek Behún
  2021-12-08  6:22 ` [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier
  Cc: linux-pci, pali, Marc Zyngier, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 3cde3f761696..4a21387a4693 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1430,7 +1430,6 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
 	}
 
 	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 =
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 17/17] PCI: aardvark: Don't mask irq when mapping
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (15 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 16/17] PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts Marek Behún
@ 2021-12-08  6:18 ` Marek Behún
  2021-12-08  6:22 ` [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
  17 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:18 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali, Marek Behún

From: Pali Rohár <pali@kernel.org>

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(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 4a21387a4693..b1b6620b1d9a 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1339,7 +1339,6 @@ static int advk_pcie_irq_map(struct irq_domain *h,
 {
 	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/17] PCI: aardvark controller fixes BATCH 4
  2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
                   ` (16 preceding siblings ...)
  2021-12-08  6:18 ` [PATCH 17/17] PCI: aardvark: Don't mask irq when mapping Marek Behún
@ 2021-12-08  6:22 ` Marek Behún
  2021-12-08  7:55   ` Marc Zyngier
  17 siblings, 1 reply; 24+ messages in thread
From: Marek Behún @ 2021-12-08  6:22 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: Lorenzo Pieralisi, Marc Zyngier, linux-pci, pali

Hello Marc,

sorry about this, I wanted to send this series also to you, but
I accidentally sent it to your @arm.com e-mail address.
Does that address still work? Should I resend to your @kernel.org
address?

Marek

On Wed,  8 Dec 2021 07:18:34 +0100
Marek Behún <kabel@kernel.org> wrote:

> Hello Lorenzo, Marc,
> 
> this is batch 4 of patches for Aardvark PCIe controller driver.
> 
> This series mainly fixes and adds support for stuff around interrupts.
> (All but the first one.)
> 
> I have rebased it sot that first come patches that change the API to the
> new one, as Marc requested. Marc, could you find time to review these?
> 
> Marek
> 
> Marek Behún (1):
>   PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy()
> 
> Pali Rohár (16):
>   PCI: aardvark: Rewrite IRQ code to chained IRQ handler
>   PCI: aardvark: Fix support for MSI interrupts
>   PCI: aardvark: Fix reading MSI interrupt number
>   PCI: aardvark: Refactor unmasking summary MSI interrupt
>   PCI: aardvark: Add support for masking MSI interrupts
>   PCI: aardvark: Fix setting MSI address
>   PCI: aardvark: Enable MSI-X support
>   PCI: aardvark: Add support for ERR interrupt on emulated bridge
>   PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
>   PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and
>     PCI_EXP_RTSTA_PME on emulated bridge
>   PCI: aardvark: Add support for PME interrupts
>   PCI: aardvark: Fix support for PME requester on emulated bridge
>   PCI: aardvark: Use separate INTA interrupt for emulated root bridge
>   PCI: aardvark: Check return value of generic_handle_domain_irq() when
>     processing INTx IRQ
>   PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts
>   PCI: aardvark: Don't mask irq when mapping
> 
>  drivers/pci/controller/pci-aardvark.c | 332 +++++++++++++++++++-------
>  1 file changed, 245 insertions(+), 87 deletions(-)
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/17] PCI: aardvark controller fixes BATCH 4
  2021-12-08  6:22 ` [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
@ 2021-12-08  7:55   ` Marc Zyngier
  2022-01-04 18:41     ` Marek Behún
  0 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2021-12-08  7:55 UTC (permalink / raw)
  To: Marek Behún; +Cc: Lorenzo Pieralisi, linux-pci, pali

On 2021-12-08 06:22, Marek Behún wrote:
> Hello Marc,
> 
> sorry about this, I wanted to send this series also to you, but
> I accidentally sent it to your @arm.com e-mail address.
> Does that address still work? Should I resend to your @kernel.org
> address?

My @arm.com address stopped working over two years ago. I guess
my ex-manager is busy reviewing your patches!

No need to resend, I'll fetch the series from lore.

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number
  2021-12-08  6:18 ` [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number Marek Behún
@ 2021-12-08 13:38     ` kernel test robot
  0 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-12-08 13:38 UTC (permalink / raw)
  To: Marek Behún; +Cc: llvm, kbuild-all

Hi "Marek,

I love your patch! Perhaps something to improve:

[auto build test WARNING on helgaas-pci/next]
[also build test WARNING on next-20211208]
[cannot apply to v5.16-rc4]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Marek-Beh-n/PCI-aardvark-controller-fixes-BATCH-4/20211208-141958
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: arm64-randconfig-r022-20211207 (https://download.01.org/0day-ci/archive/20211208/202112082134.fNH8OE60-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 097a1cb1d5ebb3a0ec4bcaed8ba3ff6a8e33c00a)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/1d0822699fe4ce28186773b9186410166165fd0f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Marek-Beh-n/PCI-aardvark-controller-fixes-BATCH-4/20211208-141958
        git checkout 1d0822699fe4ce28186773b9186410166165fd0f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/pci/controller/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/pci/controller/pci-aardvark.c:1409:70: warning: format specifies type 'unsigned short' but the argument has type 'u32' (aka 'unsigned int') [-Wformat]
                           dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_idx);
                                                                                   ~~~~~     ^~~~~~~
                                                                                   %04x
   include/linux/dev_printk.h:218:45: note: expanded from macro 'dev_err_ratelimited'
           dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
                                               ~~~    ^~~~~~~~~~~
   include/linux/dev_printk.h:208:25: note: expanded from macro 'dev_level_ratelimited'
                   dev_level(dev, fmt, ##__VA_ARGS__);                     \
                                  ~~~    ^~~~~~~~~~~
   include/linux/dev_printk.h:144:65: note: expanded from macro 'dev_err'
           dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                  ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
   1 warning generated.


vim +1409 drivers/pci/controller/pci-aardvark.c

  1393	
  1394	static void advk_pcie_handle_msi(struct advk_pcie *pcie)
  1395	{
  1396		u32 msi_val, msi_mask, msi_status, msi_idx;
  1397	
  1398		msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
  1399		msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
  1400		msi_status = msi_val & ((~msi_mask) & PCIE_MSI_ALL_MASK);
  1401	
  1402		for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) {
  1403			if (!(BIT(msi_idx) & msi_status))
  1404				continue;
  1405	
  1406			advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
  1407	
  1408			if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_idx) == -EINVAL)
> 1409				dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_idx);
  1410		}
  1411	
  1412		advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
  1413			    PCIE_ISR0_REG);
  1414	}
  1415	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number
@ 2021-12-08 13:38     ` kernel test robot
  0 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-12-08 13:38 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4224 bytes --]

Hi "Marek,

I love your patch! Perhaps something to improve:

[auto build test WARNING on helgaas-pci/next]
[also build test WARNING on next-20211208]
[cannot apply to v5.16-rc4]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Marek-Beh-n/PCI-aardvark-controller-fixes-BATCH-4/20211208-141958
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: arm64-randconfig-r022-20211207 (https://download.01.org/0day-ci/archive/20211208/202112082134.fNH8OE60-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 097a1cb1d5ebb3a0ec4bcaed8ba3ff6a8e33c00a)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/1d0822699fe4ce28186773b9186410166165fd0f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Marek-Beh-n/PCI-aardvark-controller-fixes-BATCH-4/20211208-141958
        git checkout 1d0822699fe4ce28186773b9186410166165fd0f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/pci/controller/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/pci/controller/pci-aardvark.c:1409:70: warning: format specifies type 'unsigned short' but the argument has type 'u32' (aka 'unsigned int') [-Wformat]
                           dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_idx);
                                                                                   ~~~~~     ^~~~~~~
                                                                                   %04x
   include/linux/dev_printk.h:218:45: note: expanded from macro 'dev_err_ratelimited'
           dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
                                               ~~~    ^~~~~~~~~~~
   include/linux/dev_printk.h:208:25: note: expanded from macro 'dev_level_ratelimited'
                   dev_level(dev, fmt, ##__VA_ARGS__);                     \
                                  ~~~    ^~~~~~~~~~~
   include/linux/dev_printk.h:144:65: note: expanded from macro 'dev_err'
           dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                  ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
   1 warning generated.


vim +1409 drivers/pci/controller/pci-aardvark.c

  1393	
  1394	static void advk_pcie_handle_msi(struct advk_pcie *pcie)
  1395	{
  1396		u32 msi_val, msi_mask, msi_status, msi_idx;
  1397	
  1398		msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
  1399		msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
  1400		msi_status = msi_val & ((~msi_mask) & PCIE_MSI_ALL_MASK);
  1401	
  1402		for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) {
  1403			if (!(BIT(msi_idx) & msi_status))
  1404				continue;
  1405	
  1406			advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
  1407	
  1408			if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_idx) == -EINVAL)
> 1409				dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%04hx\n", msi_idx);
  1410		}
  1411	
  1412		advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
  1413			    PCIE_ISR0_REG);
  1414	}
  1415	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/17] PCI: aardvark controller fixes BATCH 4
  2021-12-08  7:55   ` Marc Zyngier
@ 2022-01-04 18:41     ` Marek Behún
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2022-01-04 18:41 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: Lorenzo Pieralisi, linux-pci, pali

On Wed, 08 Dec 2021 07:55:48 +0000
Marc Zyngier <maz@kernel.org> wrote:

> On 2021-12-08 06:22, Marek Behún wrote:
> > Hello Marc,
> > 
> > sorry about this, I wanted to send this series also to you, but
> > I accidentally sent it to your @arm.com e-mail address.
> > Does that address still work? Should I resend to your @kernel.org
> > address?  
> 
> My @arm.com address stopped working over two years ago. I guess
> my ex-manager is busy reviewing your patches!
> 
> No need to resend, I'll fetch the series from lore.
> 
> Thanks,
> 
>          M.

Hello Marc,

did you manage to find some time to look at this series?

Thanks.

Marek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge
  2021-12-08  6:18 ` [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge Marek Behún
@ 2022-01-05 11:07   ` Marek Behún
  0 siblings, 0 replies; 24+ messages in thread
From: Marek Behún @ 2022-01-05 11:07 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Marc Zyngier; +Cc: linux-pci, pali

On Wed,  8 Dec 2021 07:18:47 +0100
Marek Behún <kabel@kernel.org> wrote:

> +				dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");

This should say "unhandled PME IRQ\n". Ah.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2022-01-05 11:07 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-08  6:18 [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
2021-12-08  6:18 ` [PATCH 01/17] PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy() Marek Behún
2021-12-08  6:18 ` [PATCH 02/17] PCI: aardvark: Rewrite IRQ code to chained IRQ handler Marek Behún
2021-12-08  6:18 ` [PATCH 03/17] PCI: aardvark: Fix support for MSI interrupts Marek Behún
2021-12-08  6:18 ` [PATCH 04/17] PCI: aardvark: Fix reading MSI interrupt number Marek Behún
2021-12-08 13:38   ` kernel test robot
2021-12-08 13:38     ` kernel test robot
2021-12-08  6:18 ` [PATCH 05/17] PCI: aardvark: Refactor unmasking summary MSI interrupt Marek Behún
2021-12-08  6:18 ` [PATCH 06/17] PCI: aardvark: Add support for masking MSI interrupts Marek Behún
2021-12-08  6:18 ` [PATCH 07/17] PCI: aardvark: Fix setting MSI address Marek Behún
2021-12-08  6:18 ` [PATCH 08/17] PCI: aardvark: Enable MSI-X support Marek Behún
2021-12-08  6:18 ` [PATCH 09/17] PCI: aardvark: Add support for ERR interrupt on emulated bridge Marek Behún
2021-12-08  6:18 ` [PATCH 10/17] PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit " Marek Behún
2021-12-08  6:18 ` [PATCH 11/17] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME " Marek Behún
2021-12-08  6:18 ` [PATCH 12/17] PCI: aardvark: Add support for PME interrupts Marek Behún
2021-12-08  6:18 ` [PATCH 13/17] PCI: aardvark: Fix support for PME requester on emulated bridge Marek Behún
2022-01-05 11:07   ` Marek Behún
2021-12-08  6:18 ` [PATCH 14/17] PCI: aardvark: Use separate INTA interrupt for emulated root bridge Marek Behún
2021-12-08  6:18 ` [PATCH 15/17] PCI: aardvark: Check return value of generic_handle_domain_irq() when processing INTx IRQ Marek Behún
2021-12-08  6:18 ` [PATCH 16/17] PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts Marek Behún
2021-12-08  6:18 ` [PATCH 17/17] PCI: aardvark: Don't mask irq when mapping Marek Behún
2021-12-08  6:22 ` [PATCH 00/17] PCI: aardvark controller fixes BATCH 4 Marek Behún
2021-12-08  7:55   ` Marc Zyngier
2022-01-04 18:41     ` Marek Behún

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.