From: Bjorn Helgaas <helgaas@kernel.org>
To: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Cc: bhelgaas@google.com, alex@shazbot.org, jjohnson@kernel.org,
mani@kernel.org, linux-pci@vger.kernel.org,
linux-wireless@vger.kernel.org, ath11k@lists.infradead.org,
ath12k@lists.infradead.org, mhi@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH v7 1/3] PCI: Add d3cold as general reset method
Date: Wed, 10 Jun 2026 13:42:36 -0500 [thread overview]
Message-ID: <20260610184236.GA236984@bhelgaas> (raw)
In-Reply-To: <20260603105853.326290-2-jtornosm@redhat.com>
[+cc linux-pm]
On Wed, Jun 03, 2026 at 12:58:51PM +0200, Jose Ignacio Tornos Martinez wrote:
> Add D3cold power cycle as a general PCI reset method for single-function
> devices on platforms with ACPI _PR3 power resources. This provides true
> power cycle reset capability when the platform can physically cut power
> to the device.
>
> The implementation strictly requires _PR3 to be present - the platform
> must be able to control device power. This ensures d3cold only attempts
> true power cycling, not falling back to D3hot transitions.
>
> D3cold reset is placed at the end of the reset hierarchy since it requires
> specific platform support and should be tried after standard methods.
>
> Reset hierarchy with this change:
> 1. device_specific
> 2. acpi
> 3. flr
> 4. af_flr
> 5. pm (D3hot via config space, checks NoSoftRst)
> 6. bus (SBR)
> 7. cxl_bus
> 8. d3cold (NEW - true power cycle, requires _PR3)
>
> This benefits:
> - Platforms with _PR3 support
> - Single-function devices needing true power cycle
> - VFIO passthrough scenarios where FLR/PM unavailable
I assume you have some specific device(s) in mind here; can we mention
any examples so this is more than just theoretically useful?
> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
> ---
> v7: code unchanged from v6
> v6: https://lore.kernel.org/all/20260602160024.1171949-2-jtornosm@redhat.com/
>
> drivers/pci/pci.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
> include/linux/pci.h | 2 +-
> 2 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 8f7cfcc00090..096868f80cd4 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4491,6 +4491,55 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
> return ret;
> }
>
> +/**
> + * pci_d3cold_reset - Put device into D3cold and back to D0 for reset
> + * @dev: PCI device to reset
> + * @probe: if true, check if D3cold reset is supported; if false, perform reset
> + *
> + * Reset the device by transitioning through D3cold (actual power removal via
> + * platform power control) and back to D0. This requires ACPI _PR3 power
> + * resources to be present - the platform must be able to physically cut power
> + * to the device.
> + *
> + * Only available for single-function devices to avoid affecting other
> + * functions in multi-function devices.
> + *
> + * Returns 0 if device can be/was reset this way, -ENOTTY if not supported,
> + * or other negative error code on failure.
> + */
> +static int pci_d3cold_reset(struct pci_dev *dev, bool probe)
> +{
> + int ret;
> +
> + if (dev->multifunction)
> + return -ENOTTY;
> +
> + if (!pci_pr3_present(dev))
> + return -ENOTTY;
platform_pci_set_power_state() is currently only implemented for MID
and ACPI, but we're starting to see DT systems with power control for
devices, so I assume it may someday be extended to support them.
Checking pci_pr3_present() seems wrong to me because it assumes ACPI.
On ACPI systems, it seems like pci_set_power_state(PCI_D3cold) should
return an error if the necessary ACPI methods are not present, and we
wouldn't need this check. Is that not the case?
Or is this _PR3 check here just to support the "probe"? I don't know
if there's a generic interface to tell us whether we can control the
power to a device.
> + if (probe)
> + return 0;
> +
> + if (dev->current_state != PCI_D0)
> + return -EINVAL;
> +
> + ret = pci_dev_reset_iommu_prepare(dev);
> + if (ret) {
> + pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", ret);
> + return ret;
> + }
> +
> + ret = pci_set_power_state(dev, PCI_D3cold);
> + if (ret)
> + goto done;
> +
> + ret = pci_set_power_state(dev, PCI_D0);
> +
> +done:
> + pci_dev_reset_iommu_done(dev);
> + return ret;
> +}
> +
> /**
> * pcie_wait_for_link_status - Wait for link status change
> * @pdev: Device whose link to wait for.
> @@ -5065,6 +5114,7 @@ const struct pci_reset_fn_method pci_reset_fn_methods[] = {
> { pci_pm_reset, .name = "pm" },
> { pci_reset_bus_function, .name = "bus" },
> { cxl_reset_bus_function, .name = "cxl_bus" },
> + { pci_d3cold_reset, .name = "d3cold" },
> };
>
> /**
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 2c4454583c11..1ca7b880ead7 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -51,7 +51,7 @@
> PCI_STATUS_PARITY)
>
> /* Number of reset methods used in pci_reset_fn_methods array in pci.c */
> -#define PCI_NUM_RESET_METHODS 8
> +#define PCI_NUM_RESET_METHODS 9
>
> #define PCI_RESET_PROBE true
> #define PCI_RESET_DO_RESET false
> --
> 2.54.0
>
next prev parent reply other threads:[~2026-06-10 18:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 10:58 [PATCH v7 0/3] PCI: Add d3cold and device-specific reset for Qualcomm devices Jose Ignacio Tornos Martinez
2026-06-03 10:58 ` [PATCH v7 1/3] PCI: Add d3cold as general reset method Jose Ignacio Tornos Martinez
2026-06-03 11:20 ` sashiko-bot
2026-06-10 19:19 ` Bjorn Helgaas
2026-06-10 20:04 ` Rafael J. Wysocki
2026-06-11 7:38 ` Jose Ignacio Tornos Martinez
2026-06-10 18:42 ` Bjorn Helgaas [this message]
2026-06-03 10:58 ` [PATCH v6 2/3] PCI: Add device-specific reset for Qualcomm devices Jose Ignacio Tornos Martinez
2026-06-03 11:39 ` sashiko-bot
2026-06-03 10:58 ` [PATCH v7 3/3] PCI: Disable broken bus reset on " Jose Ignacio Tornos Martinez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260610184236.GA236984@bhelgaas \
--to=helgaas@kernel.org \
--cc=alex@shazbot.org \
--cc=ath11k@lists.infradead.org \
--cc=ath12k@lists.infradead.org \
--cc=bhelgaas@google.com \
--cc=jjohnson@kernel.org \
--cc=jtornosm@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=mani@kernel.org \
--cc=mhi@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.