diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/eeh.h | 11 | ||||
-rw-r--r-- | arch/powerpc/include/asm/pci-bridge.h | 8 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc-pci.h | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_dev.c | 14 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 40 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 2 |
6 files changed, 69 insertions, 11 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 55abfd09e47f..2106f83da2d5 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -30,6 +30,7 @@ | |||
30 | struct pci_dev; | 30 | struct pci_dev; |
31 | struct pci_bus; | 31 | struct pci_bus; |
32 | struct device_node; | 32 | struct device_node; |
33 | struct pci_dn; | ||
33 | 34 | ||
34 | #ifdef CONFIG_EEH | 35 | #ifdef CONFIG_EEH |
35 | 36 | ||
@@ -137,6 +138,7 @@ struct eeh_dev { | |||
137 | struct list_head list; /* Form link list in the PE */ | 138 | struct list_head list; /* Form link list in the PE */ |
138 | struct pci_controller *phb; /* Associated PHB */ | 139 | struct pci_controller *phb; /* Associated PHB */ |
139 | struct device_node *dn; /* Associated device node */ | 140 | struct device_node *dn; /* Associated device node */ |
141 | struct pci_dn *pdn; /* Associated PCI device node */ | ||
140 | struct pci_dev *pdev; /* Associated PCI device */ | 142 | struct pci_dev *pdev; /* Associated PCI device */ |
141 | struct pci_bus *bus; /* PCI bus for partial hotplug */ | 143 | struct pci_bus *bus; /* PCI bus for partial hotplug */ |
142 | }; | 144 | }; |
@@ -146,6 +148,11 @@ static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev) | |||
146 | return edev ? edev->dn : NULL; | 148 | return edev ? edev->dn : NULL; |
147 | } | 149 | } |
148 | 150 | ||
151 | static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev) | ||
152 | { | ||
153 | return edev ? edev->pdn : NULL; | ||
154 | } | ||
155 | |||
149 | static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev) | 156 | static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev) |
150 | { | 157 | { |
151 | return edev ? edev->pdev : NULL; | 158 | return edev ? edev->pdev : NULL; |
@@ -272,7 +279,7 @@ void eeh_pe_restore_bars(struct eeh_pe *pe); | |||
272 | const char *eeh_pe_loc_get(struct eeh_pe *pe); | 279 | const char *eeh_pe_loc_get(struct eeh_pe *pe); |
273 | struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); | 280 | struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); |
274 | 281 | ||
275 | void *eeh_dev_init(struct device_node *dn, void *data); | 282 | void *eeh_dev_init(struct pci_dn *pdn, void *data); |
276 | void eeh_dev_phb_init_dynamic(struct pci_controller *phb); | 283 | void eeh_dev_phb_init_dynamic(struct pci_controller *phb); |
277 | int eeh_init(void); | 284 | int eeh_init(void); |
278 | int __init eeh_ops_register(struct eeh_ops *ops); | 285 | int __init eeh_ops_register(struct eeh_ops *ops); |
@@ -323,7 +330,7 @@ static inline int eeh_init(void) | |||
323 | return 0; | 330 | return 0; |
324 | } | 331 | } |
325 | 332 | ||
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) |
327 | { | 334 | { |
328 | return NULL; | 335 | return NULL; |
329 | } | 336 | } |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 01b730a8a5a3..7b74499b728c 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -213,8 +213,14 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn) | |||
213 | 213 | ||
214 | return PCI_DN(dn)->edev; | 214 | return PCI_DN(dn)->edev; |
215 | } | 215 | } |
216 | |||
217 | static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn) | ||
218 | { | ||
219 | return pdn ? pdn->edev : NULL; | ||
220 | } | ||
216 | #else | 221 | #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) | ||
218 | #endif | 224 | #endif |
219 | 225 | ||
220 | /** Find the bus corresponding to the indicated device node */ | 226 | /** Find the bus corresponding to the indicated device node */ |
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index db1e2b8eff3c..ade75238ceb5 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h | |||
@@ -33,9 +33,14 @@ extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */ | |||
33 | 33 | ||
34 | /* PCI device_node operations */ | 34 | /* PCI device_node operations */ |
35 | struct device_node; | 35 | struct device_node; |
36 | struct pci_dn; | ||
37 | |||
36 | typedef void *(*traverse_func)(struct device_node *me, void *data); | 38 | typedef void *(*traverse_func)(struct device_node *me, void *data); |
37 | void *traverse_pci_devices(struct device_node *start, traverse_func pre, | 39 | void *traverse_pci_devices(struct device_node *start, traverse_func pre, |
38 | void *data); | 40 | void *data); |
41 | void *traverse_pci_dn(struct pci_dn *root, | ||
42 | void *(*fn)(struct pci_dn *, void *), | ||
43 | void *data); | ||
39 | 44 | ||
40 | extern void pci_devs_phb_init(void); | 45 | extern void pci_devs_phb_init(void); |
41 | extern void pci_devs_phb_init_dynamic(struct pci_controller *phb); | 46 | extern void pci_devs_phb_init_dynamic(struct pci_controller *phb); |
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) |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e445b6701f50..70304070a260 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -265,7 +265,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act | |||
265 | update_dn_pci_info(np, pci->phb); | 265 | update_dn_pci_info(np, pci->phb); |
266 | 266 | ||
267 | /* Create EEH device for the OF node */ | 267 | /* Create EEH device for the OF node */ |
268 | eeh_dev_init(np, pci->phb); | 268 | eeh_dev_init(PCI_DN(np), pci->phb); |
269 | } | 269 | } |
270 | break; | 270 | break; |
271 | default: | 271 | default: |