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 <vidyas@nvidia.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
9d7d5db8e7
commit
407abde9ca
@ -233,28 +233,62 @@ int of_get_pci_domain_nr(struct device_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
bool of_pci_preserve_config(struct device_node *node)
|
||||
{
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
|
||||
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("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)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(of_chosen, "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 (val)
|
||||
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);
|
||||
|
||||
|
@ -648,6 +648,7 @@ int of_pci_get_max_link_speed(struct device_node *node);
|
||||
u32 of_pci_get_slot_power_limit(struct device_node *node,
|
||||
u8 *slot_power_limit_value,
|
||||
u8 *slot_power_limit_scale);
|
||||
bool of_pci_preserve_config(struct device_node *node);
|
||||
int pci_set_of_node(struct pci_dev *dev);
|
||||
void pci_release_of_node(struct pci_dev *dev);
|
||||
void pci_set_bus_of_node(struct pci_bus *bus);
|
||||
@ -686,6 +687,11 @@ of_pci_get_slot_power_limit(struct device_node *node,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool of_pci_preserve_config(struct device_node *node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int pci_set_of_node(struct pci_dev *dev) { return 0; }
|
||||
static inline void pci_release_of_node(struct pci_dev *dev) { }
|
||||
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
|
||||
|
Loading…
x
Reference in New Issue
Block a user