lkml.org 
[lkml]   [2021]   [Jul]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v12 7/8] PCI: Add support for ACPI _RST reset method
    Date
    The _RST is a standard method specified in the ACPI specification. It
    provides a function level reset when it is described in the acpi_device
    context associated with PCI-device. Implement a new reset function
    pci_dev_acpi_reset() for probing RST method and execute if it is defined
    in the firmware.

    The default priority of the ACPI reset is set to below device-specific
    and above hardware resets.

    Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
    Suggested-by: Alex Williamson <alex.williamson@redhat.com>
    Reviewed-by: Sinan Kaya <okaya@kernel.org>
    Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
    ---
    drivers/pci/pci-acpi.c | 23 +++++++++++++++++++++++
    drivers/pci/pci.c | 1 +
    drivers/pci/pci.h | 6 ++++++
    include/linux/pci.h | 2 +-
    4 files changed, 31 insertions(+), 1 deletion(-)

    diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
    index dae021322b3fc..31f76746741f5 100644
    --- a/drivers/pci/pci-acpi.c
    +++ b/drivers/pci/pci-acpi.c
    @@ -941,6 +941,29 @@ void pci_set_acpi_fwnode(struct pci_dev *dev)
    acpi_pci_find_companion(&dev->dev));
    }

    +/**
    + * pci_dev_acpi_reset - do a function level reset using _RST method
    + * @dev: device to reset
    + * @probe: check if _RST method is included in the acpi_device context.
    + */
    +int pci_dev_acpi_reset(struct pci_dev *dev, int probe)
    +{
    + acpi_handle handle = ACPI_HANDLE(&dev->dev);
    +
    + if (!handle || !acpi_has_method(handle, "_RST"))
    + return -ENOTTY;
    +
    + if (probe)
    + return 0;
    +
    + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, NULL))) {
    + pci_warn(dev, "ACPI _RST failed\n");
    + return -ENOTTY;
    + }
    +
    + return 0;
    +}
    +
    static bool acpi_pci_bridge_d3(struct pci_dev *dev)
    {
    const struct fwnode_handle *fwnode;
    diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
    index cc9f96effa546..8aab4097f80bc 100644
    --- a/drivers/pci/pci.c
    +++ b/drivers/pci/pci.c
    @@ -5127,6 +5127,7 @@ static void pci_dev_restore(struct pci_dev *dev)
    const struct pci_reset_fn_method pci_reset_fn_methods[] = {
    { },
    { &pci_dev_specific_reset, .name = "device_specific" },
    + { &pci_dev_acpi_reset, .name = "acpi" },
    { &pcie_reset_flr, .name = "flr" },
    { &pci_af_flr, .name = "af_flr" },
    { &pci_pm_reset, .name = "pm" },
    diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
    index 37381734fcc78..699d14243867a 100644
    --- a/drivers/pci/pci.h
    +++ b/drivers/pci/pci.h
    @@ -709,7 +709,13 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL
    int pci_acpi_program_hp_params(struct pci_dev *dev);
    extern const struct attribute_group pci_dev_acpi_attr_group;
    void pci_set_acpi_fwnode(struct pci_dev *dev);
    +int pci_dev_acpi_reset(struct pci_dev *dev, int probe);
    #else
    +static inline int pci_dev_acpi_reset(struct pci_dev *dev, int probe)
    +{
    + return -ENOTTY;
    +}
    +
    static inline void pci_set_acpi_fwnode(struct pci_dev *dev) {}
    static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
    {
    diff --git a/include/linux/pci.h b/include/linux/pci.h
    index 58cc2e2b05051..698a668828f66 100644
    --- a/include/linux/pci.h
    +++ b/include/linux/pci.h
    @@ -50,7 +50,7 @@
    PCI_STATUS_PARITY)

    /* Number of reset methods used in pci_reset_fn_methods array in pci.c */
    -#define PCI_NUM_RESET_METHODS 6
    +#define PCI_NUM_RESET_METHODS 7

    /*
    * The PCI interface treats multi-function devices as independent
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-07-16 17:25    [W:5.304 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site