From 77c5f3def45937f3f90ea4018cfdf9342b78b78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:21 +0000 Subject: PCI: Add pci_resource_is_io() and pci_resource_is_mem() helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to check whether a PCI resource is of I/O port or memory type. These replace the open-coded pci_resource_flags() with IORESOURCE_IO and IORESOURCE_MEM pattern used across the tree. Suggested-by: Ilpo Järvinen Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Reviewed-by: Ilpo Järvinen Link: https://patch.msgid.link/20260508043543.217179-3-kwilczynski@kernel.org --- include/linux/pci.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 2c4454583c11..e93fbe6b57fe 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2300,6 +2300,31 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma); CONCATENATE(__pci_dev_for_each_res, COUNT_ARGS(__VA_ARGS__)) \ (dev, res, __VA_ARGS__) +/** + * pci_resource_is_io - check if a PCI resource is of I/O port type. + * @dev: PCI device to check. + * @resno: The resource number (BAR index) to check. + * + * Returns true if the resource type is I/O port. + */ +static inline bool pci_resource_is_io(const struct pci_dev *dev, int resno) +{ + return resource_type(pci_resource_n(dev, resno)) == IORESOURCE_IO; +} + +/** + * pci_resource_is_mem - check if a PCI resource is of memory type. + * @dev: PCI device to check. + * @resno: The resource number (BAR index) to check. + * + * Returns true if the resource type is memory, including + * prefetchable memory. + */ +static inline bool pci_resource_is_mem(const struct pci_dev *dev, int resno) +{ + return resource_type(pci_resource_n(dev, resno)) == IORESOURCE_MEM; +} + /* * Similar to the helpers above, these manipulate per-pci_dev * driver-specific data. They are really just a wrapper around -- cgit v1.2.3 From ca617c60af9f6bb74216645ce4362dcb96697d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:26 +0000 Subject: PCI/sysfs: Convert PCI resource files to static attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the PCI resource files (resourceN, resourceN_wc) are dynamically created by pci_create_sysfs_dev_files(), called from both pci_bus_add_device() and the pci_sysfs_init() late_initcall, with only a sysfs_initialized flag for synchronisation. This has caused warnings and boot panics when both paths race on the same device, e.g.: sysfs: cannot create duplicate filename '/devices/pci0000:3c/0000:3c:01.0/0000:3e:00.2/resource2' This is especially likely on Devicetree-based platforms, where the PCI host controllers are platform drivers that probe via the driver model, which can happen during or after the late_initcall. As such, pci_bus_add_device() and pci_sysfs_init() are more likely to overlap. Convert to static const attributes with three attribute groups (I/O, UC, WC), each with an .is_bin_visible() callback that checks resource flags, BAR length, and non_mappable_bars. A .bin_size() callback provides pci_resource_len() to the kernfs node for correct stat and lseek behaviour. As part of this conversion: - Rename pci_read_resource_io() and pci_write_resource_io() to pci_read_resource() and pci_write_resource() since the callbacks are no longer I/O-specific in the static attribute context. - Update __resource_resize_store() to use sysfs_create_groups() and sysfs_remove_groups(), which re-evaluates visibility and runs the .bin_size() callback for the static resource attribute groups. - Remove pci_create_resource_files(), pci_remove_resource_files(), and pci_create_attr() which are no longer needed. - Move the __weak stubs outside the #if guard so they remain available for callers converted in subsequent commits. Platforms that do not define the HAVE_PCI_MMAP macro or the ARCH_GENERIC_PCI_MMAP_RESOURCE macro, such as Alpha architecture, continue using their platform-specific resource file creation. For reference, the dynamic creation dates back to the pre-Git era: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/drivers/pci/pci-sysfs.c?id=42298be0eeb5ae98453b3374c36161b05a46c5dc The write-combine support was added in commit 45aec1ae72fc ("x86: PAT export resource_wc in pci sysfs"). Many other reports mentioned in the cover letter (first Link: below). Link: https://lore.kernel.org/r/20260508043543.217179-1-kwilczynski@kernel.org/ Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215515 Closes: https://github.com/openwrt/openwrt/issues/17143 Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Link: https://patch.msgid.link/20260508043543.217179-8-kwilczynski@kernel.org --- include/linux/pci.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e93fbe6b57fe..974605c9fce2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2531,10 +2531,8 @@ int pcibios_alloc_irq(struct pci_dev *dev); void pcibios_free_irq(struct pci_dev *dev); resource_size_t pcibios_default_alignment(void); -#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE) extern int pci_create_resource_files(struct pci_dev *dev); extern void pci_remove_resource_files(struct pci_dev *dev); -#endif #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) void __init pci_mmcfg_early_init(void); -- cgit v1.2.3 From 2c31a9675f50a61c9ceed6dab2545be7aa896d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:28 +0000 Subject: PCI/sysfs: Add stubs for pci_{create,remove}_sysfs_dev_files() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On platforms with HAVE_PCI_MMAP or ARCH_GENERIC_PCI_MMAP_RESOURCE, resource files are now handled by static attribute groups registered via pci_dev_groups[]. Stub out the pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files(), as the dynamic resource file creation is no longer needed. Also, simplify pci_sysfs_init() on these platforms to only iterate buses for legacy attributes creation, skipping the per-device loop. Move the __weak stubs for pci_create_resource_files() and pci_remove_resource_files() into the #else branch since only platforms without HAVE_PCI_MMAP (such as Alpha architecture) still need them. Guard the res_attr[] and res_attr_wc[] fields in struct pci_dev the same way. Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Link: https://patch.msgid.link/20260508043543.217179-10-kwilczynski@kernel.org --- include/linux/pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 974605c9fce2..b998a56f6010 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -515,8 +515,10 @@ struct pci_dev { spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */ u32 saved_config_space[16]; /* Config space saved at suspend time */ struct hlist_head saved_cap_space; +#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE) struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ +#endif #ifdef CONFIG_HOTPLUG_PCI_PCIE unsigned int broken_cmd_compl:1; /* No compl for some cmds */ @@ -2531,8 +2533,10 @@ int pcibios_alloc_irq(struct pci_dev *dev); void pcibios_free_irq(struct pci_dev *dev); resource_size_t pcibios_default_alignment(void); +#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE) extern int pci_create_resource_files(struct pci_dev *dev); extern void pci_remove_resource_files(struct pci_dev *dev); +#endif #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) void __init pci_mmcfg_early_init(void); -- cgit v1.2.3 From b45bebbfa0be8b1c8be5d3c5946f8f04d556fdf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:37 +0000 Subject: PCI/sysfs: Remove pci_{create,remove}_sysfs_dev_files() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files() are no-op stubs. With both the generic and Alpha resource files now handled by static attribute groups, no platform needs dynamic per-device sysfs file creation. Remove both functions, their declarations, and the call sites in pci_bus_add_device() and pci_stop_dev(). Remove __weak pci_create_resource_files() and pci_remove_resource_files() stubs and their declarations in pci.h, as no architecture overrides them anymore. Remove the res_attr[] and res_attr_wc[] fields from struct pci_dev which were used to track dynamically allocated resource attributes. Finally, simplify pci_sysfs_init() to only handle legacy file creation under HAVE_PCI_LEGACY, removing the per-device loop and the HAVE_PCI_SYSFS_INIT helper added earlier. Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Link: https://patch.msgid.link/20260508043543.217179-19-kwilczynski@kernel.org --- include/linux/pci.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index b998a56f6010..c56f2cf0d2ab 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -515,10 +515,6 @@ struct pci_dev { spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */ u32 saved_config_space[16]; /* Config space saved at suspend time */ struct hlist_head saved_cap_space; -#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE) - struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ - struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ -#endif #ifdef CONFIG_HOTPLUG_PCI_PCIE unsigned int broken_cmd_compl:1; /* No compl for some cmds */ @@ -2533,11 +2529,6 @@ int pcibios_alloc_irq(struct pci_dev *dev); void pcibios_free_irq(struct pci_dev *dev); resource_size_t pcibios_default_alignment(void); -#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE) -extern int pci_create_resource_files(struct pci_dev *dev); -extern void pci_remove_resource_files(struct pci_dev *dev); -#endif - #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) void __init pci_mmcfg_early_init(void); void __init pci_mmcfg_late_init(void); -- cgit v1.2.3 From e52e497e3778c99c3fb26ef6a47af6a219133f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:38 +0000 Subject: PCI: Add macros for legacy I/O and memory address space sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add defines for the standard PCI legacy address space sizes, replacing the raw literals used by the legacy sysfs attributes. Then, replace open-coded values with the newly added macros. No functional changes intended. Suggested-by: Ilpo Järvinen Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Link: https://patch.msgid.link/20260508043543.217179-20-kwilczynski@kernel.org --- include/linux/pci.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index c56f2cf0d2ab..e37677a8dd3c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -1169,6 +1170,10 @@ enum { /* These external functions are only available when PCI support is enabled */ #ifdef CONFIG_PCI +/* PCI legacy I/O port and memory address space sizes. */ +#define PCI_LEGACY_IO_SIZE (SZ_64K - 1) +#define PCI_LEGACY_MEM_SIZE SZ_1M + extern unsigned int pci_flags; static inline void pci_set_flags(int flags) { pci_flags = flags; } -- cgit v1.2.3 From 2800a911ced1540baa78de7494218aaf1c7dc4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Fri, 8 May 2026 04:35:42 +0000 Subject: PCI/sysfs: Remove pci_create_legacy_files() and pci_sysfs_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, pci_create_legacy_files() and pci_remove_legacy_files() are no-op stubs. With legacy attributes now handled by static groups registered via pcibus_groups[], no call site needs them. Remove both functions, their declarations, and the call sites in pci_register_host_bridge(), pci_alloc_child_bus(), and pci_remove_bus(). Remove the pci_sysfs_init() late_initcall and sysfs_initialized. The late_initcall originally existed to create all the dynamic PCI sysfs files, but with both resource and legacy attributes now handled by static groups, it is no longer needed. Remove the legacy_io and legacy_mem fields from struct pci_bus which were used to track the dynamically allocated legacy attributes. Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Tested-by: Shivaprasad G Bhat Link: https://patch.msgid.link/20260508043543.217179-24-kwilczynski@kernel.org --- include/linux/pci.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e37677a8dd3c..74b767012766 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -726,8 +726,6 @@ struct pci_bus { pci_bus_flags_t bus_flags; /* Inherited by child buses */ struct device *bridge; struct device dev; - struct bin_attribute *legacy_io; /* Legacy I/O for this bus */ - struct bin_attribute *legacy_mem; /* Legacy mem */ unsigned int is_added:1; unsigned int unsafe_warn:1; /* warned about RW1C config write */ unsigned int flit_mode:1; /* Link in Flit mode */ -- cgit v1.2.3