diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-03-17 16:15:05 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-03-24 13:15:51 +1100 |
commit | e8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9 (patch) | |
tree | aa6d7d2300e27e621af79b4a252ee9aa93a4a893 /arch/powerpc/kernel/pci_dn.c | |
parent | c035ff1d2eaa03ab40839041e955a86a8e412eb4 (diff) | |
download | blackbird-op-linux-e8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9.tar.gz blackbird-op-linux-e8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9.zip |
powerpc/eeh: Create eeh_dev from pci_dn instead of device_node
The patch adds function traverse_pci_dn(), which is similar to
traverse_pci_devices() except it takes pci_dn, not device_node
as parameter. The pci_dev.c has been reworked to create eeh_dev
from pci_dn, instead of device_node.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_dn.c')
-rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index d139f72ff9d5..65b98367005c 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -246,6 +246,46 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, return NULL; } +static struct pci_dn *pci_dn_next_one(struct pci_dn *root, + struct pci_dn *pdn) +{ + struct list_head *next = pdn->child_list.next; + + if (next != &pdn->child_list) + return list_entry(next, struct pci_dn, list); + + while (1) { + if (pdn == root) + return NULL; + + next = pdn->list.next; + if (next != &pdn->parent->child_list) + break; + + pdn = pdn->parent; + } + + return list_entry(next, struct pci_dn, list); +} + +void *traverse_pci_dn(struct pci_dn *root, + void *(*fn)(struct pci_dn *, void *), + void *data) +{ + struct pci_dn *pdn = root; + void *ret; + + /* Only scan the child nodes */ + for (pdn = pci_dn_next_one(root, pdn); pdn; + pdn = pci_dn_next_one(root, pdn)) { + ret = fn(pdn, data); + if (ret) + return ret; + } + + return NULL; +} + /** * pci_devs_phb_init_dynamic - setup pci devices under this PHB * phb: pci-to-host bridge (top-level bridge connecting to cpu) |