From 407abde9caee0d8f757fc8bed43fa5efc6fe509a Mon Sep 17 00:00:00 2001 From: Vidya Sagar Date: Wed, 8 May 2024 23:11:36 +0530 Subject: 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/20240508174138.3630283-3-vidyas@nvidia.com Signed-off-by: Vidya Sagar Signed-off-by: Bjorn Helgaas --- drivers/pci/of.c | 54 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'drivers/pci/of.c') diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 51e3dd0ea5ab..48ba95e4ab05 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -234,27 +234,61 @@ int of_get_pci_domain_nr(struct device_node *node) EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); /** - * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only - * is present and valid + * of_pci_preserve_config - Return true if the boot configuration needs to + * be preserved + * @node: Device tree node. + * + * Look for "linux,pci-probe-only" property for a given PCI controller's + * node and return true if found. Also look in the chosen node if the + * property is not found in the given controller's node. Having this + * property ensures that the kernel doesn't reconfigure the BARs and bridge + * windows that are already done by the platform firmware. + * + * Return: true if the property exists; false otherwise. */ -void of_pci_check_probe_only(void) +bool of_pci_preserve_config(struct device_node *node) { - u32 val; + u32 val = 0; int ret; - ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val); + if (!node) { + pr_warn("device node is NULL, trying with of_chosen\n"); + node = of_chosen; + } + +retry: + ret = of_property_read_u32(node, "linux,pci-probe-only", &val); if (ret) { - if (ret == -ENODATA || ret == -EOVERFLOW) - pr_warn("linux,pci-probe-only without valid value, ignoring\n"); - return; + if (ret == -ENODATA || ret == -EOVERFLOW) { + pr_warn("Incorrect value for linux,pci-probe-only in %pOF, ignoring\n", + node); + return false; + } + if (ret == -EINVAL) { + if (node == of_chosen) + return false; + + node = of_chosen; + goto retry; + } } if (val) + return true; + else + return false; +} + +/** + * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only + * is present and valid + */ +void of_pci_check_probe_only(void) +{ + if (of_pci_preserve_config(of_chosen)) pci_add_flags(PCI_PROBE_ONLY); else pci_clear_flags(PCI_PROBE_ONLY); - - pr_info("PROBE_ONLY %s\n", val ? "enabled" : "disabled"); } EXPORT_SYMBOL_GPL(of_pci_check_probe_only); -- cgit v1.2.3