Skip to content

Commit e8e9b34

Browse files
Gavin Shanozbenh
authored andcommitted
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>
1 parent c035ff1 commit e8e9b34

File tree

6 files changed

+69
-11
lines changed

6 files changed

+69
-11
lines changed

arch/powerpc/include/asm/eeh.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
struct pci_dev;
3131
struct pci_bus;
3232
struct device_node;
33+
struct pci_dn;
3334

3435
#ifdef CONFIG_EEH
3536

@@ -137,6 +138,7 @@ struct eeh_dev {
137138
struct list_head list; /* Form link list in the PE */
138139
struct pci_controller *phb; /* Associated PHB */
139140
struct device_node *dn; /* Associated device node */
141+
struct pci_dn *pdn; /* Associated PCI device node */
140142
struct pci_dev *pdev; /* Associated PCI device */
141143
struct pci_bus *bus; /* PCI bus for partial hotplug */
142144
};
@@ -146,6 +148,11 @@ static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
146148
return edev ? edev->dn : NULL;
147149
}
148150

151+
static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
152+
{
153+
return edev ? edev->pdn : NULL;
154+
}
155+
149156
static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
150157
{
151158
return edev ? edev->pdev : NULL;
@@ -272,7 +279,7 @@ void eeh_pe_restore_bars(struct eeh_pe *pe);
272279
const char *eeh_pe_loc_get(struct eeh_pe *pe);
273280
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
274281

275-
void *eeh_dev_init(struct device_node *dn, void *data);
282+
void *eeh_dev_init(struct pci_dn *pdn, void *data);
276283
void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
277284
int eeh_init(void);
278285
int __init eeh_ops_register(struct eeh_ops *ops);
@@ -323,7 +330,7 @@ static inline int eeh_init(void)
323330
return 0;
324331
}
325332

326-
static inline void *eeh_dev_init(struct device_node *dn, void *data)
333+
static inline void *eeh_dev_init(struct pci_dn *pdn, void *data)
327334
{
328335
return NULL;
329336
}

arch/powerpc/include/asm/pci-bridge.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,14 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
213213

214214
return PCI_DN(dn)->edev;
215215
}
216+
217+
static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
218+
{
219+
return pdn ? pdn->edev : NULL;
220+
}
216221
#else
217-
#define of_node_to_eeh_dev(x) (NULL)
222+
#define of_node_to_eeh_dev(x) (NULL)
223+
#define pdn_to_eeh_dev(x) (NULL)
218224
#endif
219225

220226
/** Find the bus corresponding to the indicated device node */

arch/powerpc/include/asm/ppc-pci.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
3333

3434
/* PCI device_node operations */
3535
struct device_node;
36+
struct pci_dn;
37+
3638
typedef void *(*traverse_func)(struct device_node *me, void *data);
3739
void *traverse_pci_devices(struct device_node *start, traverse_func pre,
3840
void *data);
41+
void *traverse_pci_dn(struct pci_dn *root,
42+
void *(*fn)(struct pci_dn *, void *),
43+
void *data);
3944

4045
extern void pci_devs_phb_init(void);
4146
extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);

arch/powerpc/kernel/eeh_dev.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343

4444
/**
4545
* eeh_dev_init - Create EEH device according to OF node
46-
* @dn: device node
46+
* @pdn: PCI device node
4747
* @data: PHB
4848
*
4949
* It will create EEH device according to the given OF node. The function
5050
* might be called by PCI emunation, DR, PHB hotplug.
5151
*/
52-
void *eeh_dev_init(struct device_node *dn, void *data)
52+
void *eeh_dev_init(struct pci_dn *pdn, void *data)
5353
{
5454
struct pci_controller *phb = data;
5555
struct eeh_dev *edev;
@@ -63,8 +63,8 @@ void *eeh_dev_init(struct device_node *dn, void *data)
6363
}
6464

6565
/* Associate EEH device with OF node */
66-
PCI_DN(dn)->edev = edev;
67-
edev->dn = dn;
66+
pdn->edev = edev;
67+
edev->pdn = pdn;
6868
edev->phb = phb;
6969
INIT_LIST_HEAD(&edev->list);
7070

@@ -80,16 +80,16 @@ void *eeh_dev_init(struct device_node *dn, void *data)
8080
*/
8181
void eeh_dev_phb_init_dynamic(struct pci_controller *phb)
8282
{
83-
struct device_node *dn = phb->dn;
83+
struct pci_dn *root = phb->pci_data;
8484

8585
/* EEH PE for PHB */
8686
eeh_phb_pe_create(phb);
8787

8888
/* EEH device for PHB */
89-
eeh_dev_init(dn, phb);
89+
eeh_dev_init(root, phb);
9090

9191
/* EEH devices for children OF nodes */
92-
traverse_pci_devices(dn, eeh_dev_init, phb);
92+
traverse_pci_dn(root, eeh_dev_init, phb);
9393
}
9494

9595
/**

arch/powerpc/kernel/pci_dn.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,46 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
246246
return NULL;
247247
}
248248

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+
249289
/**
250290
* pci_devs_phb_init_dynamic - setup pci devices under this PHB
251291
* phb: pci-to-host bridge (top-level bridge connecting to cpu)

arch/powerpc/platforms/pseries/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
265265
update_dn_pci_info(np, pci->phb);
266266

267267
/* Create EEH device for the OF node */
268-
eeh_dev_init(np, pci->phb);
268+
eeh_dev_init(PCI_DN(np), pci->phb);
269269
}
270270
break;
271271
default:

0 commit comments

Comments
 (0)