diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-01-25 16:03:40 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-01-25 16:03:40 -0800 |
commit | 647d69605c70368d54fc012fce8a43e8e5955b04 (patch) | |
tree | 1c3818d738528c0c532e8db0e1badeeec0112c96 /drivers/pci/pci.c | |
parent | 184a0997fb77f4a9527fc867fcd16806776c27ce (diff) | |
parent | 10ff5bbfd4b020e58fd8863e44ae59f0d4c337bf (diff) |
Merge tag 'pci-v6.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci updates from Bjorn Helgaas:
"Enumeration:
- Batch sizing of multiple BARs while memory decoding is disabled
instead of disabling/enabling decoding for each BAR individually;
this optimizes virtualized environments where toggling decoding
enable is expensive (Alex Williamson)
- Add host bridge .enable_device() and .disable_device() hooks for
bridges that need to configure things like Requester ID to StreamID
mapping when enabling devices (Frank Li)
- Extend struct pci_ecam_ops with .enable_device() and
.disable_device() hooks so drivers that use pci_host_common_probe()
instead of their own .probe() have a way to set the
.enable_device() callbacks (Marc Zyngier)
- Drop 'No bus range found' message so we don't complain when DTs
don't specify the default 'bus-range = <0x00 0xff>' (Bjorn Helgaas)
- Rename the drivers/pci/of_property.c struct of_pci_range to
of_pci_range_entry to avoid confusion with the global of_pci_range
in include/linux/of_address.h (Bjorn Helgaas)
Driver binding:
- Update resource request API documentation to encourage callers to
supply a driver name when requesting resources (Philipp Stanner)
- Export pci_intx_unmanaged() and pcim_intx() (always managed) so
callers of pci_intx() (which is sometimes managed) can explicitly
choose the one they need (Philipp Stanner)
- Convert drivers from pci_intx() to always-managed pcim_intx() or
never-managed pci_intx_unmanaged(): amd_sfh, ata (ahci, ata_piix,
pata_rdc, sata_sil24, sata_sis, sata_uli, sata_vsc), bnx2x, bna,
ntb, qtnfmac, rtsx, tifm_7xx1, vfio, xen-pciback (Philipp Stanner)
- Remove pci_intx_unmanaged() since pci_intx() is now always
unmanaged and pcim_intx() is always managed (Philipp Stanner)
Error handling:
- Unexport pcie_read_tlp_log() to encourage drivers to use PCI core
logging rather than building their own (Ilpo Järvinen)
- Move TLP Log handling to its own file (Ilpo Järvinen)
- Store number of supported End-End TLP Prefixes always so we can
read the correct number of DWORDs from the TLP Prefix Log (Ilpo
Järvinen)
- Read TLP Prefixes in addition to the Header Log in
pcie_read_tlp_log() (Ilpo Järvinen)
- Add pcie_print_tlp_log() to consolidate printing of TLP Header and
Prefix Log (Ilpo Järvinen)
- Quirk the Intel Raptor Lake-P PIO log size to accommodate vendor
BIOSes that don't configure it correctly (Takashi Iwai)
ASPM:
- Save parent L1 PM Substates config so when we restore it along with
an endpoint's config, the parent info isn't junk (Jian-Hong Pan)
Power management:
- Avoid D3 for Root Ports on TUXEDO Sirius Gen1 with old BIOS because
the system can't wake up from suspend (Werner Sembach)
Endpoint framework:
- Destroy the EPC device in devm_pci_epc_destroy(), which previously
didn't call devres_release() (Zijun Hu)
- Finish virtual EP removal in pci_epf_remove_vepf(), which
previously caused a subsequent pci_epf_add_vepf() to fail with
-EBUSY (Zijun Hu)
- Write BAR_MASK before iATU registers in pci_epc_set_bar() so we
don't depend on the BAR_MASK reset value being larger than the
requested BAR size (Niklas Cassel)
- Prevent changing BAR size/flags in pci_epc_set_bar() to prevent
reads from bypassing the iATU if we reduced the BAR size (Niklas
Cassel)
- Verify address alignment when programming iATU so we don't attempt
to write bits that are read-only because of the BAR size, which
could lead to directing accesses to the wrong address (Niklas
Cassel)
- Implement artpec6 pci_epc_features so we can rely on all drivers
supporting it so we can use it in EPC core code (Niklas Cassel)
- Check for BARs of fixed size to prevent endpoint drivers from
trying to change their size (Niklas Cassel)
- Verify that requested BAR size is a power of two when endpoint
driver sets the BAR (Niklas Cassel)
Endpoint framework tests:
- Clear pci-epf-test dma_chan_rx, not dma_chan_tx, after freeing
dma_chan_rx (Mohamed Khalfella)
- Correct the DMA MEMCPY test so it doesn't fail if the Endpoint
supports both DMA_PRIVATE and DMA_MEMCPY (Manivannan Sadhasivam)
- Add pci-epf-test and pci_endpoint_test support for capabilities
(Niklas Cassel)
- Add Endpoint test for consecutive BARs (Niklas Cassel)
- Remove redundant comparison from Endpoint BAR test because a > 1MB
BAR can always be exactly covered by iterating with a 1MB buffer
(Hans Zhang)
- Move and convert PCI Endpoint tests from tools/pci to Kselftests
(Manivannan Sadhasivam)
Apple PCIe controller driver:
- Convert StreamID mapping configuration from a bus notifier to the
.enable_device() and .disable_device() callbacks (Marc Zyngier)
Freescale i.MX6 PCIe controller driver:
- Add Requester ID to StreamID mapping configuration when enabling
devices (Frank Li)
- Use DWC core suspend/resume functions for imx6 (Frank Li)
- Add suspend/resume support for i.MX8MQ, i.MX8Q, and i.MX95 (Richard
Zhu)
- Add DT compatible string 'fsl,imx8q-pcie-ep' and driver support for
i.MX8Q series (i.MX8QM, i.MX8QXP, and i.MX8DXL) Endpoints (Frank
Li)
- Add DT binding for optional i.MX95 Refclk and driver support to
enable it if the platform hasn't enabled it (Richard Zhu)
- Configure PHY based on controller being in Root Complex or Endpoint
mode (Frank Li)
- Rely on dbi2 and iATU base addresses from DT via
dw_pcie_get_resources() instead of hardcoding them (Richard Zhu)
- Deassert apps_reset in imx_pcie_deassert_core_reset() since it is
asserted in imx_pcie_assert_core_reset() (Richard Zhu)
- Add missing reference clock enable or disable logic for IMX6SX,
IMX7D, IMX8MM (Richard Zhu)
- Remove redundant imx7d_pcie_init_phy() since
imx7d_pcie_enable_ref_clk() does the same thing (Richard Zhu)
Freescale Layerscape PCIe controller driver:
- Simplify by using syscon_regmap_lookup_by_phandle_args() instead
of syscon_regmap_lookup_by_phandle() followed by
of_property_read_u32_array() (Krzysztof Kozlowski)
Marvell MVEBU PCIe controller driver:
- Add MODULE_DEVICE_TABLE() to enable module autoloading (Liao Chen)
MediaTek PCIe Gen3 controller driver:
- Use clk_bulk_prepare_enable() instead of separate
clk_bulk_prepare() and clk_bulk_enable() (Lorenzo Bianconi)
- Rearrange reset assert/deassert so they're both done in the
*_power_up() callbacks (Lorenzo Bianconi)
- Document that Airoha EN7581 requires PHY init and power-on before
PHY reset deassert, unlike other MediaTek Gen3 controllers (Lorenzo
Bianconi)
- Move Airoha EN7581 post-reset delay from the en7581 clock .enable()
method to mtk_pcie_en7581_power_up() (Lorenzo Bianconi)
- Sleep instead of delay during Airoha EN7581 power-up, since this is
a non-atomic context (Lorenzo Bianconi)
- Skip PERST# assertion on Airoha EN7581 during probe and
suspend/resume to avoid a hardware defect (Lorenzo Bianconi)
- Enable async probe to reduce system startup time (Douglas Anderson)
Microchip PolarFlare PCIe controller driver:
- Set up the inbound address translation based on whether the
platform allows coherent or non-coherent DMA (Daire McNamara)
- Update DT binding such that platforms are DMA-coherent by default
and must specify 'dma-noncoherent' if needed (Conor Dooley)
Mobiveil PCIe controller driver:
- Convert mobiveil-pcie.txt to YAML and update 'interrupt-names'
and 'reg-names' (Frank Li)
Qualcomm PCIe controller driver:
- Add DT SM8550 and SM8650 optional 'global' interrupt for link
events (Neil Armstrong)
- Add DT 'compatible' strings for IPQ5424 PCIe controller (Manikanta
Mylavarapu)
- If 'global' IRQ is supported for detection of Link Up events, tell
DWC core not to wait for link up (Krishna chaitanya chundru)
Renesas R-Car PCIe controller driver:
- Avoid passing stack buffer as resource name (King Dix)
Rockchip PCIe controller driver:
- Simplify clock and reset handling by using bulk interfaces (Anand
Moon)
- Pass typed rockchip_pcie (not void) pointer to
rockchip_pcie_disable_clocks() (Anand Moon)
- Return -ENOMEM, not success, when pci_epc_mem_alloc_addr() fails
(Dan Carpenter)
Rockchip DesignWare PCIe controller driver:
- Use dll_link_up IRQ to detect Link Up and enumerate devices so
users don't have to manually rescan (Niklas Cassel)
- Tell DWC core not to wait for link up since the 'sys' interrupt is
required and detects Link Up events (Niklas Cassel)
Synopsys DesignWare PCIe controller driver:
- Don't wait for link up in DWC core if driver can detect Link Up
event (Krishna chaitanya chundru)
- Update ICC and OPP votes after Link Up events (Krishna chaitanya
chundru)
- Always stop link in dw_pcie_suspend_noirq(), which is required at
least for i.MX8QM to re-establish link on resume (Richard Zhu)
- Drop racy and unnecessary LTSSM state check before sending
PME_TURN_OFF message in dw_pcie_suspend_noirq() (Richard Zhu)
- Add struct of_pci_range.parent_bus_addr for devices that need their
immediate parent bus address, not the CPU address, e.g., to program
an internal Address Translation Unit (iATU) (Frank Li)
TI DRA7xx PCIe controller driver:
- Simplify by using syscon_regmap_lookup_by_phandle_args() instead of
syscon_regmap_lookup_by_phandle() followed by
of_parse_phandle_with_fixed_args() or of_property_read_u32_index()
(Krzysztof Kozlowski)
Xilinx Versal CPM PCIe controller driver:
- Add DT binding and driver support for Xilinx Versal CPM5
(Thippeswamy Havalige)
MicroSemi Switchtec management driver:
- Add Microchip PCI100X device IDs (Rakesh Babu Saladi)
Miscellaneous:
- Move reset related sysfs code from pci.c to pci-sysfs.c where other
similar code lives (Ilpo Järvinen)
- Simplify reset_method_store() memory management by using __free()
instead of explicit kfree() cleanup (Ilpo Järvinen)
- Constify struct bin_attribute for sysfs, VPD, P2PDMA, and the IBM
ACPI hotplug driver (Thomas Weißschuh)
- Remove redundant PCI_VSEC_HDR and PCI_VSEC_HDR_LEN_SHIFT (Dongdong
Zhang)
- Correct documentation of the 'config_acs=' kernel parameter
(Akihiko Odaki)"
* tag 'pci-v6.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (111 commits)
PCI: Batch BAR sizing operations
dt-bindings: PCI: microchip,pcie-host: Allow dma-noncoherent
PCI: microchip: Set inbound address translation for coherent or non-coherent mode
Documentation: Fix pci=config_acs= example
PCI: Remove redundant PCI_VSEC_HDR and PCI_VSEC_HDR_LEN_SHIFT
PCI: Don't include 'pm_wakeup.h' directly
selftests: pci_endpoint: Migrate to Kselftest framework
selftests: Move PCI Endpoint tests from tools/pci to Kselftests
misc: pci_endpoint_test: Fix IOCTL return value
dt-bindings: PCI: qcom: Document the IPQ5424 PCIe controller
dt-bindings: PCI: qcom,pcie-sm8550: Document 'global' interrupt
dt-bindings: PCI: mobiveil: Convert mobiveil-pcie.txt to YAML
PCI: switchtec: Add Microchip PCI100X device IDs
misc: pci_endpoint_test: Remove redundant 'remainder' test
misc: pci_endpoint_test: Add consecutive BAR test
misc: pci_endpoint_test: Add support for capabilities
PCI: endpoint: pci-epf-test: Add support for capabilities
PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test
PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error
PCI: dwc: Simplify config resource lookup
...
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 275 |
1 files changed, 72 insertions, 203 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 661f98c6c63a..869d204a70a3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -23,7 +23,6 @@ #include <linux/string.h> #include <linux/log2.h> #include <linux/logic_pio.h> -#include <linux/pm_wakeup.h> #include <linux/device.h> #include <linux/pm_runtime.h> #include <linux/pci_hotplug.h> @@ -1100,34 +1099,6 @@ static void pci_enable_acs(struct pci_dev *dev) } /** - * pcie_read_tlp_log - read TLP Header Log - * @dev: PCIe device - * @where: PCI Config offset of TLP Header Log - * @tlp_log: TLP Log structure to fill - * - * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC. - * - * Return: 0 on success and filled TLP Log structure, <0 on error. - */ -int pcie_read_tlp_log(struct pci_dev *dev, int where, - struct pcie_tlp_log *tlp_log) -{ - int i, ret; - - memset(tlp_log, 0, sizeof(*tlp_log)); - - for (i = 0; i < 4; i++) { - ret = pci_read_config_dword(dev, where + i * 4, - &tlp_log->dw[i]); - if (ret) - return pcibios_err_to_errno(ret); - } - - return 0; -} -EXPORT_SYMBOL_GPL(pcie_read_tlp_log); - -/** * pci_restore_bars - restore a device's BAR values (e.g. after wake-up) * @dev: PCI device to have its BARs restored * @@ -2059,6 +2030,28 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars) return pci_enable_resources(dev, bars); } +static int pci_host_bridge_enable_device(struct pci_dev *dev) +{ + struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus); + int err; + + if (host_bridge && host_bridge->enable_device) { + err = host_bridge->enable_device(host_bridge, dev); + if (err) + return err; + } + + return 0; +} + +static void pci_host_bridge_disable_device(struct pci_dev *dev) +{ + struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus); + + if (host_bridge && host_bridge->disable_device) + host_bridge->disable_device(host_bridge, dev); +} + static int do_pci_enable_device(struct pci_dev *dev, int bars) { int err; @@ -2074,9 +2067,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) if (bridge) pcie_aspm_powersave_config_link(bridge); + err = pci_host_bridge_enable_device(dev); + if (err) + return err; + err = pcibios_enable_device(dev, bars); if (err < 0) - return err; + goto err_enable; pci_fixup_device(pci_fixup_enable, dev); if (dev->msi_enabled || dev->msix_enabled) @@ -2091,6 +2088,12 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) } return 0; + +err_enable: + pci_host_bridge_disable_device(dev); + + return err; + } /** @@ -2274,6 +2277,8 @@ void pci_disable_device(struct pci_dev *dev) if (atomic_dec_return(&dev->enable_cnt) != 0) return; + pci_host_bridge_disable_device(dev); + do_pci_disable_device(dev); dev->is_busmaster = 0; @@ -3941,15 +3946,14 @@ EXPORT_SYMBOL(pci_release_region); * __pci_request_region - Reserved PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved - * @res_name: Name to be associated with resource. + * @name: name of the driver requesting the resource * @exclusive: whether the region access is exclusive or not * * Returns: 0 on success, negative error code on failure. * - * Mark the PCI region associated with PCI device @pdev BAR @bar as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark the PCI region associated with PCI device @pdev BAR @bar as being + * reserved by owner @name. Do not access any address inside the PCI regions + * unless this call returns successfully. * * If @exclusive is set, then the region is marked so that userspace * is explicitly not allowed to map the resource via /dev/mem or @@ -3959,13 +3963,13 @@ EXPORT_SYMBOL(pci_release_region); * message is also printed on failure. */ static int __pci_request_region(struct pci_dev *pdev, int bar, - const char *res_name, int exclusive) + const char *name, int exclusive) { if (pci_is_managed(pdev)) { if (exclusive == IORESOURCE_EXCLUSIVE) - return pcim_request_region_exclusive(pdev, bar, res_name); + return pcim_request_region_exclusive(pdev, bar, name); - return pcim_request_region(pdev, bar, res_name); + return pcim_request_region(pdev, bar, name); } if (pci_resource_len(pdev, bar) == 0) @@ -3973,11 +3977,11 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) { if (!request_region(pci_resource_start(pdev, bar), - pci_resource_len(pdev, bar), res_name)) + pci_resource_len(pdev, bar), name)) goto err_out; } else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { if (!__request_mem_region(pci_resource_start(pdev, bar), - pci_resource_len(pdev, bar), res_name, + pci_resource_len(pdev, bar), name, exclusive)) goto err_out; } @@ -3994,14 +3998,13 @@ err_out: * pci_request_region - Reserve PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved - * @res_name: Name to be associated with resource + * @name: name of the driver requesting the resource * * Returns: 0 on success, negative error code on failure. * - * Mark the PCI region associated with PCI device @pdev BAR @bar as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark the PCI region associated with PCI device @pdev BAR @bar as being + * reserved by owner @name. Do not access any address inside the PCI regions + * unless this call returns successfully. * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. @@ -4011,9 +4014,9 @@ err_out: * when pcim_enable_device() has been called in advance. This hybrid feature is * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ -int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) +int pci_request_region(struct pci_dev *pdev, int bar, const char *name) { - return __pci_request_region(pdev, bar, res_name, 0); + return __pci_request_region(pdev, bar, name, 0); } EXPORT_SYMBOL(pci_request_region); @@ -4036,13 +4039,13 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) EXPORT_SYMBOL(pci_release_selected_regions); static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, - const char *res_name, int excl) + const char *name, int excl) { int i; for (i = 0; i < PCI_STD_NUM_BARS; i++) if (bars & (1 << i)) - if (__pci_request_region(pdev, i, res_name, excl)) + if (__pci_request_region(pdev, i, name, excl)) goto err_out; return 0; @@ -4059,7 +4062,7 @@ err_out: * pci_request_selected_regions - Reserve selected PCI I/O and memory resources * @pdev: PCI device whose resources are to be reserved * @bars: Bitmask of BARs to be requested - * @res_name: Name to be associated with resource + * @name: Name of the driver requesting the resources * * Returns: 0 on success, negative error code on failure. * @@ -4069,9 +4072,9 @@ err_out: * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ int pci_request_selected_regions(struct pci_dev *pdev, int bars, - const char *res_name) + const char *name) { - return __pci_request_selected_regions(pdev, bars, res_name, 0); + return __pci_request_selected_regions(pdev, bars, name, 0); } EXPORT_SYMBOL(pci_request_selected_regions); @@ -4079,7 +4082,7 @@ EXPORT_SYMBOL(pci_request_selected_regions); * pci_request_selected_regions_exclusive - Request regions exclusively * @pdev: PCI device to request regions from * @bars: bit mask of BARs to request - * @res_name: name to be associated with the requests + * @name: name of the driver requesting the resources * * Returns: 0 on success, negative error code on failure. * @@ -4089,9 +4092,9 @@ EXPORT_SYMBOL(pci_request_selected_regions); * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ int pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars, - const char *res_name) + const char *name) { - return __pci_request_selected_regions(pdev, bars, res_name, + return __pci_request_selected_regions(pdev, bars, name, IORESOURCE_EXCLUSIVE); } EXPORT_SYMBOL(pci_request_selected_regions_exclusive); @@ -4114,12 +4117,11 @@ EXPORT_SYMBOL(pci_release_regions); /** * pci_request_regions - Reserve PCI I/O and memory resources * @pdev: PCI device whose resources are to be reserved - * @res_name: Name to be associated with resource. + * @name: name of the driver requesting the resources * - * Mark all PCI regions associated with PCI device @pdev as - * being reserved by owner @res_name. Do not access any - * address inside the PCI regions unless this call returns - * successfully. + * Mark all PCI regions associated with PCI device @pdev as being reserved by + * owner @name. Do not access any address inside the PCI regions unless this + * call returns successfully. * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. @@ -4129,22 +4131,22 @@ EXPORT_SYMBOL(pci_release_regions); * when pcim_enable_device() has been called in advance. This hybrid feature is * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ -int pci_request_regions(struct pci_dev *pdev, const char *res_name) +int pci_request_regions(struct pci_dev *pdev, const char *name) { return pci_request_selected_regions(pdev, - ((1 << PCI_STD_NUM_BARS) - 1), res_name); + ((1 << PCI_STD_NUM_BARS) - 1), name); } EXPORT_SYMBOL(pci_request_regions); /** * pci_request_regions_exclusive - Reserve PCI I/O and memory resources * @pdev: PCI device whose resources are to be reserved - * @res_name: Name to be associated with resource. + * @name: name of the driver requesting the resources * * Returns: 0 on success, negative error code on failure. * * Mark all PCI regions associated with PCI device @pdev as being reserved - * by owner @res_name. Do not access any address inside the PCI regions + * by owner @name. Do not access any address inside the PCI regions * unless this call returns successfully. * * pci_request_regions_exclusive() will mark the region so that /dev/mem @@ -4158,10 +4160,10 @@ EXPORT_SYMBOL(pci_request_regions); * when pcim_enable_device() has been called in advance. This hybrid feature is * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ -int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) +int pci_request_regions_exclusive(struct pci_dev *pdev, const char *name) { return pci_request_selected_regions_exclusive(pdev, - ((1 << PCI_STD_NUM_BARS) - 1), res_name); + ((1 << PCI_STD_NUM_BARS) - 1), name); } EXPORT_SYMBOL(pci_request_regions_exclusive); @@ -4488,11 +4490,6 @@ void pci_disable_parity(struct pci_dev *dev) * @enable: boolean: whether to enable or disable PCI INTx * * Enables/disables PCI INTx for device @pdev - * - * NOTE: - * This is a "hybrid" function: It's normally unmanaged, but becomes managed - * when pcim_enable_device() has been called in advance. This hybrid feature is - * DEPRECATED! If you want managed cleanup, use pcim_intx() instead. */ void pci_intx(struct pci_dev *pdev, int enable) { @@ -4505,15 +4502,10 @@ void pci_intx(struct pci_dev *pdev, int enable) else new = pci_command | PCI_COMMAND_INTX_DISABLE; - if (new != pci_command) { - /* Preserve the "hybrid" behavior for backwards compatibility */ - if (pci_is_managed(pdev)) { - WARN_ON_ONCE(pcim_intx(pdev, enable) != 0); - return; - } + if (new == pci_command) + return; - pci_write_config_word(pdev, PCI_COMMAND, new); - } + pci_write_config_word(pdev, PCI_COMMAND, new); } EXPORT_SYMBOL_GPL(pci_intx); @@ -5204,7 +5196,7 @@ static void pci_dev_restore(struct pci_dev *dev) } /* dev->reset_methods[] is a 0-terminated list of indices into this array */ -static const struct pci_reset_fn_method pci_reset_fn_methods[] = { +const struct pci_reset_fn_method pci_reset_fn_methods[] = { { }, { pci_dev_specific_reset, .name = "device_specific" }, { pci_dev_acpi_reset, .name = "acpi" }, @@ -5215,129 +5207,6 @@ static const struct pci_reset_fn_method pci_reset_fn_methods[] = { { cxl_reset_bus_function, .name = "cxl_bus" }, }; -static ssize_t reset_method_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - ssize_t len = 0; - int i, m; - - for (i = 0; i < PCI_NUM_RESET_METHODS; i++) { - m = pdev->reset_methods[i]; - if (!m) - break; - - len += sysfs_emit_at(buf, len, "%s%s", len ? " " : "", - pci_reset_fn_methods[m].name); - } - - if (len) - len += sysfs_emit_at(buf, len, "\n"); - - return len; -} - -static int reset_method_lookup(const char *name) -{ - int m; - - for (m = 1; m < PCI_NUM_RESET_METHODS; m++) { - if (sysfs_streq(name, pci_reset_fn_methods[m].name)) - return m; - } - - return 0; /* not found */ -} - -static ssize_t reset_method_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - char *options, *tmp_options, *name; - int m, n; - u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 }; - - if (sysfs_streq(buf, "")) { - pdev->reset_methods[0] = 0; - pci_warn(pdev, "All device reset methods disabled by user"); - return count; - } - - if (sysfs_streq(buf, "default")) { - pci_init_reset_methods(pdev); - return count; - } - - options = kstrndup(buf, count, GFP_KERNEL); - if (!options) - return -ENOMEM; - - n = 0; - tmp_options = options; - while ((name = strsep(&tmp_options, " ")) != NULL) { - if (sysfs_streq(name, "")) - continue; - - name = strim(name); - - m = reset_method_lookup(name); - if (!m) { - pci_err(pdev, "Invalid reset method '%s'", name); - goto error; - } - - if (pci_reset_fn_methods[m].reset_fn(pdev, PCI_RESET_PROBE)) { - pci_err(pdev, "Unsupported reset method '%s'", name); - goto error; - } - - if (n == PCI_NUM_RESET_METHODS - 1) { - pci_err(pdev, "Too many reset methods\n"); - goto error; - } - - reset_methods[n++] = m; - } - - reset_methods[n] = 0; - - /* Warn if dev-specific supported but not highest priority */ - if (pci_reset_fn_methods[1].reset_fn(pdev, PCI_RESET_PROBE) == 0 && - reset_methods[0] != 1) - pci_warn(pdev, "Device-specific reset disabled/de-prioritized by user"); - memcpy(pdev->reset_methods, reset_methods, sizeof(pdev->reset_methods)); - kfree(options); - return count; - -error: - /* Leave previous methods unchanged */ - kfree(options); - return -EINVAL; -} -static DEVICE_ATTR_RW(reset_method); - -static struct attribute *pci_dev_reset_method_attrs[] = { - &dev_attr_reset_method.attr, - NULL, -}; - -static umode_t pci_dev_reset_method_attr_is_visible(struct kobject *kobj, - struct attribute *a, int n) -{ - struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); - - if (!pci_reset_supported(pdev)) - return 0; - - return a->mode; -} - -const struct attribute_group pci_dev_reset_method_attr_group = { - .attrs = pci_dev_reset_method_attrs, - .is_visible = pci_dev_reset_method_attr_is_visible, -}; - /** * __pci_reset_function_locked - reset a PCI device function while holding * the @dev mutex lock. |