[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250822145605.18172-24-ilpo.jarvinen@linux.intel.com>
Date: Fri, 22 Aug 2025 17:56:04 +0300
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Andreas Larsson <andreas@...sler.com>,
Bjorn Helgaas <bhelgaas@...gle.com>,
"David S. Miller" <davem@...emloft.net>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
linux-m68k@...ts.linux-m68k.org,
linux-mips@...r.kernel.org,
linux-pci@...r.kernel.org,
sparclinux@...r.kernel.org,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Christian König <christian.koenig@....com>,
Yinghai Lu <yinghai@...nel.org>,
Igor Mammedov <imammedo@...hat.com>,
"Rafael J . Wysocki" <rafael@...nel.org>,
Jonathan Cameron <Jonathan.Cameron@...wei.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@....com>,
Krzysztof Wilczyński <kw@...ux.com>,
linux-kernel@...r.kernel.org
Cc: Michał Winiarski <michal.winiarski@...el.com>,
linuxppc-dev@...ts.ozlabs.org,
Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: [PATCH 23/24] PCI: Pass bridge window to pci_bus_release_bridge_resources()
pci_bus_release_bridge_resources() takes type, which is converted
into a bridge window resource in pci_bridge_release_resources().
Find out the correct bridge window for resource whose assignment failed.
Pass that bridge window to pci_bus_release_bridge_resources() instead of
passing the type. When recursing to subordinate, check which bridge
windows have to be released and recurse for each.
For now, use pbus_select_window_for_type() instead of
pbus_select_window() because non-bridge window resources still have
their flags reset which destroys the type information from the struct
resource. The struct pci_dev_resource holds a copy of the flags which
are used instead.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
---
drivers/pci/setup-bus.c | 69 ++++++++++++++++-------------------------
1 file changed, 27 insertions(+), 42 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index f5b0274bde0a..9c69a84f2b23 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1800,51 +1800,24 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge,
}
static void pci_bridge_release_resources(struct pci_bus *bus,
- unsigned long type)
+ struct resource *b_win)
{
struct pci_dev *dev = bus->self;
- struct resource *r;
- struct resource *b_res;
int idx, ret;
- b_res = &dev->resource[PCI_BRIDGE_RESOURCES];
-
- /*
- * 1. If IO port assignment fails, release bridge IO port.
- * 2. If non pref MMIO assignment fails, release bridge nonpref MMIO.
- * 3. If 64bit pref MMIO assignment fails, and bridge pref is 64bit,
- * release bridge pref MMIO.
- * 4. If pref MMIO assignment fails, and bridge pref is 32bit,
- * release bridge pref MMIO.
- * 5. If pref MMIO assignment fails, and bridge pref is not
- * assigned, release bridge nonpref MMIO.
- */
- if (type & IORESOURCE_IO)
- idx = 0;
- else if (!(type & IORESOURCE_PREFETCH))
- idx = 1;
- else if ((type & IORESOURCE_MEM_64) &&
- (b_res[2].flags & IORESOURCE_MEM_64))
- idx = 2;
- else if (!(b_res[2].flags & IORESOURCE_MEM_64) &&
- (b_res[2].flags & IORESOURCE_PREFETCH))
- idx = 2;
- else
- idx = 1;
-
- r = &b_res[idx];
-
- if (!r->parent)
+ if (!b_win->parent)
return;
+ idx = pci_resource_num(dev, b_win);
+
/* If there are children, release them all */
- release_child_resources(r);
+ release_child_resources(b_win);
- ret = pci_release_resource(dev, PCI_BRIDGE_RESOURCES + idx);
+ ret = pci_release_resource(dev, idx);
if (ret)
return;
- pci_setup_one_bridge_window(dev, PCI_BRIDGE_RESOURCES + idx);
+ pci_setup_one_bridge_window(dev, idx);
}
enum release_type {
@@ -1857,7 +1830,7 @@ enum release_type {
* a larger window later.
*/
static void pci_bus_release_bridge_resources(struct pci_bus *bus,
- unsigned long type,
+ struct resource *b_win,
enum release_type rel_type)
{
struct pci_dev *dev;
@@ -1865,6 +1838,8 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus,
list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_bus *b = dev->subordinate;
+ struct resource *res;
+
if (!b)
continue;
@@ -1873,9 +1848,15 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus,
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
continue;
- if (rel_type == whole_subtree)
- pci_bus_release_bridge_resources(b, type,
- whole_subtree);
+ if (rel_type != whole_subtree)
+ continue;
+
+ pci_bus_for_each_resource(b, res) {
+ if (res->parent != b_win)
+ continue;
+
+ pci_bus_release_bridge_resources(b, res, whole_subtree);
+ }
}
if (pci_is_root_bus(bus))
@@ -1885,7 +1866,7 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus,
return;
if ((rel_type == whole_subtree) || is_leaf_bridge)
- pci_bridge_release_resources(bus, type);
+ pci_bridge_release_resources(bus, b_win);
}
static void pci_bus_dump_res(struct pci_bus *bus)
@@ -2282,9 +2263,13 @@ static void pci_prepare_next_assign_round(struct list_head *fail_head,
* enough to contain child device resources.
*/
list_for_each_entry(fail_res, fail_head, list) {
- pci_bus_release_bridge_resources(fail_res->dev->bus,
- fail_res->flags & PCI_RES_TYPE_MASK,
- rel_type);
+ struct pci_bus *bus = fail_res->dev->bus;
+ struct resource *b_win;
+
+ b_win = pbus_select_window_for_type(bus, fail_res->flags);
+ if (!b_win)
+ continue;
+ pci_bus_release_bridge_resources(bus, b_win, rel_type);
}
/* Restore size and flags */
--
2.39.5
Powered by blists - more mailing lists