summaryrefslogtreecommitdiff
path: root/drivers/pci/of.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/of.c')
-rw-r--r--drivers/pci/of.c54
1 files changed, 44 insertions, 10 deletions
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);