| Message ID | 20261002091029.2225203-3-stefan.roese@mailbox.org |
|---|---|
| State | New |
| Headers | show |
| Series | PCI: Fix Renesas uPD720201 hang after the RCB Link Control write | expand |
> pci_configure_rcb() read-modify-writes Link Control of every endpoint > at enumeration, also when RCB is clear in the Root Port and there is > nothing to set. Not writing a register that has nothing to change is > justified on its own, but the write-back of the other Link Control bits > also has side effects on some devices: the Renesas uPD720201 xHCI > (1912:0014) comes out of reset with ASPM L0s and L1 enabled and stops > clearing them itself once Link Control has been written. On a link > whose Root Port supports no ASPM, the previous patch clears them, but > it does not run with pcie_aspm=off or CONFIG_PCIEASPM=n. There the > first access to the xHCI BAR runs into completion timeouts that hang > the system. > > RCB may only be set in an endpoint if it is set in the Root Port, so > there is no need to ever clear it here; an endpoint with RCB set > below a Root Port without it is a firmware configuration error. Only > set RCB, and only when the Root Port has it set. > > Fixes: 1a6845aaa6de ("PCI: Initialize RCB from pci_configure_device()") > Cc: stable@vger.kernel.org > Suggested-by: Bjorn Helgaas <bhelgaas@google.com> > Assisted-by: Claude:claude-opus-5-5 > Signed-off-by: Stefan Roese <stefan.roese@mailbox.org> Sashiko has reviewed this patch and found no issues. It looks great!
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 721daf5c5184..0d05536216fb 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2448,10 +2448,9 @@ static void pci_configure_rcb(struct pci_dev *dev) return; pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &rp_lnkctl); - pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_RCB, - (rp_lnkctl & PCI_EXP_LNKCTL_RCB) ? - PCI_EXP_LNKCTL_RCB : 0); + if (rp_lnkctl & PCI_EXP_LNKCTL_RCB) + pcie_capability_set_word(dev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_RCB); } static void pci_configure_device(struct pci_dev *dev)
pci_configure_rcb() read-modify-writes Link Control of every endpoint at enumeration, also when RCB is clear in the Root Port and there is nothing to set. Not writing a register that has nothing to change is justified on its own, but the write-back of the other Link Control bits also has side effects on some devices: the Renesas uPD720201 xHCI (1912:0014) comes out of reset with ASPM L0s and L1 enabled and stops clearing them itself once Link Control has been written. On a link whose Root Port supports no ASPM, the previous patch clears them, but it does not run with pcie_aspm=off or CONFIG_PCIEASPM=n. There the first access to the xHCI BAR runs into completion timeouts that hang the system. RCB may only be set in an endpoint if it is set in the Root Port, so there is no need to ever clear it here; an endpoint with RCB set below a Root Port without it is a firmware configuration error. Only set RCB, and only when the Root Port has it set. Fixes: 1a6845aaa6de ("PCI: Initialize RCB from pci_configure_device()") Cc: stable@vger.kernel.org Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Stefan Roese <stefan.roese@mailbox.org> --- Changes in v2: - Replace "PCI: Write RCB only when it changes" (v1 1/2) with the set-only variant suggested by Bjorn: never clear RCB, set it only when the Root Port has it set - Now patch 2/2, still with Fixes: and stable, because with pcie_aspm=off or CONFIG_PCIEASPM=n patch 1 never runs and only avoiding the Link Control write prevents the hang --- drivers/pci/probe.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)