aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/rpaphp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/rpaphp_core.c')
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c114
1 files changed, 62 insertions, 52 deletions
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index cf075c34b578..6e79f5675b0d 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -56,25 +56,6 @@ MODULE_LICENSE("GPL");
56 56
57module_param(debug, bool, 0644); 57module_param(debug, bool, 0644);
58 58
59static int enable_slot(struct hotplug_slot *slot);
60static int disable_slot(struct hotplug_slot *slot);
61static int set_attention_status(struct hotplug_slot *slot, u8 value);
62static int get_power_status(struct hotplug_slot *slot, u8 * value);
63static int get_attention_status(struct hotplug_slot *slot, u8 * value);
64static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
65static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
66
67struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
68 .owner = THIS_MODULE,
69 .enable_slot = enable_slot,
70 .disable_slot = disable_slot,
71 .set_attention_status = set_attention_status,
72 .get_power_status = get_power_status,
73 .get_attention_status = get_attention_status,
74 .get_adapter_status = get_adapter_status,
75 .get_max_bus_speed = get_max_bus_speed,
76};
77
78static int rpaphp_get_attention_status(struct slot *slot) 59static int rpaphp_get_attention_status(struct slot *slot)
79{ 60{
80 return slot->hotplug_slot->info->attention_status; 61 return slot->hotplug_slot->info->attention_status;
@@ -196,11 +177,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
196 return 0; 177 return 0;
197} 178}
198 179
199int rpaphp_remove_slot(struct slot *slot)
200{
201 return deregister_slot(slot);
202}
203
204static int get_children_props(struct device_node *dn, int **drc_indexes, 180static int get_children_props(struct device_node *dn, int **drc_indexes,
205 int **drc_names, int **drc_types, int **drc_power_domains) 181 int **drc_names, int **drc_types, int **drc_power_domains)
206{ 182{
@@ -307,13 +283,15 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names,
307 return 0; 283 return 0;
308} 284}
309 285
310/**************************************************************** 286/**
287 * rpaphp_add_slot -- add hotplug or dlpar slot
288 *
311 * rpaphp not only registers PCI hotplug slots(HOTPLUG), 289 * rpaphp not only registers PCI hotplug slots(HOTPLUG),
312 * but also logical DR slots(EMBEDDED). 290 * but also logical DR slots(EMBEDDED).
313 * HOTPLUG slot: An adapter can be physically added/removed. 291 * HOTPLUG slot: An adapter can be physically added/removed.
314 * EMBEDDED slot: An adapter can be logically removed/added 292 * EMBEDDED slot: An adapter can be logically removed/added
315 * from/to a partition with the slot. 293 * from/to a partition with the slot.
316 ***************************************************************/ 294 */
317int rpaphp_add_slot(struct device_node *dn) 295int rpaphp_add_slot(struct device_node *dn)
318{ 296{
319 struct slot *slot; 297 struct slot *slot;
@@ -344,7 +322,7 @@ int rpaphp_add_slot(struct device_node *dn)
344 dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", 322 dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
345 indexes[i + 1], name, type); 323 indexes[i + 1], name, type);
346 324
347 retval = register_pci_slot(slot); 325 retval = rpaphp_register_pci_slot(slot);
348 } 326 }
349 } 327 }
350exit: 328exit:
@@ -393,53 +371,85 @@ static void __exit rpaphp_exit(void)
393 cleanup_slots(); 371 cleanup_slots();
394} 372}
395 373
396static int enable_slot(struct hotplug_slot *hotplug_slot) 374static int __enable_slot(struct slot *slot)
397{ 375{
398 int retval = 0; 376 int state;
399 struct slot *slot = (struct slot *)hotplug_slot->private; 377 int retval;
400 378
401 if (slot->state == CONFIGURED) { 379 if (slot->state == CONFIGURED)
402 dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name); 380 return 0;
403 goto exit; 381
382 retval = rpaphp_get_sensor_state(slot, &state);
383 if (retval)
384 return retval;
385
386 if (state == PRESENT) {
387 pcibios_add_pci_devices(slot->bus);
388 slot->state = CONFIGURED;
389 } else if (state == EMPTY) {
390 slot->state = EMPTY;
391 } else {
392 err("%s: slot[%s] is in invalid state\n", __FUNCTION__, slot->name);
393 slot->state = NOT_VALID;
394 return -EINVAL;
404 } 395 }
396 return 0;
397}
398
399static int enable_slot(struct hotplug_slot *hotplug_slot)
400{
401 int retval;
402 struct slot *slot = (struct slot *)hotplug_slot->private;
405 403
406 dbg("ENABLING SLOT %s\n", slot->name);
407 down(&rpaphp_sem); 404 down(&rpaphp_sem);
408 retval = rpaphp_enable_pci_slot(slot); 405 retval = __enable_slot(slot);
409 up(&rpaphp_sem); 406 up(&rpaphp_sem);
410exit: 407
411 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
412 return retval; 408 return retval;
413} 409}
414 410
415static int disable_slot(struct hotplug_slot *hotplug_slot) 411static int __disable_slot(struct slot *slot)
416{ 412{
417 int retval = -EINVAL; 413 struct pci_dev *dev, *tmp;
418 struct slot *slot = (struct slot *)hotplug_slot->private;
419 414
420 dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); 415 if (slot->state == NOT_CONFIGURED)
416 return -EINVAL;
421 417
422 if (slot->state == NOT_CONFIGURED) { 418 list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) {
423 dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name); 419 eeh_remove_bus_device(dev);
424 goto exit; 420 pci_remove_bus_device(dev);
425 } 421 }
426 422
427 dbg("DISABLING SLOT %s\n", slot->name); 423 slot->state = NOT_CONFIGURED;
424 return 0;
425}
426
427static int disable_slot(struct hotplug_slot *hotplug_slot)
428{
429 struct slot *slot = (struct slot *)hotplug_slot->private;
430 int retval;
431
428 down(&rpaphp_sem); 432 down(&rpaphp_sem);
429 retval = rpaphp_unconfig_pci_adapter(slot->bus); 433 retval = __disable_slot (slot);
430 up(&rpaphp_sem); 434 up(&rpaphp_sem);
431 slot->state = NOT_CONFIGURED; 435
432 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
433 slot->name);
434exit:
435 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
436 return retval; 436 return retval;
437} 437}
438 438
439struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
440 .owner = THIS_MODULE,
441 .enable_slot = enable_slot,
442 .disable_slot = disable_slot,
443 .set_attention_status = set_attention_status,
444 .get_power_status = get_power_status,
445 .get_attention_status = get_attention_status,
446 .get_adapter_status = get_adapter_status,
447 .get_max_bus_speed = get_max_bus_speed,
448};
449
439module_init(rpaphp_init); 450module_init(rpaphp_init);
440module_exit(rpaphp_exit); 451module_exit(rpaphp_exit);
441 452
442EXPORT_SYMBOL_GPL(rpaphp_add_slot); 453EXPORT_SYMBOL_GPL(rpaphp_add_slot);
443EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
444EXPORT_SYMBOL_GPL(rpaphp_slot_head); 454EXPORT_SYMBOL_GPL(rpaphp_slot_head);
445EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); 455EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);