Skip to content

PCI: qcom: Fix Asynchronous SError Interrupt on PCIe - #594

Open
BigfootACA wants to merge 18 commits into
radxa:linux-7.0.11from
BigfootACA:linux-7.0.11-fix-pcie-serror
Open

PCI: qcom: Fix Asynchronous SError Interrupt on PCIe#594
BigfootACA wants to merge 18 commits into
radxa:linux-7.0.11from
BigfootACA:linux-7.0.11-fix-pcie-serror

Conversation

@BigfootACA

Copy link
Copy Markdown

No description provided.

krishnachaitanya-linux and others added 18 commits August 15, 2026 15:30
When the PCIe link goes down unexpectedly, being able to inspect the
state of key controller registers at the time of failure is valuable
for root-causing the issue.

If a storage endpoint is present downstream, the dump is printed
directly via dev_err() so it is visible in dmesg immediately, since a
devcoredump read from userspace could otherwise race with a storage
failure. Otherwise, the buffer is handed to the devcoredump framework
so it can be collected from /sys/class/devcoredump/ for offline
analysis.

To keep the dump readable given the number of registers involved,
entries are packed as "offset: value" pairs, QCOM_PCIE_DUMP_REGS_PER_LINE
(4) per dmesg line, with a section header ("DBI registers:", "PARF
registers:", "MHI registers:") identifying each register group.

Also expose the same dump on demand via a new "regdump" debugfs file
under the existing per-controller debugfs directory, so the register
state can be inspected without needing an actual Link Down event.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
After a PCIe link goes down, software may still access the BAR (MMIO)
space or configuration space of devices behind that link before recovery
has run. As the link is down, these accesses never complete, resulting in
a storm of Completion Timeout AERs.

Use the controller's ECAM blocker to drop these accesses to the PCIe
address space as soon as the link-down interrupt fires, so that Completion
Timeout AERs are reduced. The blocked range covers the entire address
space (base 0x0, all-ones limit), since the Root Port's own DBI/iATU
register space remains accessible regardless.

The range is programmed once in the host init path, since the range
registers are wiped by BCR reset. This leaves only the ECAM_BLOCKER_EN
bit to be flipped from the link-down IRQ handler, so the blocker can be
armed with a single fast register write for immediate effect.

The subsequent Root Port reset re-initialises the controller, which clears
the enable bit and re-programs the range for the fresh link.

Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
…fic way

Some host bridge devices require resetting the Root Ports in a platform
specific way to recover them from error conditions such as Fatal AER
errors, Link Down, etc. Introduce pci_host_bridge::reset_root_port()
callback and call it from pcibios_reset_secondary_bus() if available. Also,
save the Root Port config space before reset and restore it afterwards.

The .reset_root_port() callback is responsible for resetting the given Root
Port referenced by the 'pci_dev' pointer in a platform-specific way and
bring it back to the working state if possible. If any error occurs during
the reset operation, relevant errno should be returned.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260729-pci-port-reset-v9-2-53570b92064d@oss.qualcomm.com
The PCIe link, when down, needs to be recovered to bring it back. But on
some platforms, that cannot be done in a generic way as link recovery
procedure is platform specific. Add a new pci_host_handle_link_down() that
could be called by the host bridge drivers for a specific Root Port when
the link goes down.

pci_host_handle_link_down() accepts a 'pci_dev' corresponding to the Root
Port that observed the link down event. If CONFIG_PCIEAER is enabled, it
calls pcie_do_recovery() with 'pci_channel_io_frozen' as the state.  This
will result in the execution of the AER Fatal error handling code.  Since
the link down recovery is pretty much the same as AER Fatal error handling,
reuse pcie_do_recovery() here.

The AER .error_detected() callback will be triggered for all of the
downstream devices, but not for the Root Port itself as there is nothing to
do for the Root Ports in the callbacks. Finally, pci_host_reset_root_port()
will be called for the Root Port, which will reset the Root Port using the
.reset_root_port() callback to recover the link. Once that's done, resume
message will be broadcasted to the bridge and the downstream devices,
indicating successful link recovery.

But if CONFIG_PCIEAER is not enabled in the kernel, only
pci_host_reset_root_port() will be called, which will in turn call
pci_bus_error_reset() to just reset the Root Port as there is no way we
could inform the drivers about link recovery.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260729-pci-port-reset-v9-3-53570b92064d@oss.qualcomm.com
The PCIe link can go down under circumstances such as the device firmware
crash, link instability, etc. When that happens, the Root Port needs to be
reset to make it operational again. Currently, the driver is not handling
the link down event, so users have to restart the machine to make PCIe link
operational again. Fix it by detecting the link down event and resetting
the Root Port.

Since the Qcom PCIe controllers report the link down event through the
'global' IRQ, enable the link down event by setting PARF_INT_ALL_LINK_DOWN
in the PARF_INT_ALL_MASK register.

In the case of the event, iterate through the available Root Ports and call
pci_host_handle_link_down() API with Root Port 'pci_dev' to let the PCI
core handle the link down condition. Since Qcom PCIe controllers only
support one Root Port per controller instance, the API will be called only
once. But the looping is necessary as there is no PCI API available to
fetch the Root Port instance without the child 'pci_dev'.

The API will internally call the 'pci_host_bridge::reset_root_port()'
callback to reset the Root Port in a platform-specific way. Implement the
callback to reset the Root Port by first resetting the PCIe core, followed
by reinitializing the resources and then finally starting the link again.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
[bhelgaas: subject]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729-pci-port-reset-v9-4-53570b92064d@oss.qualcomm.com
The Qualcomm PCIe controller reports link-down and other controller events
through the global interrupt. Allow SC8280XP to describe it as an optional
fifth interrupt after the four MSI interrupts.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Add the global controller-event interrupt for all five PCIe instances.
This allows the Qualcomm PCIe driver to receive link-down events and invoke
the Root Port recovery path.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Serialize concurrent recovery notifications and retain the final state.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Guard DesignWare config and MSI-X accesses after link failure.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Describe the optional controller reset used during Link Down recovery.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Block unsafe accesses and synchronize reset, IRQ, dump and shutdown paths.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Permit the optional NOCSR common reset on SC8280XP PCIe PHYs.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Pulse the optional NOCSR reset through the generic PHY reset callback.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Describe controller Link Down and PHY NOCSR reset lines.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Mark the hierarchy disconnected without reading an inaccessible Root Port.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Ignore PME requests once system device shutdown has started.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Do not access config space after the PCIe channel is offline.
Release error-device references when detailed status cannot be read.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
The ECAM blocker is relative to the controller ECAM aperture.
Block only its documented non-DBI range instead of PCI memory windows.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants