PCI: qcom: Fix Asynchronous SError Interrupt on PCIe - #594
Open
BigfootACA wants to merge 18 commits into
Open
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.