2019-06-14 06:56:22

by Remi Pommarel

[permalink] [raw]
Subject: [PATCH v2] PCI: aardvark: Fix PCI_EXP_RTCTL conf register writing

PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
should not modify other interrupts' mask. The ISR mask polarity was also
inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
should actually be cleared.

Fixes: 6302bf3ef78d ("PCI: Init PCIe feature bits for managed host bridge alloc")
Signed-off-by: Remi Pommarel <[email protected]>
---
Changes since v1:
* Improve code readability
* Fix mask polarity
* PME_MASK shift was off by one
---
drivers/pci/controller/pci-aardvark.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 134e0306ff00..f6e55c4597b1 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -415,7 +415,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,

case PCI_EXP_RTCTL: {
u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
- *value = (val & PCIE_MSG_PM_PME_MASK) ? PCI_EXP_RTCTL_PMEIE : 0;
+ *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
return PCI_BRIDGE_EMUL_HANDLED;
}

@@ -451,10 +451,15 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
break;

- case PCI_EXP_RTCTL:
- new = (new & PCI_EXP_RTCTL_PMEIE) << 3;
- advk_writel(pcie, new, PCIE_ISR0_MASK_REG);
+ 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);
break;
+ }

case PCI_EXP_RTSTA:
new = (new & PCI_EXP_RTSTA_PME) >> 9;
--
2.20.1


2019-06-14 09:00:06

by Thomas Petazzoni

[permalink] [raw]
Subject: Re: [PATCH v2] PCI: aardvark: Fix PCI_EXP_RTCTL conf register writing

Hello,

On Fri, 14 Jun 2019 08:42:25 +0200
Remi Pommarel <[email protected]> wrote:

> PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> should not modify other interrupts' mask. The ISR mask polarity was also
> inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
> should actually be cleared.
>
> Fixes: 6302bf3ef78d ("PCI: Init PCIe feature bits for managed host bridge alloc")

Are you sure about this Fixes tag ? This commit seems unrelated.

The commit introducing this issue is 8a3ebd8de328301aacbe328650a59253be2ac82c.

Best regards,

Thomas
--
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-06-14 09:25:10

by Remi Pommarel

[permalink] [raw]
Subject: Re: [PATCH v2] PCI: aardvark: Fix PCI_EXP_RTCTL conf register writing

Hello,

On Fri, Jun 14, 2019 at 10:58:54AM +0200, Thomas Petazzoni wrote:
> Hello,
>
> On Fri, 14 Jun 2019 08:42:25 +0200
> Remi Pommarel <[email protected]> wrote:
>
> > PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> > should not modify other interrupts' mask. The ISR mask polarity was also
> > inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
> > should actually be cleared.
> >
> > Fixes: 6302bf3ef78d ("PCI: Init PCIe feature bits for managed host bridge alloc")
>
> Are you sure about this Fixes tag ? This commit seems unrelated.
>
> The commit introducing this issue is 8a3ebd8de328301aacbe328650a59253be2ac82c.

The 6302bf3ef78d commit fixes PCI bridge's PME flag which introduces the
configuration of PCI_EXP_RTCTL register (which wasn't used before). So,
yes, PCI_EXP_RTCTL conf was flawed since 8a3ebd8de328 but the infinite
interrupt loop happens only since that 6302bf3ef78d has fixed this PME
flag bug.

I chose to use 6302bf3ef78d because it was the one commit triggering
the bug during my bisect process, but yes maybe using the commit that
introduced (even if it was silently) the problem makes more sense.

So if you want I can do a v3 with this Fixes tag modification.

--
Remi