aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-03-17 01:15:05 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-23 22:15:51 -0400
commite8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9 (patch)
treeaa6d7d2300e27e621af79b4a252ee9aa93a4a893 /arch/powerpc/kernel
parentc035ff1d2eaa03ab40839041e955a86a8e412eb4 (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.c14
-rw-r--r--arch/powerpc/kernel/pci_dn.c40
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 */
52void *eeh_dev_init(struct device_node *dn, void *data) 52void *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 */
81void eeh_dev_phb_init_dynamic(struct pci_controller *phb) 81void 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
249static 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
271void *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)