Re: [PATCH v4 12/18] PCI: rcar-gen4: Recover the Root Port on link down

From: Marek Vasut

Date: Sat Oct 17 2026 - 14:16:30 EST


On 10/15/26 5:30 AM, Koichiro Den wrote:
On R-Car, the controller's reset requests (smlh_req_rst_not,
link_req_rst_not) arrive on intreq_pcim_sub, the interrupt the MSIs are
demultiplexed from, so DBI is read as soon as the link goes down. On
R-Car S4 that is a hazard: DBI accesses issued within a few hundred
microseconds of an unexpected link down do not complete and hang the
host. In testing, the first Root Port config read after powering off
the link partner hung unless delayed by ~300 us.

Check the APP reset status in the interrupt handler before DBI is
touched. When a reset request is latched, flag the controller as
needing reinitialization, which masks the sources, ack the request and
schedule recovery work. The work calls pci_host_handle_link_down() on
the Root Port, which runs the AER-style recovery and resets the
controller through reset_root_port(), holding a reference on the port.
If the Root Port is absent when the work runs, reset the controller
directly so that successful reinitialization can restore interrupt
delivery. Hold the rescan lock across the absence check and reset.
The APP reset-status check also reports a recovery already pending,
whether started by another interrupt or left over from a failed reset,
so the handler issues no further DBI accesses until a reset succeeds.

Arm detection after initial PCI enumeration, so recovery does not
interrupt device discovery or resource assignment. Only unmasked status
bits are handled and pending latches are cleared when the sources are
re-enabled, so requests recorded during probe or the reset itself do
not trigger another recovery. Teardown only disarms the detection: MSI
delivery has to keep working while devices are removed.

Run recovery on a freezable workqueue to keep it outside device
suspend/resume. Reject suspend while a reset request is pending,
including one latched after the parent IRQs were suspended.
dw_pcie_suspend_noirq() would otherwise access DBI, and the queued
recovery can run once the system thaws. Disarm Root Port events during
suspend and re-arm them in .post_init() after resume has set up the
link, so taking the link down for suspend does not start recovery.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
Reviewed-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx>