diff options
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_pci.c | 36 |
3 files changed, 35 insertions, 14 deletions
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 2ee7eb513e6c..f2a73f70e58c 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -209,9 +209,10 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) | |||
209 | return dev; | 209 | return dev; |
210 | } | 210 | } |
211 | 211 | ||
212 | static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) | 212 | static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) |
213 | { | 213 | { |
214 | struct pci_dev *dev; | 214 | struct pci_dev *dev; |
215 | int rc; | ||
215 | 216 | ||
216 | /* Add pci bus */ | 217 | /* Add pci bus */ |
217 | dev = dlpar_pci_add_bus(dn); | 218 | dev = dlpar_pci_add_bus(dn); |
@@ -221,6 +222,15 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) | |||
221 | return -EIO; | 222 | return -EIO; |
222 | } | 223 | } |
223 | 224 | ||
225 | if (dn->child) { | ||
226 | rc = rpaphp_config_pci_adapter(dev->subordinate); | ||
227 | if (rc < 0) { | ||
228 | printk(KERN_ERR "%s: unable to enable slot %s\n", | ||
229 | __FUNCTION__, drc_name); | ||
230 | return -EIO; | ||
231 | } | ||
232 | } | ||
233 | |||
224 | /* Add hotplug slot */ | 234 | /* Add hotplug slot */ |
225 | if (rpaphp_add_slot(dn)) { | 235 | if (rpaphp_add_slot(dn)) { |
226 | printk(KERN_ERR "%s: unable to add hotplug slot %s\n", | 236 | printk(KERN_ERR "%s: unable to add hotplug slot %s\n", |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 8ecff0b950e8..064a0d66e3c5 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -98,6 +98,7 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); | |||
98 | extern int register_pci_slot(struct slot *slot); | 98 | extern int register_pci_slot(struct slot *slot); |
99 | extern int rpaphp_unconfig_pci_adapter(struct slot *slot); | 99 | extern int rpaphp_unconfig_pci_adapter(struct slot *slot); |
100 | extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); | 100 | extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); |
101 | extern int rpaphp_config_pci_adapter(struct pci_bus *bus); | ||
101 | 102 | ||
102 | /* rpaphp_core.c */ | 103 | /* rpaphp_core.c */ |
103 | extern int rpaphp_add_slot(struct device_node *dn); | 104 | extern int rpaphp_add_slot(struct device_node *dn); |
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 30a892ca4b37..f2f1cd0f941a 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -219,14 +219,15 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev) | |||
219 | given slot->dn and return the the first pci_dev. | 219 | given slot->dn and return the the first pci_dev. |
220 | *****************************************************************************/ | 220 | *****************************************************************************/ |
221 | static struct pci_dev * | 221 | static struct pci_dev * |
222 | rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus) | 222 | rpaphp_pci_config_slot(struct pci_bus *bus) |
223 | { | 223 | { |
224 | struct device_node *dn = pci_bus_to_OF_node(bus); | ||
224 | struct pci_dev *dev = NULL; | 225 | struct pci_dev *dev = NULL; |
225 | int slotno; | 226 | int slotno; |
226 | int num; | 227 | int num; |
227 | 228 | ||
228 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); | 229 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); |
229 | if (!dn->child) | 230 | if (!dn || !dn->child) |
230 | return NULL; | 231 | return NULL; |
231 | 232 | ||
232 | slotno = PCI_SLOT(dn->child->devfn); | 233 | slotno = PCI_SLOT(dn->child->devfn); |
@@ -260,35 +261,44 @@ static void enable_eeh(struct device_node *dn) | |||
260 | 261 | ||
261 | } | 262 | } |
262 | 263 | ||
263 | static void print_slot_pci_funcs(struct slot *slot) | 264 | static void print_slot_pci_funcs(struct pci_bus *bus) |
264 | { | 265 | { |
266 | struct device_node *dn; | ||
265 | struct pci_dev *dev; | 267 | struct pci_dev *dev; |
266 | 268 | ||
267 | dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name); | 269 | dn = pci_bus_to_OF_node(bus); |
268 | list_for_each_entry (dev, slot->pci_devs, bus_list) | 270 | if (!dn) |
271 | return; | ||
272 | |||
273 | dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name); | ||
274 | list_for_each_entry (dev, &bus->devices, bus_list) | ||
269 | dbg("\t%s\n", pci_name(dev)); | 275 | dbg("\t%s\n", pci_name(dev)); |
270 | return; | 276 | return; |
271 | } | 277 | } |
272 | 278 | ||
273 | static int rpaphp_config_pci_adapter(struct slot *slot) | 279 | int rpaphp_config_pci_adapter(struct pci_bus *bus) |
274 | { | 280 | { |
281 | struct device_node *dn = pci_bus_to_OF_node(bus); | ||
275 | struct pci_dev *dev; | 282 | struct pci_dev *dev; |
276 | int rc = -ENODEV; | 283 | int rc = -ENODEV; |
277 | 284 | ||
278 | dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); | 285 | dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); |
286 | if (!dn) | ||
287 | goto exit; | ||
279 | 288 | ||
280 | enable_eeh(slot->dn); | 289 | enable_eeh(dn); |
281 | dev = rpaphp_pci_config_slot(slot->dn, slot->bus); | 290 | dev = rpaphp_pci_config_slot(bus); |
282 | if (!dev) { | 291 | if (!dev) { |
283 | err("%s: can't find any devices.\n", __FUNCTION__); | 292 | err("%s: can't find any devices.\n", __FUNCTION__); |
284 | goto exit; | 293 | goto exit; |
285 | } | 294 | } |
286 | print_slot_pci_funcs(slot); | 295 | print_slot_pci_funcs(bus); |
287 | rc = 0; | 296 | rc = 0; |
288 | exit: | 297 | exit: |
289 | dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); | 298 | dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); |
290 | return rc; | 299 | return rc; |
291 | } | 300 | } |
301 | EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter); | ||
292 | 302 | ||
293 | static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) | 303 | static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) |
294 | { | 304 | { |
@@ -384,7 +394,7 @@ static int setup_pci_slot(struct slot *slot) | |||
384 | if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { | 394 | if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { |
385 | dbg("%s CONFIGURING pci adapter in slot[%s]\n", | 395 | dbg("%s CONFIGURING pci adapter in slot[%s]\n", |
386 | __FUNCTION__, slot->name); | 396 | __FUNCTION__, slot->name); |
387 | if (rpaphp_config_pci_adapter(slot)) { | 397 | if (rpaphp_config_pci_adapter(slot->bus)) { |
388 | err("%s: CONFIG pci adapter failed\n", __FUNCTION__); | 398 | err("%s: CONFIG pci adapter failed\n", __FUNCTION__); |
389 | goto exit_rc; | 399 | goto exit_rc; |
390 | } | 400 | } |
@@ -394,7 +404,7 @@ static int setup_pci_slot(struct slot *slot) | |||
394 | __FUNCTION__, slot->name); | 404 | __FUNCTION__, slot->name); |
395 | goto exit_rc; | 405 | goto exit_rc; |
396 | } | 406 | } |
397 | print_slot_pci_funcs(slot); | 407 | print_slot_pci_funcs(slot->bus); |
398 | if (!list_empty(slot->pci_devs)) { | 408 | if (!list_empty(slot->pci_devs)) { |
399 | slot->state = CONFIGURED; | 409 | slot->state = CONFIGURED; |
400 | } else { | 410 | } else { |
@@ -437,7 +447,7 @@ int rpaphp_enable_pci_slot(struct slot *slot) | |||
437 | /* if slot is not empty, enable the adapter */ | 447 | /* if slot is not empty, enable the adapter */ |
438 | if (state == PRESENT) { | 448 | if (state == PRESENT) { |
439 | dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); | 449 | dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); |
440 | retval = rpaphp_config_pci_adapter(slot); | 450 | retval = rpaphp_config_pci_adapter(slot->bus); |
441 | if (!retval) { | 451 | if (!retval) { |
442 | slot->state = CONFIGURED; | 452 | slot->state = CONFIGURED; |
443 | dbg("%s: PCI devices in slot[%s] has been configured\n", | 453 | dbg("%s: PCI devices in slot[%s] has been configured\n", |