Skip to content

Commit 407abde

Browse files
Vidya Sagarbjorn-helgaas
authored andcommitted
PCI: of: Add of_pci_preserve_config() for per-host bridge support
Add of_pci_preserve_config() to look for the "linux,pci-probe-only" property under a specified node. If it's not found there, look under "of_chosen" in addition. If the caller didn't specify a node, look under "of_chosen". With a future patch, this will support "linux,pci-probe-only" on a per host bridge basis based on the presence of the property in the respective PCI host bridge DT node. Implement of_pci_check_probe_only() using of_pci_preserve_config(). Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vidya Sagar <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent 9d7d5db commit 407abde

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

drivers/pci/of.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,27 +234,61 @@ int of_get_pci_domain_nr(struct device_node *node)
234234
EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
235235

236236
/**
237-
* of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
238-
* is present and valid
237+
* of_pci_preserve_config - Return true if the boot configuration needs to
238+
* be preserved
239+
* @node: Device tree node.
240+
*
241+
* Look for "linux,pci-probe-only" property for a given PCI controller's
242+
* node and return true if found. Also look in the chosen node if the
243+
* property is not found in the given controller's node. Having this
244+
* property ensures that the kernel doesn't reconfigure the BARs and bridge
245+
* windows that are already done by the platform firmware.
246+
*
247+
* Return: true if the property exists; false otherwise.
239248
*/
240-
void of_pci_check_probe_only(void)
249+
bool of_pci_preserve_config(struct device_node *node)
241250
{
242-
u32 val;
251+
u32 val = 0;
243252
int ret;
244253

245-
ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
254+
if (!node) {
255+
pr_warn("device node is NULL, trying with of_chosen\n");
256+
node = of_chosen;
257+
}
258+
259+
retry:
260+
ret = of_property_read_u32(node, "linux,pci-probe-only", &val);
246261
if (ret) {
247-
if (ret == -ENODATA || ret == -EOVERFLOW)
248-
pr_warn("linux,pci-probe-only without valid value, ignoring\n");
249-
return;
262+
if (ret == -ENODATA || ret == -EOVERFLOW) {
263+
pr_warn("Incorrect value for linux,pci-probe-only in %pOF, ignoring\n",
264+
node);
265+
return false;
266+
}
267+
if (ret == -EINVAL) {
268+
if (node == of_chosen)
269+
return false;
270+
271+
node = of_chosen;
272+
goto retry;
273+
}
250274
}
251275

252276
if (val)
277+
return true;
278+
else
279+
return false;
280+
}
281+
282+
/**
283+
* of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
284+
* is present and valid
285+
*/
286+
void of_pci_check_probe_only(void)
287+
{
288+
if (of_pci_preserve_config(of_chosen))
253289
pci_add_flags(PCI_PROBE_ONLY);
254290
else
255291
pci_clear_flags(PCI_PROBE_ONLY);
256-
257-
pr_info("PROBE_ONLY %s\n", val ? "enabled" : "disabled");
258292
}
259293
EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
260294

drivers/pci/pci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ int of_pci_get_max_link_speed(struct device_node *node);
648648
u32 of_pci_get_slot_power_limit(struct device_node *node,
649649
u8 *slot_power_limit_value,
650650
u8 *slot_power_limit_scale);
651+
bool of_pci_preserve_config(struct device_node *node);
651652
int pci_set_of_node(struct pci_dev *dev);
652653
void pci_release_of_node(struct pci_dev *dev);
653654
void pci_set_bus_of_node(struct pci_bus *bus);
@@ -686,6 +687,11 @@ of_pci_get_slot_power_limit(struct device_node *node,
686687
return 0;
687688
}
688689

690+
static inline bool of_pci_preserve_config(struct device_node *node)
691+
{
692+
return false;
693+
}
694+
689695
static inline int pci_set_of_node(struct pci_dev *dev) { return 0; }
690696
static inline void pci_release_of_node(struct pci_dev *dev) { }
691697
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }

0 commit comments

Comments
 (0)