/**
* of_node_is_pci - Test if a node a pci host
* @node: node to compare
*
* returns 1 for PCI hosts and 0 for anything else
*
* This function is meant to be called from
* of_find_phb_node as a helper. We compare both
* the compatible and the device_type properties
* to known strings used to indicate PCI hosts.
*/
static int of_node_is_pci(struct device_node *node)
{
if (!node)
return 0;
if (device_is_compatible(node, "pci") ||
device_is_compatible(node, "ht") ||
device_is_compatible(node, "pcie"))
return 1;
if (!node->type)
return 0;
if (!strcasecmp(node->type, "pci") ||
!strcasecmp(node->type, "ht") ||
!strcasecmp(node->type, "pcie"))
return 1;
return 0;
}
/**
*
* of_find_phb_node - Iterate all PCI host bridge device nodes
*
* @from: The node to start searching from or NULL, the node
* you pass will not be searched, only the next one
* will; typically, you pass what the previous call
* returned. of_node_put() will be called on it
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done.
*
* since we only want to return host bridges, not pci-pci
* bridges, check if the parent is not also a pci host.
*/
struct device_node *of_find_phb_node(struct device_node *from)
{
struct device_node *np;
read_lock(&devtree_lock);
np = from ? from->allnext : allnodes;
for (; np; np = np->allnext) {
if (of_node_is_pci(np) &&
!of_node_is_pci(np->parent))
break;
}
if (np)
of_node_get(np);
if (from)
of_node_put(from);
read_unlock(&devtree_lock);
return np;
}