diff options
| author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-03-17 01:15:05 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-03-23 22:15:51 -0400 |
| commit | e8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9 (patch) | |
| tree | aa6d7d2300e27e621af79b4a252ee9aa93a4a893 /arch/powerpc/kernel | |
| parent | c035ff1d2eaa03ab40839041e955a86a8e412eb4 (diff) | |
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')
| -rw-r--r-- | arch/powerpc/kernel/eeh_dev.c | 14 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 40 |
2 files changed, 47 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index e5274ee9a75f..aabba94ff9cb 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c | |||
| @@ -43,13 +43,13 @@ | |||
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | * eeh_dev_init - Create EEH device according to OF node | 45 | * eeh_dev_init - Create EEH device according to OF node |
| 46 | * @dn: device node | 46 | * @pdn: PCI device node |
| 47 | * @data: PHB | 47 | * @data: PHB |
| 48 | * | 48 | * |
| 49 | * It will create EEH device according to the given OF node. The function | 49 | * It will create EEH device according to the given OF node. The function |
| 50 | * might be called by PCI emunation, DR, PHB hotplug. | 50 | * might be called by PCI emunation, DR, PHB hotplug. |
| 51 | */ | 51 | */ |
| 52 | void *eeh_dev_init(struct device_node *dn, void *data) | 52 | void *eeh_dev_init(struct pci_dn *pdn, void *data) |
| 53 | { | 53 | { |
| 54 | struct pci_controller *phb = data; | 54 | struct pci_controller *phb = data; |
| 55 | struct eeh_dev *edev; | 55 | struct eeh_dev *edev; |
| @@ -63,8 +63,8 @@ void *eeh_dev_init(struct device_node *dn, void *data) | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /* Associate EEH device with OF node */ | 65 | /* Associate EEH device with OF node */ |
| 66 | PCI_DN(dn)->edev = edev; | 66 | pdn->edev = edev; |
| 67 | edev->dn = dn; | 67 | edev->pdn = pdn; |
| 68 | edev->phb = phb; | 68 | edev->phb = phb; |
| 69 | INIT_LIST_HEAD(&edev->list); | 69 | INIT_LIST_HEAD(&edev->list); |
| 70 | 70 | ||
| @@ -80,16 +80,16 @@ void *eeh_dev_init(struct device_node *dn, void *data) | |||
| 80 | */ | 80 | */ |
| 81 | void eeh_dev_phb_init_dynamic(struct pci_controller *phb) | 81 | void eeh_dev_phb_init_dynamic(struct pci_controller *phb) |
| 82 | { | 82 | { |
| 83 | struct device_node *dn = phb->dn; | 83 | struct pci_dn *root = phb->pci_data; |
| 84 | 84 | ||
| 85 | /* EEH PE for PHB */ | 85 | /* EEH PE for PHB */ |
| 86 | eeh_phb_pe_create(phb); | 86 | eeh_phb_pe_create(phb); |
| 87 | 87 | ||
| 88 | /* EEH device for PHB */ | 88 | /* EEH device for PHB */ |
| 89 | eeh_dev_init(dn, phb); | 89 | eeh_dev_init(root, phb); |
| 90 | 90 | ||
| 91 | /* EEH devices for children OF nodes */ | 91 | /* EEH devices for children OF nodes */ |
| 92 | traverse_pci_devices(dn, eeh_dev_init, phb); | 92 | traverse_pci_dn(root, eeh_dev_init, phb); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | /** | 95 | /** |
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, | |||
| 246 | return NULL; | 246 | return NULL; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | static struct pci_dn *pci_dn_next_one(struct pci_dn *root, | ||
| 250 | struct pci_dn *pdn) | ||
| 251 | { | ||
| 252 | struct list_head *next = pdn->child_list.next; | ||
| 253 | |||
| 254 | if (next != &pdn->child_list) | ||
| 255 | return list_entry(next, struct pci_dn, list); | ||
| 256 | |||
| 257 | while (1) { | ||
| 258 | if (pdn == root) | ||
| 259 | return NULL; | ||
| 260 | |||
| 261 | next = pdn->list.next; | ||
| 262 | if (next != &pdn->parent->child_list) | ||
| 263 | break; | ||
| 264 | |||
| 265 | pdn = pdn->parent; | ||
| 266 | } | ||
| 267 | |||
| 268 | return list_entry(next, struct pci_dn, list); | ||
| 269 | } | ||
| 270 | |||
| 271 | void *traverse_pci_dn(struct pci_dn *root, | ||
| 272 | void *(*fn)(struct pci_dn *, void *), | ||
| 273 | void *data) | ||
| 274 | { | ||
| 275 | struct pci_dn *pdn = root; | ||
| 276 | void *ret; | ||
| 277 | |||
| 278 | /* Only scan the child nodes */ | ||
| 279 | for (pdn = pci_dn_next_one(root, pdn); pdn; | ||
| 280 | pdn = pci_dn_next_one(root, pdn)) { | ||
| 281 | ret = fn(pdn, data); | ||
| 282 | if (ret) | ||
| 283 | return ret; | ||
| 284 | } | ||
| 285 | |||
| 286 | return NULL; | ||
| 287 | } | ||
| 288 | |||
| 249 | /** | 289 | /** |
| 250 | * pci_devs_phb_init_dynamic - setup pci devices under this PHB | 290 | * pci_devs_phb_init_dynamic - setup pci devices under this PHB |
| 251 | * phb: pci-to-host bridge (top-level bridge connecting to cpu) | 291 | * phb: pci-to-host bridge (top-level bridge connecting to cpu) |
