aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:58:52 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:58:52 -0400
commitc0638a455382e01e42bf66d8d41e4b703f1550a5 (patch)
tree87e95b7eec0ea23bb23fc385d3b83333532fcd3d /drivers/pci/hotplug
parenta8bcb5e5966ccbd99a6d06cf69ada7f95416aabc (diff)
parent4e6a13356f1c1dc27ff48ff35576a478d73f8713 (diff)
Merge branch 'pci/hotplug'
- Simplify SHPC existence/permission checks (Bjorn Helgaas) - Remove hotplug sample skeleton driver (Lukas Wunner) - Convert pciehp to threaded IRQ handling (Lukas Wunner) - Improve pciehp tolerance of missed events and initially unstable links (Lukas Wunner) - Clear spurious pciehp events on resume (Lukas Wunner) - Add pciehp runtime PM support, including for Thunderbolt controllers (Lukas Wunner) - Support interrupts from pciehp bridges in D3hot (Lukas Wunner) * pci/hotplug: PCI: pciehp: Deduplicate presence check on probe & resume PCI: pciehp: Avoid implicit fallthroughs in switch statements PCI: Whitelist Thunderbolt ports for runtime D3 PCI: Whitelist native hotplug ports for runtime D3 PCI: sysfs: Resume to D0 on function reset PCI: pciehp: Resume parent to D0 on config space access PCI: pciehp: Resume to D0 on enable/disable PCI: pciehp: Support interrupts sent from D3hot PCI: pciehp: Obey compulsory command delay after resume PCI: pciehp: Clear spurious events earlier on resume PCI: portdrv: Deduplicate PM callback iterator PCI: pciehp: Avoid slot access during reset PCI: pciehp: Always enable occupied slot on probe PCI: pciehp: Become resilient to missed events PCI: pciehp: Tolerate initially unstable link PCI: pciehp: Declare pciehp_enable/disable_slot() static PCI: pciehp: Drop enable/disable lock PCI: pciehp: Enable/disable exclusively from IRQ thread PCI: pciehp: Track enable/disable status PCI: pciehp: Publish to user space last on probe PCI: hotplug: Demidlayer registration with the core PCI: pciehp: Drop slot workqueue PCI: pciehp: Handle events synchronously PCI: pciehp: Stop blinking on slot enable failure PCI: pciehp: Convert to threaded polling PCI: pciehp: Convert to threaded IRQ PCI: pciehp: Document struct slot and struct controller PCI: pciehp: Declare pciehp_unconfigure_device() void PCI: pciehp: Drop unnecessary NULL pointer check PCI: pciehp: Fix unprotected list iteration in IRQ handler PCI: pciehp: Fix use-after-free on unplug PCI: hotplug: Don't leak pci_slot on registration failure PCI: hotplug: Delete skeleton driver PCI: shpchp: Separate existence of SHPC and permission to use it
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c36
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c22
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c14
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c16
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c15
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c20
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c134
-rw-r--r--drivers/pci/hotplug/pciehp.h117
-rw-r--r--drivers/pci/hotplug/pciehp_core.c127
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c351
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c276
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c4
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c348
-rw-r--r--drivers/pci/hotplug/pnv_php.c5
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c2
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c13
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c13
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c9
-rw-r--r--drivers/pci/hotplug/shpchp_core.c41
19 files changed, 658 insertions, 905 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 5bd6c1573295..6b7c1ed58e7e 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -74,20 +74,6 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev)
74 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 74 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
75 75
76 /* 76 /*
77 * Per PCI firmware specification, we should run the ACPI _OSC
78 * method to get control of hotplug hardware before using it. If
79 * an _OSC is missing, we look for an OSHP to do the same thing.
80 * To handle different BIOS behavior, we look for _OSC on a root
81 * bridge preferentially (according to PCI fw spec). Later for
82 * OSHP within the scope of the hotplug controller and its parents,
83 * up to the host bridge under which this controller exists.
84 */
85 if (shpchp_is_native(pdev))
86 return 0;
87
88 /* If _OSC exists, we should not evaluate OSHP */
89
90 /*
91 * If there's no ACPI host bridge (i.e., ACPI support is compiled 77 * If there's no ACPI host bridge (i.e., ACPI support is compiled
92 * into the kernel but the hardware platform doesn't support ACPI), 78 * into the kernel but the hardware platform doesn't support ACPI),
93 * there's nothing to do here. 79 * there's nothing to do here.
@@ -97,9 +83,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev)
97 if (!root) 83 if (!root)
98 return 0; 84 return 0;
99 85
100 if (root->osc_support_set) 86 /*
101 goto no_control; 87 * If _OSC exists, it determines whether we're allowed to manage
88 * the SHPC. We executed it while enumerating the host bridge.
89 */
90 if (root->osc_support_set) {
91 if (host->native_shpc_hotplug)
92 return 0;
93 return -ENODEV;
94 }
102 95
96 /*
97 * In the absence of _OSC, we're always allowed to manage the SHPC.
98 * However, if an OSHP method is present, we must execute it so the
99 * firmware can transfer control to the OS, e.g., direct interrupts
100 * to the OS instead of to the firmware.
101 *
102 * N.B. The PCI Firmware Spec (r3.2, sec 4.8) does not endorse
103 * searching up the ACPI hierarchy, so the loops below are suspect.
104 */
103 handle = ACPI_HANDLE(&pdev->dev); 105 handle = ACPI_HANDLE(&pdev->dev);
104 if (!handle) { 106 if (!handle) {
105 /* 107 /*
@@ -128,7 +130,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev)
128 if (ACPI_FAILURE(status)) 130 if (ACPI_FAILURE(status))
129 break; 131 break;
130 } 132 }
131no_control: 133
132 pci_info(pdev, "Cannot get control of SHPC hotplug\n"); 134 pci_info(pdev, "Cannot get control of SHPC hotplug\n");
133 kfree(string.pointer); 135 kfree(string.pointer);
134 return -ENODEV; 136 return -ENODEV;
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 12b5655fd390..ad32ffbc4b91 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -254,20 +254,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
254 return 0; 254 return 0;
255} 255}
256 256
257/**
258 * release_slot - free up the memory used by a slot
259 * @hotplug_slot: slot to free
260 */
261static void release_slot(struct hotplug_slot *hotplug_slot)
262{
263 struct slot *slot = hotplug_slot->private;
264
265 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
266
267 kfree(slot->hotplug_slot);
268 kfree(slot);
269}
270
271/* callback routine to initialize 'struct slot' for each slot */ 257/* callback routine to initialize 'struct slot' for each slot */
272int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, 258int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,
273 unsigned int sun) 259 unsigned int sun)
@@ -287,7 +273,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot,
287 slot->hotplug_slot->info = &slot->info; 273 slot->hotplug_slot->info = &slot->info;
288 274
289 slot->hotplug_slot->private = slot; 275 slot->hotplug_slot->private = slot;
290 slot->hotplug_slot->release = &release_slot;
291 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; 276 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
292 277
293 slot->acpi_slot = acpiphp_slot; 278 slot->acpi_slot = acpiphp_slot;
@@ -324,13 +309,12 @@ error:
324void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) 309void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
325{ 310{
326 struct slot *slot = acpiphp_slot->slot; 311 struct slot *slot = acpiphp_slot->slot;
327 int retval = 0;
328 312
329 pr_info("Slot [%s] unregistered\n", slot_name(slot)); 313 pr_info("Slot [%s] unregistered\n", slot_name(slot));
330 314
331 retval = pci_hp_deregister(slot->hotplug_slot); 315 pci_hp_deregister(slot->hotplug_slot);
332 if (retval) 316 kfree(slot->hotplug_slot);
333 pr_err("pci_hp_deregister failed with error %d\n", retval); 317 kfree(slot);
334} 318}
335 319
336 320
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 07b533adc9df..52a339baf06c 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -195,10 +195,8 @@ get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
195 return 0; 195 return 0;
196} 196}
197 197
198static void release_slot(struct hotplug_slot *hotplug_slot) 198static void release_slot(struct slot *slot)
199{ 199{
200 struct slot *slot = hotplug_slot->private;
201
202 kfree(slot->hotplug_slot->info); 200 kfree(slot->hotplug_slot->info);
203 kfree(slot->hotplug_slot); 201 kfree(slot->hotplug_slot);
204 pci_dev_put(slot->dev); 202 pci_dev_put(slot->dev);
@@ -253,7 +251,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
253 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i); 251 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
254 252
255 hotplug_slot->private = slot; 253 hotplug_slot->private = slot;
256 hotplug_slot->release = &release_slot;
257 hotplug_slot->ops = &cpci_hotplug_slot_ops; 254 hotplug_slot->ops = &cpci_hotplug_slot_ops;
258 255
259 /* 256 /*
@@ -308,12 +305,8 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
308 slots--; 305 slots--;
309 306
310 dbg("deregistering slot %s", slot_name(slot)); 307 dbg("deregistering slot %s", slot_name(slot));
311 status = pci_hp_deregister(slot->hotplug_slot); 308 pci_hp_deregister(slot->hotplug_slot);
312 if (status) { 309 release_slot(slot);
313 err("pci_hp_deregister failed with error %d",
314 status);
315 break;
316 }
317 } 310 }
318 } 311 }
319 up_write(&list_rwsem); 312 up_write(&list_rwsem);
@@ -623,6 +616,7 @@ cleanup_slots(void)
623 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { 616 list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
624 list_del(&slot->slot_list); 617 list_del(&slot->slot_list);
625 pci_hp_deregister(slot->hotplug_slot); 618 pci_hp_deregister(slot->hotplug_slot);
619 release_slot(slot);
626 } 620 }
627cleanup_null: 621cleanup_null:
628 up_write(&list_rwsem); 622 up_write(&list_rwsem);
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 1797e36ec586..5a06636e910a 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -266,17 +266,6 @@ static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
266 return previous; 266 return previous;
267} 267}
268 268
269static void release_slot(struct hotplug_slot *hotplug_slot)
270{
271 struct slot *slot = hotplug_slot->private;
272
273 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
274
275 kfree(slot->hotplug_slot->info);
276 kfree(slot->hotplug_slot);
277 kfree(slot);
278}
279
280static int ctrl_slot_cleanup(struct controller *ctrl) 269static int ctrl_slot_cleanup(struct controller *ctrl)
281{ 270{
282 struct slot *old_slot, *next_slot; 271 struct slot *old_slot, *next_slot;
@@ -285,9 +274,11 @@ static int ctrl_slot_cleanup(struct controller *ctrl)
285 ctrl->slot = NULL; 274 ctrl->slot = NULL;
286 275
287 while (old_slot) { 276 while (old_slot) {
288 /* memory will be freed by the release_slot callback */
289 next_slot = old_slot->next; 277 next_slot = old_slot->next;
290 pci_hp_deregister(old_slot->hotplug_slot); 278 pci_hp_deregister(old_slot->hotplug_slot);
279 kfree(old_slot->hotplug_slot->info);
280 kfree(old_slot->hotplug_slot);
281 kfree(old_slot);
291 old_slot = next_slot; 282 old_slot = next_slot;
292 } 283 }
293 284
@@ -678,7 +669,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
678 ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; 669 ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
679 670
680 /* register this slot with the hotplug pci core */ 671 /* register this slot with the hotplug pci core */
681 hotplug_slot->release = &release_slot;
682 hotplug_slot->private = slot; 672 hotplug_slot->private = slot;
683 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); 673 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
684 hotplug_slot->ops = &cpqphp_hotplug_slot_ops; 674 hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 1869b0411ce0..4ea57e9019f1 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -673,7 +673,20 @@ static void free_slots(void)
673 673
674 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head, 674 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
675 ibm_slot_list) { 675 ibm_slot_list) {
676 pci_hp_deregister(slot_cur->hotplug_slot); 676 pci_hp_del(slot_cur->hotplug_slot);
677 slot_cur->ctrl = NULL;
678 slot_cur->bus_on = NULL;
679
680 /*
681 * We don't want to actually remove the resources,
682 * since ibmphp_free_resources() will do just that.
683 */
684 ibmphp_unconfigure_card(&slot_cur, -1);
685
686 pci_hp_destroy(slot_cur->hotplug_slot);
687 kfree(slot_cur->hotplug_slot->info);
688 kfree(slot_cur->hotplug_slot);
689 kfree(slot_cur);
677 } 690 }
678 debug("%s -- exit\n", __func__); 691 debug("%s -- exit\n", __func__);
679} 692}
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 64549aa24c0f..6f8e90e3ec08 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -699,25 +699,6 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot)
699 return rc; 699 return rc;
700} 700}
701 701
702static void release_slot(struct hotplug_slot *hotplug_slot)
703{
704 struct slot *slot;
705
706 if (!hotplug_slot || !hotplug_slot->private)
707 return;
708
709 slot = hotplug_slot->private;
710 kfree(slot->hotplug_slot->info);
711 kfree(slot->hotplug_slot);
712 slot->ctrl = NULL;
713 slot->bus_on = NULL;
714
715 /* we don't want to actually remove the resources, since free_resources will do just that */
716 ibmphp_unconfigure_card(&slot, -1);
717
718 kfree(slot);
719}
720
721static struct pci_driver ibmphp_driver; 702static struct pci_driver ibmphp_driver;
722 703
723/* 704/*
@@ -941,7 +922,6 @@ static int __init ebda_rsrc_controller(void)
941 tmp_slot->hotplug_slot = hp_slot_ptr; 922 tmp_slot->hotplug_slot = hp_slot_ptr;
942 923
943 hp_slot_ptr->private = tmp_slot; 924 hp_slot_ptr->private = tmp_slot;
944 hp_slot_ptr->release = release_slot;
945 925
946 rc = fillslotinfo(hp_slot_ptr); 926 rc = fillslotinfo(hp_slot_ptr);
947 if (rc) 927 if (rc)
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index af92fed46ab7..90fde5f106d8 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -396,8 +396,9 @@ static struct hotplug_slot *get_slot_from_name(const char *name)
396 * @owner: caller module owner 396 * @owner: caller module owner
397 * @mod_name: caller module name 397 * @mod_name: caller module name
398 * 398 *
399 * Registers a hotplug slot with the pci hotplug subsystem, which will allow 399 * Prepares a hotplug slot for in-kernel use and immediately publishes it to
400 * userspace interaction to the slot. 400 * user space in one go. Drivers may alternatively carry out the two steps
401 * separately by invoking pci_hp_initialize() and pci_hp_add().
401 * 402 *
402 * Returns 0 if successful, anything else for an error. 403 * Returns 0 if successful, anything else for an error.
403 */ 404 */
@@ -406,45 +407,91 @@ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus,
406 struct module *owner, const char *mod_name) 407 struct module *owner, const char *mod_name)
407{ 408{
408 int result; 409 int result;
410
411 result = __pci_hp_initialize(slot, bus, devnr, name, owner, mod_name);
412 if (result)
413 return result;
414
415 result = pci_hp_add(slot);
416 if (result)
417 pci_hp_destroy(slot);
418
419 return result;
420}
421EXPORT_SYMBOL_GPL(__pci_hp_register);
422
423/**
424 * __pci_hp_initialize - prepare hotplug slot for in-kernel use
425 * @slot: pointer to the &struct hotplug_slot to initialize
426 * @bus: bus this slot is on
427 * @devnr: slot number
428 * @name: name registered with kobject core
429 * @owner: caller module owner
430 * @mod_name: caller module name
431 *
432 * Allocate and fill in a PCI slot for use by a hotplug driver. Once this has
433 * been called, the driver may invoke hotplug_slot_name() to get the slot's
434 * unique name. The driver must be prepared to handle a ->reset_slot callback
435 * from this point on.
436 *
437 * Returns 0 on success or a negative int on error.
438 */
439int __pci_hp_initialize(struct hotplug_slot *slot, struct pci_bus *bus,
440 int devnr, const char *name, struct module *owner,
441 const char *mod_name)
442{
409 struct pci_slot *pci_slot; 443 struct pci_slot *pci_slot;
410 444
411 if (slot == NULL) 445 if (slot == NULL)
412 return -ENODEV; 446 return -ENODEV;
413 if ((slot->info == NULL) || (slot->ops == NULL)) 447 if ((slot->info == NULL) || (slot->ops == NULL))
414 return -EINVAL; 448 return -EINVAL;
415 if (slot->release == NULL) {
416 dbg("Why are you trying to register a hotplug slot without a proper release function?\n");
417 return -EINVAL;
418 }
419 449
420 slot->ops->owner = owner; 450 slot->ops->owner = owner;
421 slot->ops->mod_name = mod_name; 451 slot->ops->mod_name = mod_name;
422 452
423 mutex_lock(&pci_hp_mutex);
424 /* 453 /*
425 * No problems if we call this interface from both ACPI_PCI_SLOT 454 * No problems if we call this interface from both ACPI_PCI_SLOT
426 * driver and call it here again. If we've already created the 455 * driver and call it here again. If we've already created the
427 * pci_slot, the interface will simply bump the refcount. 456 * pci_slot, the interface will simply bump the refcount.
428 */ 457 */
429 pci_slot = pci_create_slot(bus, devnr, name, slot); 458 pci_slot = pci_create_slot(bus, devnr, name, slot);
430 if (IS_ERR(pci_slot)) { 459 if (IS_ERR(pci_slot))
431 result = PTR_ERR(pci_slot); 460 return PTR_ERR(pci_slot);
432 goto out;
433 }
434 461
435 slot->pci_slot = pci_slot; 462 slot->pci_slot = pci_slot;
436 pci_slot->hotplug = slot; 463 pci_slot->hotplug = slot;
464 return 0;
465}
466EXPORT_SYMBOL_GPL(__pci_hp_initialize);
437 467
438 list_add(&slot->slot_list, &pci_hotplug_slot_list); 468/**
469 * pci_hp_add - publish hotplug slot to user space
470 * @slot: pointer to the &struct hotplug_slot to publish
471 *
472 * Make a hotplug slot's sysfs interface available and inform user space of its
473 * addition by sending a uevent. The hotplug driver must be prepared to handle
474 * all &struct hotplug_slot_ops callbacks from this point on.
475 *
476 * Returns 0 on success or a negative int on error.
477 */
478int pci_hp_add(struct hotplug_slot *slot)
479{
480 struct pci_slot *pci_slot = slot->pci_slot;
481 int result;
439 482
440 result = fs_add_slot(pci_slot); 483 result = fs_add_slot(pci_slot);
484 if (result)
485 return result;
486
441 kobject_uevent(&pci_slot->kobj, KOBJ_ADD); 487 kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
442 dbg("Added slot %s to the list\n", name); 488 mutex_lock(&pci_hp_mutex);
443out: 489 list_add(&slot->slot_list, &pci_hotplug_slot_list);
444 mutex_unlock(&pci_hp_mutex); 490 mutex_unlock(&pci_hp_mutex);
445 return result; 491 dbg("Added slot %s to the list\n", hotplug_slot_name(slot));
492 return 0;
446} 493}
447EXPORT_SYMBOL_GPL(__pci_hp_register); 494EXPORT_SYMBOL_GPL(pci_hp_add);
448 495
449/** 496/**
450 * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem 497 * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
@@ -455,35 +502,62 @@ EXPORT_SYMBOL_GPL(__pci_hp_register);
455 * 502 *
456 * Returns 0 if successful, anything else for an error. 503 * Returns 0 if successful, anything else for an error.
457 */ 504 */
458int pci_hp_deregister(struct hotplug_slot *slot) 505void pci_hp_deregister(struct hotplug_slot *slot)
506{
507 pci_hp_del(slot);
508 pci_hp_destroy(slot);
509}
510EXPORT_SYMBOL_GPL(pci_hp_deregister);
511
512/**
513 * pci_hp_del - unpublish hotplug slot from user space
514 * @slot: pointer to the &struct hotplug_slot to unpublish
515 *
516 * Remove a hotplug slot's sysfs interface.
517 *
518 * Returns 0 on success or a negative int on error.
519 */
520void pci_hp_del(struct hotplug_slot *slot)
459{ 521{
460 struct hotplug_slot *temp; 522 struct hotplug_slot *temp;
461 struct pci_slot *pci_slot;
462 523
463 if (!slot) 524 if (WARN_ON(!slot))
464 return -ENODEV; 525 return;
465 526
466 mutex_lock(&pci_hp_mutex); 527 mutex_lock(&pci_hp_mutex);
467 temp = get_slot_from_name(hotplug_slot_name(slot)); 528 temp = get_slot_from_name(hotplug_slot_name(slot));
468 if (temp != slot) { 529 if (WARN_ON(temp != slot)) {
469 mutex_unlock(&pci_hp_mutex); 530 mutex_unlock(&pci_hp_mutex);
470 return -ENODEV; 531 return;
471 } 532 }
472 533
473 list_del(&slot->slot_list); 534 list_del(&slot->slot_list);
474 535 mutex_unlock(&pci_hp_mutex);
475 pci_slot = slot->pci_slot;
476 fs_remove_slot(pci_slot);
477 dbg("Removed slot %s from the list\n", hotplug_slot_name(slot)); 536 dbg("Removed slot %s from the list\n", hotplug_slot_name(slot));
537 fs_remove_slot(slot->pci_slot);
538}
539EXPORT_SYMBOL_GPL(pci_hp_del);
478 540
479 slot->release(slot); 541/**
542 * pci_hp_destroy - remove hotplug slot from in-kernel use
543 * @slot: pointer to the &struct hotplug_slot to destroy
544 *
545 * Destroy a PCI slot used by a hotplug driver. Once this has been called,
546 * the driver may no longer invoke hotplug_slot_name() to get the slot's
547 * unique name. The driver no longer needs to handle a ->reset_slot callback
548 * from this point on.
549 *
550 * Returns 0 on success or a negative int on error.
551 */
552void pci_hp_destroy(struct hotplug_slot *slot)
553{
554 struct pci_slot *pci_slot = slot->pci_slot;
555
556 slot->pci_slot = NULL;
480 pci_slot->hotplug = NULL; 557 pci_slot->hotplug = NULL;
481 pci_destroy_slot(pci_slot); 558 pci_destroy_slot(pci_slot);
482 mutex_unlock(&pci_hp_mutex);
483
484 return 0;
485} 559}
486EXPORT_SYMBOL_GPL(pci_hp_deregister); 560EXPORT_SYMBOL_GPL(pci_hp_destroy);
487 561
488/** 562/**
489 * pci_hp_change_slot_info - changes the slot's information structure in the core 563 * pci_hp_change_slot_info - changes the slot's information structure in the core
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 5f892065585e..811cf83f956d 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -21,6 +21,7 @@
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/sched/signal.h> /* signal_pending() */ 22#include <linux/sched/signal.h> /* signal_pending() */
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/rwsem.h>
24#include <linux/workqueue.h> 25#include <linux/workqueue.h>
25 26
26#include "../pcie/portdrv.h" 27#include "../pcie/portdrv.h"
@@ -57,49 +58,111 @@ do { \
57 dev_warn(&ctrl->pcie->device, format, ## arg) 58 dev_warn(&ctrl->pcie->device, format, ## arg)
58 59
59#define SLOT_NAME_SIZE 10 60#define SLOT_NAME_SIZE 10
61
62/**
63 * struct slot - PCIe hotplug slot
64 * @state: current state machine position
65 * @ctrl: pointer to the slot's controller structure
66 * @hotplug_slot: pointer to the structure registered with the PCI hotplug core
67 * @work: work item to turn the slot on or off after 5 seconds in response to
68 * an Attention Button press
69 * @lock: protects reads and writes of @state;
70 * protects scheduling, execution and cancellation of @work
71 */
60struct slot { 72struct slot {
61 u8 state; 73 u8 state;
62 struct controller *ctrl; 74 struct controller *ctrl;
63 struct hotplug_slot *hotplug_slot; 75 struct hotplug_slot *hotplug_slot;
64 struct delayed_work work; /* work for button event */ 76 struct delayed_work work;
65 struct mutex lock; 77 struct mutex lock;
66 struct mutex hotplug_lock;
67 struct workqueue_struct *wq;
68};
69
70struct event_info {
71 u32 event_type;
72 struct slot *p_slot;
73 struct work_struct work;
74}; 78};
75 79
80/**
81 * struct controller - PCIe hotplug controller
82 * @ctrl_lock: serializes writes to the Slot Control register
83 * @pcie: pointer to the controller's PCIe port service device
84 * @reset_lock: prevents access to the Data Link Layer Link Active bit in the
85 * Link Status register and to the Presence Detect State bit in the Slot
86 * Status register during a slot reset which may cause them to flap
87 * @slot: pointer to the controller's slot structure
88 * @queue: wait queue to wake up on reception of a Command Completed event,
89 * used for synchronous writes to the Slot Control register
90 * @slot_cap: cached copy of the Slot Capabilities register
91 * @slot_ctrl: cached copy of the Slot Control register
92 * @poll_thread: thread to poll for slot events if no IRQ is available,
93 * enabled with pciehp_poll_mode module parameter
94 * @cmd_started: jiffies when the Slot Control register was last written;
95 * the next write is allowed 1 second later, absent a Command Completed
96 * interrupt (PCIe r4.0, sec 6.7.3.2)
97 * @cmd_busy: flag set on Slot Control register write, cleared by IRQ handler
98 * on reception of a Command Completed event
99 * @link_active_reporting: cached copy of Data Link Layer Link Active Reporting
100 * Capable bit in Link Capabilities register; if this bit is zero, the
101 * Data Link Layer Link Active bit in the Link Status register will never
102 * be set and the driver is thus confined to wait 1 second before assuming
103 * the link to a hotplugged device is up and accessing it
104 * @notification_enabled: whether the IRQ was requested successfully
105 * @power_fault_detected: whether a power fault was detected by the hardware
106 * that has not yet been cleared by the user
107 * @pending_events: used by the IRQ handler to save events retrieved from the
108 * Slot Status register for later consumption by the IRQ thread
109 * @request_result: result of last user request submitted to the IRQ thread
110 * @requester: wait queue to wake up on completion of user request,
111 * used for synchronous slot enable/disable request via sysfs
112 */
76struct controller { 113struct controller {
77 struct mutex ctrl_lock; /* controller lock */ 114 struct mutex ctrl_lock;
78 struct pcie_device *pcie; /* PCI Express port service */ 115 struct pcie_device *pcie;
116 struct rw_semaphore reset_lock;
79 struct slot *slot; 117 struct slot *slot;
80 wait_queue_head_t queue; /* sleep & wake process */ 118 wait_queue_head_t queue;
81 u32 slot_cap; 119 u32 slot_cap;
82 u16 slot_ctrl; 120 u16 slot_ctrl;
83 struct timer_list poll_timer; 121 struct task_struct *poll_thread;
84 unsigned long cmd_started; /* jiffies */ 122 unsigned long cmd_started; /* jiffies */
85 unsigned int cmd_busy:1; 123 unsigned int cmd_busy:1;
86 unsigned int link_active_reporting:1; 124 unsigned int link_active_reporting:1;
87 unsigned int notification_enabled:1; 125 unsigned int notification_enabled:1;
88 unsigned int power_fault_detected; 126 unsigned int power_fault_detected;
127 atomic_t pending_events;
128 int request_result;
129 wait_queue_head_t requester;
89}; 130};
90 131
91#define INT_PRESENCE_ON 1 132/**
92#define INT_PRESENCE_OFF 2 133 * DOC: Slot state
93#define INT_POWER_FAULT 3 134 *
94#define INT_BUTTON_PRESS 4 135 * @OFF_STATE: slot is powered off, no subordinate devices are enumerated
95#define INT_LINK_UP 5 136 * @BLINKINGON_STATE: slot will be powered on after the 5 second delay,
96#define INT_LINK_DOWN 6 137 * green led is blinking
97 138 * @BLINKINGOFF_STATE: slot will be powered off after the 5 second delay,
98#define STATIC_STATE 0 139 * green led is blinking
140 * @POWERON_STATE: slot is currently powering on
141 * @POWEROFF_STATE: slot is currently powering off
142 * @ON_STATE: slot is powered on, subordinate devices have been enumerated
143 */
144#define OFF_STATE 0
99#define BLINKINGON_STATE 1 145#define BLINKINGON_STATE 1
100#define BLINKINGOFF_STATE 2 146#define BLINKINGOFF_STATE 2
101#define POWERON_STATE 3 147#define POWERON_STATE 3
102#define POWEROFF_STATE 4 148#define POWEROFF_STATE 4
149#define ON_STATE 5
150
151/**
152 * DOC: Flags to request an action from the IRQ thread
153 *
154 * These are stored together with events read from the Slot Status register,
155 * hence must be greater than its 16-bit width.
156 *
157 * %DISABLE_SLOT: Disable the slot in response to a user request via sysfs or
158 * an Attention Button press after the 5 second delay
159 * %RERUN_ISR: Used by the IRQ handler to inform the IRQ thread that the
160 * hotplug port was inaccessible when the interrupt occurred, requiring
161 * that the IRQ handler is rerun by the IRQ thread after it has made the
162 * hotplug port accessible by runtime resuming its parents to D0
163 */
164#define DISABLE_SLOT (1 << 16)
165#define RERUN_ISR (1 << 17)
103 166
104#define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_ABP) 167#define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_ABP)
105#define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_PCP) 168#define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_PCP)
@@ -113,15 +176,17 @@ struct controller {
113 176
114int pciehp_sysfs_enable_slot(struct slot *slot); 177int pciehp_sysfs_enable_slot(struct slot *slot);
115int pciehp_sysfs_disable_slot(struct slot *slot); 178int pciehp_sysfs_disable_slot(struct slot *slot);
116void pciehp_queue_interrupt_event(struct slot *slot, u32 event_type); 179void pciehp_request(struct controller *ctrl, int action);
180void pciehp_handle_button_press(struct slot *slot);
181void pciehp_handle_disable_request(struct slot *slot);
182void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events);
117int pciehp_configure_device(struct slot *p_slot); 183int pciehp_configure_device(struct slot *p_slot);
118int pciehp_unconfigure_device(struct slot *p_slot); 184void pciehp_unconfigure_device(struct slot *p_slot);
119void pciehp_queue_pushbutton_work(struct work_struct *work); 185void pciehp_queue_pushbutton_work(struct work_struct *work);
120struct controller *pcie_init(struct pcie_device *dev); 186struct controller *pcie_init(struct pcie_device *dev);
121int pcie_init_notification(struct controller *ctrl); 187int pcie_init_notification(struct controller *ctrl);
122int pciehp_enable_slot(struct slot *p_slot); 188void pcie_shutdown_notification(struct controller *ctrl);
123int pciehp_disable_slot(struct slot *p_slot); 189void pcie_clear_hotplug_events(struct controller *ctrl);
124void pcie_reenable_notification(struct controller *ctrl);
125int pciehp_power_on_slot(struct slot *slot); 190int pciehp_power_on_slot(struct slot *slot);
126void pciehp_power_off_slot(struct slot *slot); 191void pciehp_power_off_slot(struct slot *slot);
127void pciehp_get_power_status(struct slot *slot, u8 *status); 192void pciehp_get_power_status(struct slot *slot, u8 *status);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 44a6a63802d5..ec48c9433ae5 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -26,11 +26,12 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/time.h> 27#include <linux/time.h>
28 28
29#include "../pci.h"
30
29/* Global variables */ 31/* Global variables */
30bool pciehp_debug; 32bool pciehp_debug;
31bool pciehp_poll_mode; 33bool pciehp_poll_mode;
32int pciehp_poll_time; 34int pciehp_poll_time;
33static bool pciehp_force;
34 35
35/* 36/*
36 * not really modular, but the easiest way to keep compat with existing 37 * not really modular, but the easiest way to keep compat with existing
@@ -39,11 +40,9 @@ static bool pciehp_force;
39module_param(pciehp_debug, bool, 0644); 40module_param(pciehp_debug, bool, 0644);
40module_param(pciehp_poll_mode, bool, 0644); 41module_param(pciehp_poll_mode, bool, 0644);
41module_param(pciehp_poll_time, int, 0644); 42module_param(pciehp_poll_time, int, 0644);
42module_param(pciehp_force, bool, 0644);
43MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 43MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
44MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 44MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
45MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 45MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
46MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
47 46
48#define PCIE_MODULE_NAME "pciehp" 47#define PCIE_MODULE_NAME "pciehp"
49 48
@@ -56,17 +55,6 @@ static int get_latch_status(struct hotplug_slot *slot, u8 *value);
56static int get_adapter_status(struct hotplug_slot *slot, u8 *value); 55static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
57static int reset_slot(struct hotplug_slot *slot, int probe); 56static int reset_slot(struct hotplug_slot *slot, int probe);
58 57
59/**
60 * release_slot - free up the memory used by a slot
61 * @hotplug_slot: slot to free
62 */
63static void release_slot(struct hotplug_slot *hotplug_slot)
64{
65 kfree(hotplug_slot->ops);
66 kfree(hotplug_slot->info);
67 kfree(hotplug_slot);
68}
69
70static int init_slot(struct controller *ctrl) 58static int init_slot(struct controller *ctrl)
71{ 59{
72 struct slot *slot = ctrl->slot; 60 struct slot *slot = ctrl->slot;
@@ -107,15 +95,14 @@ static int init_slot(struct controller *ctrl)
107 /* register this slot with the hotplug pci core */ 95 /* register this slot with the hotplug pci core */
108 hotplug->info = info; 96 hotplug->info = info;
109 hotplug->private = slot; 97 hotplug->private = slot;
110 hotplug->release = &release_slot;
111 hotplug->ops = ops; 98 hotplug->ops = ops;
112 slot->hotplug_slot = hotplug; 99 slot->hotplug_slot = hotplug;
113 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); 100 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl));
114 101
115 retval = pci_hp_register(hotplug, 102 retval = pci_hp_initialize(hotplug,
116 ctrl->pcie->port->subordinate, 0, name); 103 ctrl->pcie->port->subordinate, 0, name);
117 if (retval) 104 if (retval)
118 ctrl_err(ctrl, "pci_hp_register failed: error %d\n", retval); 105 ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval);
119out: 106out:
120 if (retval) { 107 if (retval) {
121 kfree(ops); 108 kfree(ops);
@@ -127,7 +114,12 @@ out:
127 114
128static void cleanup_slot(struct controller *ctrl) 115static void cleanup_slot(struct controller *ctrl)
129{ 116{
130 pci_hp_deregister(ctrl->slot->hotplug_slot); 117 struct hotplug_slot *hotplug_slot = ctrl->slot->hotplug_slot;
118
119 pci_hp_destroy(hotplug_slot);
120 kfree(hotplug_slot->ops);
121 kfree(hotplug_slot->info);
122 kfree(hotplug_slot);
131} 123}
132 124
133/* 125/*
@@ -136,8 +128,11 @@ static void cleanup_slot(struct controller *ctrl)
136static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 128static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
137{ 129{
138 struct slot *slot = hotplug_slot->private; 130 struct slot *slot = hotplug_slot->private;
131 struct pci_dev *pdev = slot->ctrl->pcie->port;
139 132
133 pci_config_pm_runtime_get(pdev);
140 pciehp_set_attention_status(slot, status); 134 pciehp_set_attention_status(slot, status);
135 pci_config_pm_runtime_put(pdev);
141 return 0; 136 return 0;
142} 137}
143 138
@@ -160,8 +155,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
160static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 155static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
161{ 156{
162 struct slot *slot = hotplug_slot->private; 157 struct slot *slot = hotplug_slot->private;
158 struct pci_dev *pdev = slot->ctrl->pcie->port;
163 159
160 pci_config_pm_runtime_get(pdev);
164 pciehp_get_power_status(slot, value); 161 pciehp_get_power_status(slot, value);
162 pci_config_pm_runtime_put(pdev);
165 return 0; 163 return 0;
166} 164}
167 165
@@ -176,16 +174,22 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
176static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 174static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
177{ 175{
178 struct slot *slot = hotplug_slot->private; 176 struct slot *slot = hotplug_slot->private;
177 struct pci_dev *pdev = slot->ctrl->pcie->port;
179 178
179 pci_config_pm_runtime_get(pdev);
180 pciehp_get_latch_status(slot, value); 180 pciehp_get_latch_status(slot, value);
181 pci_config_pm_runtime_put(pdev);
181 return 0; 182 return 0;
182} 183}
183 184
184static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 185static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
185{ 186{
186 struct slot *slot = hotplug_slot->private; 187 struct slot *slot = hotplug_slot->private;
188 struct pci_dev *pdev = slot->ctrl->pcie->port;
187 189
190 pci_config_pm_runtime_get(pdev);
188 pciehp_get_adapter_status(slot, value); 191 pciehp_get_adapter_status(slot, value);
192 pci_config_pm_runtime_put(pdev);
189 return 0; 193 return 0;
190} 194}
191 195
@@ -196,12 +200,40 @@ static int reset_slot(struct hotplug_slot *hotplug_slot, int probe)
196 return pciehp_reset_slot(slot, probe); 200 return pciehp_reset_slot(slot, probe);
197} 201}
198 202
203/**
204 * pciehp_check_presence() - synthesize event if presence has changed
205 *
206 * On probe and resume, an explicit presence check is necessary to bring up an
207 * occupied slot or bring down an unoccupied slot. This can't be triggered by
208 * events in the Slot Status register, they may be stale and are therefore
209 * cleared. Secondly, sending an interrupt for "events that occur while
210 * interrupt generation is disabled [when] interrupt generation is subsequently
211 * enabled" is optional per PCIe r4.0, sec 6.7.3.4.
212 */
213static void pciehp_check_presence(struct controller *ctrl)
214{
215 struct slot *slot = ctrl->slot;
216 u8 occupied;
217
218 down_read(&ctrl->reset_lock);
219 mutex_lock(&slot->lock);
220
221 pciehp_get_adapter_status(slot, &occupied);
222 if ((occupied && (slot->state == OFF_STATE ||
223 slot->state == BLINKINGON_STATE)) ||
224 (!occupied && (slot->state == ON_STATE ||
225 slot->state == BLINKINGOFF_STATE)))
226 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
227
228 mutex_unlock(&slot->lock);
229 up_read(&ctrl->reset_lock);
230}
231
199static int pciehp_probe(struct pcie_device *dev) 232static int pciehp_probe(struct pcie_device *dev)
200{ 233{
201 int rc; 234 int rc;
202 struct controller *ctrl; 235 struct controller *ctrl;
203 struct slot *slot; 236 struct slot *slot;
204 u8 occupied, poweron;
205 237
206 /* If this is not a "hotplug" service, we have no business here. */ 238 /* If this is not a "hotplug" service, we have no business here. */
207 if (dev->service != PCIE_PORT_SERVICE_HP) 239 if (dev->service != PCIE_PORT_SERVICE_HP)
@@ -238,21 +270,20 @@ static int pciehp_probe(struct pcie_device *dev)
238 goto err_out_free_ctrl_slot; 270 goto err_out_free_ctrl_slot;
239 } 271 }
240 272
241 /* Check if slot is occupied */ 273 /* Publish to user space */
242 slot = ctrl->slot; 274 slot = ctrl->slot;
243 pciehp_get_adapter_status(slot, &occupied); 275 rc = pci_hp_add(slot->hotplug_slot);
244 pciehp_get_power_status(slot, &poweron); 276 if (rc) {
245 if (occupied && pciehp_force) { 277 ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc);
246 mutex_lock(&slot->hotplug_lock); 278 goto err_out_shutdown_notification;
247 pciehp_enable_slot(slot);
248 mutex_unlock(&slot->hotplug_lock);
249 } 279 }
250 /* If empty slot's power status is on, turn power off */ 280
251 if (!occupied && poweron && POWER_CTRL(ctrl)) 281 pciehp_check_presence(ctrl);
252 pciehp_power_off_slot(slot);
253 282
254 return 0; 283 return 0;
255 284
285err_out_shutdown_notification:
286 pcie_shutdown_notification(ctrl);
256err_out_free_ctrl_slot: 287err_out_free_ctrl_slot:
257 cleanup_slot(ctrl); 288 cleanup_slot(ctrl);
258err_out_release_ctlr: 289err_out_release_ctlr:
@@ -264,6 +295,8 @@ static void pciehp_remove(struct pcie_device *dev)
264{ 295{
265 struct controller *ctrl = get_service_data(dev); 296 struct controller *ctrl = get_service_data(dev);
266 297
298 pci_hp_del(ctrl->slot->hotplug_slot);
299 pcie_shutdown_notification(ctrl);
267 cleanup_slot(ctrl); 300 cleanup_slot(ctrl);
268 pciehp_release_ctrl(ctrl); 301 pciehp_release_ctrl(ctrl);
269} 302}
@@ -274,27 +307,28 @@ static int pciehp_suspend(struct pcie_device *dev)
274 return 0; 307 return 0;
275} 308}
276 309
277static int pciehp_resume(struct pcie_device *dev) 310static int pciehp_resume_noirq(struct pcie_device *dev)
278{ 311{
279 struct controller *ctrl; 312 struct controller *ctrl = get_service_data(dev);
280 struct slot *slot; 313 struct slot *slot = ctrl->slot;
281 u8 status;
282 314
283 ctrl = get_service_data(dev); 315 /* pci_restore_state() just wrote to the Slot Control register */
316 ctrl->cmd_started = jiffies;
317 ctrl->cmd_busy = true;
284 318
285 /* reinitialize the chipset's event detection logic */ 319 /* clear spurious events from rediscovery of inserted card */
286 pcie_reenable_notification(ctrl); 320 if (slot->state == ON_STATE || slot->state == BLINKINGOFF_STATE)
321 pcie_clear_hotplug_events(ctrl);
287 322
288 slot = ctrl->slot; 323 return 0;
324}
325
326static int pciehp_resume(struct pcie_device *dev)
327{
328 struct controller *ctrl = get_service_data(dev);
329
330 pciehp_check_presence(ctrl);
289 331
290 /* Check if slot is occupied */
291 pciehp_get_adapter_status(slot, &status);
292 mutex_lock(&slot->hotplug_lock);
293 if (status)
294 pciehp_enable_slot(slot);
295 else
296 pciehp_disable_slot(slot);
297 mutex_unlock(&slot->hotplug_lock);
298 return 0; 332 return 0;
299} 333}
300#endif /* PM */ 334#endif /* PM */
@@ -309,6 +343,7 @@ static struct pcie_port_service_driver hpdriver_portdrv = {
309 343
310#ifdef CONFIG_PM 344#ifdef CONFIG_PM
311 .suspend = pciehp_suspend, 345 .suspend = pciehp_suspend,
346 .resume_noirq = pciehp_resume_noirq,
312 .resume = pciehp_resume, 347 .resume = pciehp_resume,
313#endif /* PM */ 348#endif /* PM */
314}; 349};
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index c684faa43387..da7c72372ffc 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -17,28 +17,11 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/pm_runtime.h>
20#include <linux/pci.h> 21#include <linux/pci.h>
21#include "../pci.h" 22#include "../pci.h"
22#include "pciehp.h" 23#include "pciehp.h"
23 24
24static void interrupt_event_handler(struct work_struct *work);
25
26void pciehp_queue_interrupt_event(struct slot *p_slot, u32 event_type)
27{
28 struct event_info *info;
29
30 info = kmalloc(sizeof(*info), GFP_ATOMIC);
31 if (!info) {
32 ctrl_err(p_slot->ctrl, "dropped event %d (ENOMEM)\n", event_type);
33 return;
34 }
35
36 INIT_WORK(&info->work, interrupt_event_handler);
37 info->event_type = event_type;
38 info->p_slot = p_slot;
39 queue_work(p_slot->wq, &info->work);
40}
41
42/* The following routines constitute the bulk of the 25/* The following routines constitute the bulk of the
43 hotplug controller logic 26 hotplug controller logic
44 */ 27 */
@@ -119,14 +102,11 @@ err_exit:
119 * remove_board - Turns off slot and LEDs 102 * remove_board - Turns off slot and LEDs
120 * @p_slot: slot where board is being removed 103 * @p_slot: slot where board is being removed
121 */ 104 */
122static int remove_board(struct slot *p_slot) 105static void remove_board(struct slot *p_slot)
123{ 106{
124 int retval;
125 struct controller *ctrl = p_slot->ctrl; 107 struct controller *ctrl = p_slot->ctrl;
126 108
127 retval = pciehp_unconfigure_device(p_slot); 109 pciehp_unconfigure_device(p_slot);
128 if (retval)
129 return retval;
130 110
131 if (POWER_CTRL(ctrl)) { 111 if (POWER_CTRL(ctrl)) {
132 pciehp_power_off_slot(p_slot); 112 pciehp_power_off_slot(p_slot);
@@ -141,86 +121,30 @@ static int remove_board(struct slot *p_slot)
141 121
142 /* turn off Green LED */ 122 /* turn off Green LED */
143 pciehp_green_led_off(p_slot); 123 pciehp_green_led_off(p_slot);
144 return 0;
145} 124}
146 125
147struct power_work_info { 126static int pciehp_enable_slot(struct slot *slot);
148 struct slot *p_slot; 127static int pciehp_disable_slot(struct slot *slot);
149 struct work_struct work;
150 unsigned int req;
151#define DISABLE_REQ 0
152#define ENABLE_REQ 1
153};
154
155/**
156 * pciehp_power_thread - handle pushbutton events
157 * @work: &struct work_struct describing work to be done
158 *
159 * Scheduled procedure to handle blocking stuff for the pushbuttons.
160 * Handles all pending events and exits.
161 */
162static void pciehp_power_thread(struct work_struct *work)
163{
164 struct power_work_info *info =
165 container_of(work, struct power_work_info, work);
166 struct slot *p_slot = info->p_slot;
167 int ret;
168
169 switch (info->req) {
170 case DISABLE_REQ:
171 mutex_lock(&p_slot->hotplug_lock);
172 pciehp_disable_slot(p_slot);
173 mutex_unlock(&p_slot->hotplug_lock);
174 mutex_lock(&p_slot->lock);
175 p_slot->state = STATIC_STATE;
176 mutex_unlock(&p_slot->lock);
177 break;
178 case ENABLE_REQ:
179 mutex_lock(&p_slot->hotplug_lock);
180 ret = pciehp_enable_slot(p_slot);
181 mutex_unlock(&p_slot->hotplug_lock);
182 if (ret)
183 pciehp_green_led_off(p_slot);
184 mutex_lock(&p_slot->lock);
185 p_slot->state = STATIC_STATE;
186 mutex_unlock(&p_slot->lock);
187 break;
188 default:
189 break;
190 }
191
192 kfree(info);
193}
194 128
195static void pciehp_queue_power_work(struct slot *p_slot, int req) 129void pciehp_request(struct controller *ctrl, int action)
196{ 130{
197 struct power_work_info *info; 131 atomic_or(action, &ctrl->pending_events);
198 132 if (!pciehp_poll_mode)
199 p_slot->state = (req == ENABLE_REQ) ? POWERON_STATE : POWEROFF_STATE; 133 irq_wake_thread(ctrl->pcie->irq, ctrl);
200
201 info = kmalloc(sizeof(*info), GFP_KERNEL);
202 if (!info) {
203 ctrl_err(p_slot->ctrl, "no memory to queue %s request\n",
204 (req == ENABLE_REQ) ? "poweron" : "poweroff");
205 return;
206 }
207 info->p_slot = p_slot;
208 INIT_WORK(&info->work, pciehp_power_thread);
209 info->req = req;
210 queue_work(p_slot->wq, &info->work);
211} 134}
212 135
213void pciehp_queue_pushbutton_work(struct work_struct *work) 136void pciehp_queue_pushbutton_work(struct work_struct *work)
214{ 137{
215 struct slot *p_slot = container_of(work, struct slot, work.work); 138 struct slot *p_slot = container_of(work, struct slot, work.work);
139 struct controller *ctrl = p_slot->ctrl;
216 140
217 mutex_lock(&p_slot->lock); 141 mutex_lock(&p_slot->lock);
218 switch (p_slot->state) { 142 switch (p_slot->state) {
219 case BLINKINGOFF_STATE: 143 case BLINKINGOFF_STATE:
220 pciehp_queue_power_work(p_slot, DISABLE_REQ); 144 pciehp_request(ctrl, DISABLE_SLOT);
221 break; 145 break;
222 case BLINKINGON_STATE: 146 case BLINKINGON_STATE:
223 pciehp_queue_power_work(p_slot, ENABLE_REQ); 147 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
224 break; 148 break;
225 default: 149 default:
226 break; 150 break;
@@ -228,18 +152,15 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
228 mutex_unlock(&p_slot->lock); 152 mutex_unlock(&p_slot->lock);
229} 153}
230 154
231/* 155void pciehp_handle_button_press(struct slot *p_slot)
232 * Note: This function must be called with slot->lock held
233 */
234static void handle_button_press_event(struct slot *p_slot)
235{ 156{
236 struct controller *ctrl = p_slot->ctrl; 157 struct controller *ctrl = p_slot->ctrl;
237 u8 getstatus;
238 158
159 mutex_lock(&p_slot->lock);
239 switch (p_slot->state) { 160 switch (p_slot->state) {
240 case STATIC_STATE: 161 case OFF_STATE:
241 pciehp_get_power_status(p_slot, &getstatus); 162 case ON_STATE:
242 if (getstatus) { 163 if (p_slot->state == ON_STATE) {
243 p_slot->state = BLINKINGOFF_STATE; 164 p_slot->state = BLINKINGOFF_STATE;
244 ctrl_info(ctrl, "Slot(%s): Powering off due to button press\n", 165 ctrl_info(ctrl, "Slot(%s): Powering off due to button press\n",
245 slot_name(p_slot)); 166 slot_name(p_slot));
@@ -251,7 +172,7 @@ static void handle_button_press_event(struct slot *p_slot)
251 /* blink green LED and turn off amber */ 172 /* blink green LED and turn off amber */
252 pciehp_green_led_blink(p_slot); 173 pciehp_green_led_blink(p_slot);
253 pciehp_set_attention_status(p_slot, 0); 174 pciehp_set_attention_status(p_slot, 0);
254 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 175 schedule_delayed_work(&p_slot->work, 5 * HZ);
255 break; 176 break;
256 case BLINKINGOFF_STATE: 177 case BLINKINGOFF_STATE:
257 case BLINKINGON_STATE: 178 case BLINKINGON_STATE:
@@ -262,118 +183,104 @@ static void handle_button_press_event(struct slot *p_slot)
262 */ 183 */
263 ctrl_info(ctrl, "Slot(%s): Button cancel\n", slot_name(p_slot)); 184 ctrl_info(ctrl, "Slot(%s): Button cancel\n", slot_name(p_slot));
264 cancel_delayed_work(&p_slot->work); 185 cancel_delayed_work(&p_slot->work);
265 if (p_slot->state == BLINKINGOFF_STATE) 186 if (p_slot->state == BLINKINGOFF_STATE) {
187 p_slot->state = ON_STATE;
266 pciehp_green_led_on(p_slot); 188 pciehp_green_led_on(p_slot);
267 else 189 } else {
190 p_slot->state = OFF_STATE;
268 pciehp_green_led_off(p_slot); 191 pciehp_green_led_off(p_slot);
192 }
269 pciehp_set_attention_status(p_slot, 0); 193 pciehp_set_attention_status(p_slot, 0);
270 ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n", 194 ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n",
271 slot_name(p_slot)); 195 slot_name(p_slot));
272 p_slot->state = STATIC_STATE;
273 break;
274 case POWEROFF_STATE:
275 case POWERON_STATE:
276 /*
277 * Ignore if the slot is on power-on or power-off state;
278 * this means that the previous attention button action
279 * to hot-add or hot-remove is undergoing
280 */
281 ctrl_info(ctrl, "Slot(%s): Button ignored\n",
282 slot_name(p_slot));
283 break; 196 break;
284 default: 197 default:
285 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n", 198 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
286 slot_name(p_slot), p_slot->state); 199 slot_name(p_slot), p_slot->state);
287 break; 200 break;
288 } 201 }
202 mutex_unlock(&p_slot->lock);
289} 203}
290 204
291/* 205void pciehp_handle_disable_request(struct slot *slot)
292 * Note: This function must be called with slot->lock held
293 */
294static void handle_link_event(struct slot *p_slot, u32 event)
295{ 206{
296 struct controller *ctrl = p_slot->ctrl; 207 struct controller *ctrl = slot->ctrl;
297 208
298 switch (p_slot->state) { 209 mutex_lock(&slot->lock);
210 switch (slot->state) {
299 case BLINKINGON_STATE: 211 case BLINKINGON_STATE:
300 case BLINKINGOFF_STATE: 212 case BLINKINGOFF_STATE:
301 cancel_delayed_work(&p_slot->work); 213 cancel_delayed_work(&slot->work);
302 /* Fall through */
303 case STATIC_STATE:
304 pciehp_queue_power_work(p_slot, event == INT_LINK_UP ?
305 ENABLE_REQ : DISABLE_REQ);
306 break;
307 case POWERON_STATE:
308 if (event == INT_LINK_UP) {
309 ctrl_info(ctrl, "Slot(%s): Link Up event ignored; already powering on\n",
310 slot_name(p_slot));
311 } else {
312 ctrl_info(ctrl, "Slot(%s): Link Down event queued; currently getting powered on\n",
313 slot_name(p_slot));
314 pciehp_queue_power_work(p_slot, DISABLE_REQ);
315 }
316 break;
317 case POWEROFF_STATE:
318 if (event == INT_LINK_UP) {
319 ctrl_info(ctrl, "Slot(%s): Link Up event queued; currently getting powered off\n",
320 slot_name(p_slot));
321 pciehp_queue_power_work(p_slot, ENABLE_REQ);
322 } else {
323 ctrl_info(ctrl, "Slot(%s): Link Down event ignored; already powering off\n",
324 slot_name(p_slot));
325 }
326 break;
327 default:
328 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
329 slot_name(p_slot), p_slot->state);
330 break; 214 break;
331 } 215 }
216 slot->state = POWEROFF_STATE;
217 mutex_unlock(&slot->lock);
218
219 ctrl->request_result = pciehp_disable_slot(slot);
332} 220}
333 221
334static void interrupt_event_handler(struct work_struct *work) 222void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events)
335{ 223{
336 struct event_info *info = container_of(work, struct event_info, work); 224 struct controller *ctrl = slot->ctrl;
337 struct slot *p_slot = info->p_slot; 225 bool link_active;
338 struct controller *ctrl = p_slot->ctrl; 226 u8 present;
339 227
340 mutex_lock(&p_slot->lock); 228 /*
341 switch (info->event_type) { 229 * If the slot is on and presence or link has changed, turn it off.
342 case INT_BUTTON_PRESS: 230 * Even if it's occupied again, we cannot assume the card is the same.
343 handle_button_press_event(p_slot); 231 */
344 break; 232 mutex_lock(&slot->lock);
345 case INT_POWER_FAULT: 233 switch (slot->state) {
346 if (!POWER_CTRL(ctrl)) 234 case BLINKINGOFF_STATE:
347 break; 235 cancel_delayed_work(&slot->work);
348 pciehp_set_attention_status(p_slot, 1); 236 /* fall through */
349 pciehp_green_led_off(p_slot); 237 case ON_STATE:
350 break; 238 slot->state = POWEROFF_STATE;
351 case INT_PRESENCE_ON: 239 mutex_unlock(&slot->lock);
352 pciehp_queue_power_work(p_slot, ENABLE_REQ); 240 if (events & PCI_EXP_SLTSTA_DLLSC)
241 ctrl_info(ctrl, "Slot(%s): Link Down\n",
242 slot_name(slot));
243 if (events & PCI_EXP_SLTSTA_PDC)
244 ctrl_info(ctrl, "Slot(%s): Card not present\n",
245 slot_name(slot));
246 pciehp_disable_slot(slot);
353 break; 247 break;
354 case INT_PRESENCE_OFF: 248 default:
355 /* 249 mutex_unlock(&slot->lock);
356 * Regardless of surprise capability, we need to
357 * definitely remove a card that has been pulled out!
358 */
359 pciehp_queue_power_work(p_slot, DISABLE_REQ);
360 break; 250 break;
361 case INT_LINK_UP: 251 }
362 case INT_LINK_DOWN: 252
363 handle_link_event(p_slot, info->event_type); 253 /* Turn the slot on if it's occupied or link is up */
254 mutex_lock(&slot->lock);
255 pciehp_get_adapter_status(slot, &present);
256 link_active = pciehp_check_link_active(ctrl);
257 if (!present && !link_active) {
258 mutex_unlock(&slot->lock);
259 return;
260 }
261
262 switch (slot->state) {
263 case BLINKINGON_STATE:
264 cancel_delayed_work(&slot->work);
265 /* fall through */
266 case OFF_STATE:
267 slot->state = POWERON_STATE;
268 mutex_unlock(&slot->lock);
269 if (present)
270 ctrl_info(ctrl, "Slot(%s): Card present\n",
271 slot_name(slot));
272 if (link_active)
273 ctrl_info(ctrl, "Slot(%s): Link Up\n",
274 slot_name(slot));
275 ctrl->request_result = pciehp_enable_slot(slot);
364 break; 276 break;
365 default: 277 default:
278 mutex_unlock(&slot->lock);
366 break; 279 break;
367 } 280 }
368 mutex_unlock(&p_slot->lock);
369
370 kfree(info);
371} 281}
372 282
373/* 283static int __pciehp_enable_slot(struct slot *p_slot)
374 * Note: This function must be called with slot->hotplug_lock held
375 */
376int pciehp_enable_slot(struct slot *p_slot)
377{ 284{
378 u8 getstatus = 0; 285 u8 getstatus = 0;
379 struct controller *ctrl = p_slot->ctrl; 286 struct controller *ctrl = p_slot->ctrl;
@@ -404,17 +311,29 @@ int pciehp_enable_slot(struct slot *p_slot)
404 return board_added(p_slot); 311 return board_added(p_slot);
405} 312}
406 313
407/* 314static int pciehp_enable_slot(struct slot *slot)
408 * Note: This function must be called with slot->hotplug_lock held 315{
409 */ 316 struct controller *ctrl = slot->ctrl;
410int pciehp_disable_slot(struct slot *p_slot) 317 int ret;
318
319 pm_runtime_get_sync(&ctrl->pcie->port->dev);
320 ret = __pciehp_enable_slot(slot);
321 if (ret && ATTN_BUTTN(ctrl))
322 pciehp_green_led_off(slot); /* may be blinking */
323 pm_runtime_put(&ctrl->pcie->port->dev);
324
325 mutex_lock(&slot->lock);
326 slot->state = ret ? OFF_STATE : ON_STATE;
327 mutex_unlock(&slot->lock);
328
329 return ret;
330}
331
332static int __pciehp_disable_slot(struct slot *p_slot)
411{ 333{
412 u8 getstatus = 0; 334 u8 getstatus = 0;
413 struct controller *ctrl = p_slot->ctrl; 335 struct controller *ctrl = p_slot->ctrl;
414 336
415 if (!p_slot->ctrl)
416 return 1;
417
418 if (POWER_CTRL(p_slot->ctrl)) { 337 if (POWER_CTRL(p_slot->ctrl)) {
419 pciehp_get_power_status(p_slot, &getstatus); 338 pciehp_get_power_status(p_slot, &getstatus);
420 if (!getstatus) { 339 if (!getstatus) {
@@ -424,32 +343,50 @@ int pciehp_disable_slot(struct slot *p_slot)
424 } 343 }
425 } 344 }
426 345
427 return remove_board(p_slot); 346 remove_board(p_slot);
347 return 0;
348}
349
350static int pciehp_disable_slot(struct slot *slot)
351{
352 struct controller *ctrl = slot->ctrl;
353 int ret;
354
355 pm_runtime_get_sync(&ctrl->pcie->port->dev);
356 ret = __pciehp_disable_slot(slot);
357 pm_runtime_put(&ctrl->pcie->port->dev);
358
359 mutex_lock(&slot->lock);
360 slot->state = OFF_STATE;
361 mutex_unlock(&slot->lock);
362
363 return ret;
428} 364}
429 365
430int pciehp_sysfs_enable_slot(struct slot *p_slot) 366int pciehp_sysfs_enable_slot(struct slot *p_slot)
431{ 367{
432 int retval = -ENODEV;
433 struct controller *ctrl = p_slot->ctrl; 368 struct controller *ctrl = p_slot->ctrl;
434 369
435 mutex_lock(&p_slot->lock); 370 mutex_lock(&p_slot->lock);
436 switch (p_slot->state) { 371 switch (p_slot->state) {
437 case BLINKINGON_STATE: 372 case BLINKINGON_STATE:
438 cancel_delayed_work(&p_slot->work); 373 case OFF_STATE:
439 case STATIC_STATE:
440 p_slot->state = POWERON_STATE;
441 mutex_unlock(&p_slot->lock); 374 mutex_unlock(&p_slot->lock);
442 mutex_lock(&p_slot->hotplug_lock); 375 /*
443 retval = pciehp_enable_slot(p_slot); 376 * The IRQ thread becomes a no-op if the user pulls out the
444 mutex_unlock(&p_slot->hotplug_lock); 377 * card before the thread wakes up, so initialize to -ENODEV.
445 mutex_lock(&p_slot->lock); 378 */
446 p_slot->state = STATIC_STATE; 379 ctrl->request_result = -ENODEV;
447 break; 380 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC);
381 wait_event(ctrl->requester,
382 !atomic_read(&ctrl->pending_events));
383 return ctrl->request_result;
448 case POWERON_STATE: 384 case POWERON_STATE:
449 ctrl_info(ctrl, "Slot(%s): Already in powering on state\n", 385 ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
450 slot_name(p_slot)); 386 slot_name(p_slot));
451 break; 387 break;
452 case BLINKINGOFF_STATE: 388 case BLINKINGOFF_STATE:
389 case ON_STATE:
453 case POWEROFF_STATE: 390 case POWEROFF_STATE:
454 ctrl_info(ctrl, "Slot(%s): Already enabled\n", 391 ctrl_info(ctrl, "Slot(%s): Already enabled\n",
455 slot_name(p_slot)); 392 slot_name(p_slot));
@@ -461,32 +398,28 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
461 } 398 }
462 mutex_unlock(&p_slot->lock); 399 mutex_unlock(&p_slot->lock);
463 400
464 return retval; 401 return -ENODEV;
465} 402}
466 403
467int pciehp_sysfs_disable_slot(struct slot *p_slot) 404int pciehp_sysfs_disable_slot(struct slot *p_slot)
468{ 405{
469 int retval = -ENODEV;
470 struct controller *ctrl = p_slot->ctrl; 406 struct controller *ctrl = p_slot->ctrl;
471 407
472 mutex_lock(&p_slot->lock); 408 mutex_lock(&p_slot->lock);
473 switch (p_slot->state) { 409 switch (p_slot->state) {
474 case BLINKINGOFF_STATE: 410 case BLINKINGOFF_STATE:
475 cancel_delayed_work(&p_slot->work); 411 case ON_STATE:
476 case STATIC_STATE:
477 p_slot->state = POWEROFF_STATE;
478 mutex_unlock(&p_slot->lock); 412 mutex_unlock(&p_slot->lock);
479 mutex_lock(&p_slot->hotplug_lock); 413 pciehp_request(ctrl, DISABLE_SLOT);
480 retval = pciehp_disable_slot(p_slot); 414 wait_event(ctrl->requester,
481 mutex_unlock(&p_slot->hotplug_lock); 415 !atomic_read(&ctrl->pending_events));
482 mutex_lock(&p_slot->lock); 416 return ctrl->request_result;
483 p_slot->state = STATIC_STATE;
484 break;
485 case POWEROFF_STATE: 417 case POWEROFF_STATE:
486 ctrl_info(ctrl, "Slot(%s): Already in powering off state\n", 418 ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
487 slot_name(p_slot)); 419 slot_name(p_slot));
488 break; 420 break;
489 case BLINKINGON_STATE: 421 case BLINKINGON_STATE:
422 case OFF_STATE:
490 case POWERON_STATE: 423 case POWERON_STATE:
491 ctrl_info(ctrl, "Slot(%s): Already disabled\n", 424 ctrl_info(ctrl, "Slot(%s): Already disabled\n",
492 slot_name(p_slot)); 425 slot_name(p_slot));
@@ -498,5 +431,5 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
498 } 431 }
499 mutex_unlock(&p_slot->lock); 432 mutex_unlock(&p_slot->lock);
500 433
501 return retval; 434 return -ENODEV;
502} 435}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 718b6073afad..5b15e76f3564 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -17,8 +17,9 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/signal.h> 18#include <linux/signal.h>
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/timer.h> 20#include <linux/kthread.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/pm_runtime.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/time.h> 24#include <linux/time.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -31,47 +32,24 @@ static inline struct pci_dev *ctrl_dev(struct controller *ctrl)
31 return ctrl->pcie->port; 32 return ctrl->pcie->port;
32} 33}
33 34
34static irqreturn_t pcie_isr(int irq, void *dev_id); 35static irqreturn_t pciehp_isr(int irq, void *dev_id);
35static void start_int_poll_timer(struct controller *ctrl, int sec); 36static irqreturn_t pciehp_ist(int irq, void *dev_id);
36 37static int pciehp_poll(void *data);
37/* This is the interrupt polling timeout function. */
38static void int_poll_timeout(struct timer_list *t)
39{
40 struct controller *ctrl = from_timer(ctrl, t, poll_timer);
41
42 /* Poll for interrupt events. regs == NULL => polling */
43 pcie_isr(0, ctrl);
44
45 if (!pciehp_poll_time)
46 pciehp_poll_time = 2; /* default polling interval is 2 sec */
47
48 start_int_poll_timer(ctrl, pciehp_poll_time);
49}
50
51/* This function starts the interrupt polling timer. */
52static void start_int_poll_timer(struct controller *ctrl, int sec)
53{
54 /* Clamp to sane value */
55 if ((sec <= 0) || (sec > 60))
56 sec = 2;
57
58 ctrl->poll_timer.expires = jiffies + sec * HZ;
59 add_timer(&ctrl->poll_timer);
60}
61 38
62static inline int pciehp_request_irq(struct controller *ctrl) 39static inline int pciehp_request_irq(struct controller *ctrl)
63{ 40{
64 int retval, irq = ctrl->pcie->irq; 41 int retval, irq = ctrl->pcie->irq;
65 42
66 /* Install interrupt polling timer. Start with 10 sec delay */
67 if (pciehp_poll_mode) { 43 if (pciehp_poll_mode) {
68 timer_setup(&ctrl->poll_timer, int_poll_timeout, 0); 44 ctrl->poll_thread = kthread_run(&pciehp_poll, ctrl,
69 start_int_poll_timer(ctrl, 10); 45 "pciehp_poll-%s",
70 return 0; 46 slot_name(ctrl->slot));
47 return PTR_ERR_OR_ZERO(ctrl->poll_thread);
71 } 48 }
72 49
73 /* Installs the interrupt handler */ 50 /* Installs the interrupt handler */
74 retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl); 51 retval = request_threaded_irq(irq, pciehp_isr, pciehp_ist,
52 IRQF_SHARED, MY_NAME, ctrl);
75 if (retval) 53 if (retval)
76 ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n", 54 ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n",
77 irq); 55 irq);
@@ -81,7 +59,7 @@ static inline int pciehp_request_irq(struct controller *ctrl)
81static inline void pciehp_free_irq(struct controller *ctrl) 59static inline void pciehp_free_irq(struct controller *ctrl)
82{ 60{
83 if (pciehp_poll_mode) 61 if (pciehp_poll_mode)
84 del_timer_sync(&ctrl->poll_timer); 62 kthread_stop(ctrl->poll_thread);
85 else 63 else
86 free_irq(ctrl->pcie->irq, ctrl); 64 free_irq(ctrl->pcie->irq, ctrl);
87} 65}
@@ -293,6 +271,11 @@ int pciehp_check_link_status(struct controller *ctrl)
293 found = pci_bus_check_dev(ctrl->pcie->port->subordinate, 271 found = pci_bus_check_dev(ctrl->pcie->port->subordinate,
294 PCI_DEVFN(0, 0)); 272 PCI_DEVFN(0, 0));
295 273
274 /* ignore link or presence changes up to this point */
275 if (found)
276 atomic_and(~(PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC),
277 &ctrl->pending_events);
278
296 pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); 279 pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
297 ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); 280 ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
298 if ((lnk_status & PCI_EXP_LNKSTA_LT) || 281 if ((lnk_status & PCI_EXP_LNKSTA_LT) ||
@@ -339,7 +322,9 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot,
339 struct pci_dev *pdev = ctrl_dev(slot->ctrl); 322 struct pci_dev *pdev = ctrl_dev(slot->ctrl);
340 u16 slot_ctrl; 323 u16 slot_ctrl;
341 324
325 pci_config_pm_runtime_get(pdev);
342 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); 326 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
327 pci_config_pm_runtime_put(pdev);
343 *status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6; 328 *status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6;
344 return 0; 329 return 0;
345} 330}
@@ -350,7 +335,9 @@ void pciehp_get_attention_status(struct slot *slot, u8 *status)
350 struct pci_dev *pdev = ctrl_dev(ctrl); 335 struct pci_dev *pdev = ctrl_dev(ctrl);
351 u16 slot_ctrl; 336 u16 slot_ctrl;
352 337
338 pci_config_pm_runtime_get(pdev);
353 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); 339 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
340 pci_config_pm_runtime_put(pdev);
354 ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, 341 ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
355 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); 342 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
356 343
@@ -425,9 +412,12 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
425{ 412{
426 struct slot *slot = hotplug_slot->private; 413 struct slot *slot = hotplug_slot->private;
427 struct controller *ctrl = slot->ctrl; 414 struct controller *ctrl = slot->ctrl;
415 struct pci_dev *pdev = ctrl_dev(ctrl);
428 416
417 pci_config_pm_runtime_get(pdev);
429 pcie_write_cmd_nowait(ctrl, status << 6, 418 pcie_write_cmd_nowait(ctrl, status << 6,
430 PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC); 419 PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC);
420 pci_config_pm_runtime_put(pdev);
431 return 0; 421 return 0;
432} 422}
433 423
@@ -539,20 +529,35 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
539{ 529{
540 struct controller *ctrl = (struct controller *)dev_id; 530 struct controller *ctrl = (struct controller *)dev_id;
541 struct pci_dev *pdev = ctrl_dev(ctrl); 531 struct pci_dev *pdev = ctrl_dev(ctrl);
542 struct pci_bus *subordinate = pdev->subordinate; 532 struct device *parent = pdev->dev.parent;
543 struct pci_dev *dev;
544 struct slot *slot = ctrl->slot;
545 u16 status, events; 533 u16 status, events;
546 u8 present;
547 bool link;
548 534
549 /* Interrupts cannot originate from a controller that's asleep */ 535 /*
536 * Interrupts only occur in D3hot or shallower (PCIe r4.0, sec 6.7.3.4).
537 */
550 if (pdev->current_state == PCI_D3cold) 538 if (pdev->current_state == PCI_D3cold)
551 return IRQ_NONE; 539 return IRQ_NONE;
552 540
541 /*
542 * Keep the port accessible by holding a runtime PM ref on its parent.
543 * Defer resume of the parent to the IRQ thread if it's suspended.
544 * Mask the interrupt until then.
545 */
546 if (parent) {
547 pm_runtime_get_noresume(parent);
548 if (!pm_runtime_active(parent)) {
549 pm_runtime_put(parent);
550 disable_irq_nosync(irq);
551 atomic_or(RERUN_ISR, &ctrl->pending_events);
552 return IRQ_WAKE_THREAD;
553 }
554 }
555
553 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); 556 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status);
554 if (status == (u16) ~0) { 557 if (status == (u16) ~0) {
555 ctrl_info(ctrl, "%s: no response from device\n", __func__); 558 ctrl_info(ctrl, "%s: no response from device\n", __func__);
559 if (parent)
560 pm_runtime_put(parent);
556 return IRQ_NONE; 561 return IRQ_NONE;
557 } 562 }
558 563
@@ -571,86 +576,119 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
571 if (ctrl->power_fault_detected) 576 if (ctrl->power_fault_detected)
572 events &= ~PCI_EXP_SLTSTA_PFD; 577 events &= ~PCI_EXP_SLTSTA_PFD;
573 578
574 if (!events) 579 if (!events) {
580 if (parent)
581 pm_runtime_put(parent);
575 return IRQ_NONE; 582 return IRQ_NONE;
576 583 }
577 /* Capture link status before clearing interrupts */
578 if (events & PCI_EXP_SLTSTA_DLLSC)
579 link = pciehp_check_link_active(ctrl);
580 584
581 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); 585 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events);
582 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); 586 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events);
587 if (parent)
588 pm_runtime_put(parent);
583 589
584 /* Check Command Complete Interrupt Pending */ 590 /*
591 * Command Completed notifications are not deferred to the
592 * IRQ thread because it may be waiting for their arrival.
593 */
585 if (events & PCI_EXP_SLTSTA_CC) { 594 if (events & PCI_EXP_SLTSTA_CC) {
586 ctrl->cmd_busy = 0; 595 ctrl->cmd_busy = 0;
587 smp_mb(); 596 smp_mb();
588 wake_up(&ctrl->queue); 597 wake_up(&ctrl->queue);
598
599 if (events == PCI_EXP_SLTSTA_CC)
600 return IRQ_HANDLED;
601
602 events &= ~PCI_EXP_SLTSTA_CC;
603 }
604
605 if (pdev->ignore_hotplug) {
606 ctrl_dbg(ctrl, "ignoring hotplug event %#06x\n", events);
607 return IRQ_HANDLED;
589 } 608 }
590 609
591 if (subordinate) { 610 /* Save pending events for consumption by IRQ thread. */
592 list_for_each_entry(dev, &subordinate->devices, bus_list) { 611 atomic_or(events, &ctrl->pending_events);
593 if (dev->ignore_hotplug) { 612 return IRQ_WAKE_THREAD;
594 ctrl_dbg(ctrl, "ignoring hotplug event %#06x (%s requested no hotplug)\n", 613}
595 events, pci_name(dev)); 614
596 return IRQ_HANDLED; 615static irqreturn_t pciehp_ist(int irq, void *dev_id)
597 } 616{
617 struct controller *ctrl = (struct controller *)dev_id;
618 struct pci_dev *pdev = ctrl_dev(ctrl);
619 struct slot *slot = ctrl->slot;
620 irqreturn_t ret;
621 u32 events;
622
623 pci_config_pm_runtime_get(pdev);
624
625 /* rerun pciehp_isr() if the port was inaccessible on interrupt */
626 if (atomic_fetch_and(~RERUN_ISR, &ctrl->pending_events) & RERUN_ISR) {
627 ret = pciehp_isr(irq, dev_id);
628 enable_irq(irq);
629 if (ret != IRQ_WAKE_THREAD) {
630 pci_config_pm_runtime_put(pdev);
631 return ret;
598 } 632 }
599 } 633 }
600 634
635 synchronize_hardirq(irq);
636 events = atomic_xchg(&ctrl->pending_events, 0);
637 if (!events) {
638 pci_config_pm_runtime_put(pdev);
639 return IRQ_NONE;
640 }
641
601 /* Check Attention Button Pressed */ 642 /* Check Attention Button Pressed */
602 if (events & PCI_EXP_SLTSTA_ABP) { 643 if (events & PCI_EXP_SLTSTA_ABP) {
603 ctrl_info(ctrl, "Slot(%s): Attention button pressed\n", 644 ctrl_info(ctrl, "Slot(%s): Attention button pressed\n",
604 slot_name(slot)); 645 slot_name(slot));
605 pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS); 646 pciehp_handle_button_press(slot);
606 } 647 }
607 648
608 /* 649 /*
609 * Check Link Status Changed at higher precedence than Presence 650 * Disable requests have higher priority than Presence Detect Changed
610 * Detect Changed. The PDS value may be set to "card present" from 651 * or Data Link Layer State Changed events.
611 * out-of-band detection, which may be in conflict with a Link Down
612 * and cause the wrong event to queue.
613 */ 652 */
614 if (events & PCI_EXP_SLTSTA_DLLSC) { 653 down_read(&ctrl->reset_lock);
615 ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot), 654 if (events & DISABLE_SLOT)
616 link ? "Up" : "Down"); 655 pciehp_handle_disable_request(slot);
617 pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : 656 else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC))
618 INT_LINK_DOWN); 657 pciehp_handle_presence_or_link_change(slot, events);
619 } else if (events & PCI_EXP_SLTSTA_PDC) { 658 up_read(&ctrl->reset_lock);
620 present = !!(status & PCI_EXP_SLTSTA_PDS);
621 ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot),
622 present ? "" : "not ");
623 pciehp_queue_interrupt_event(slot, present ? INT_PRESENCE_ON :
624 INT_PRESENCE_OFF);
625 }
626 659
627 /* Check Power Fault Detected */ 660 /* Check Power Fault Detected */
628 if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { 661 if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
629 ctrl->power_fault_detected = 1; 662 ctrl->power_fault_detected = 1;
630 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot)); 663 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
631 pciehp_queue_interrupt_event(slot, INT_POWER_FAULT); 664 pciehp_set_attention_status(slot, 1);
665 pciehp_green_led_off(slot);
632 } 666 }
633 667
668 pci_config_pm_runtime_put(pdev);
669 wake_up(&ctrl->requester);
634 return IRQ_HANDLED; 670 return IRQ_HANDLED;
635} 671}
636 672
637static irqreturn_t pcie_isr(int irq, void *dev_id) 673static int pciehp_poll(void *data)
638{ 674{
639 irqreturn_t rc, handled = IRQ_NONE; 675 struct controller *ctrl = data;
640 676
641 /* 677 schedule_timeout_idle(10 * HZ); /* start with 10 sec delay */
642 * To guarantee that all interrupt events are serviced, we need to 678
643 * re-inspect Slot Status register after clearing what is presumed 679 while (!kthread_should_stop()) {
644 * to be the last pending interrupt. 680 /* poll for interrupt events or user requests */
645 */ 681 while (pciehp_isr(IRQ_NOTCONNECTED, ctrl) == IRQ_WAKE_THREAD ||
646 do { 682 atomic_read(&ctrl->pending_events))
647 rc = pciehp_isr(irq, dev_id); 683 pciehp_ist(IRQ_NOTCONNECTED, ctrl);
648 if (rc == IRQ_HANDLED) 684
649 handled = IRQ_HANDLED; 685 if (pciehp_poll_time <= 0 || pciehp_poll_time > 60)
650 } while (rc == IRQ_HANDLED); 686 pciehp_poll_time = 2; /* clamp to sane value */
687
688 schedule_timeout_idle(pciehp_poll_time * HZ);
689 }
651 690
652 /* Return IRQ_HANDLED if we handled one or more events */ 691 return 0;
653 return handled;
654} 692}
655 693
656static void pcie_enable_notification(struct controller *ctrl) 694static void pcie_enable_notification(struct controller *ctrl)
@@ -691,17 +729,6 @@ static void pcie_enable_notification(struct controller *ctrl)
691 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); 729 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
692} 730}
693 731
694void pcie_reenable_notification(struct controller *ctrl)
695{
696 /*
697 * Clear both Presence and Data Link Layer Changed to make sure
698 * those events still fire after we have re-enabled them.
699 */
700 pcie_capability_write_word(ctrl->pcie->port, PCI_EXP_SLTSTA,
701 PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
702 pcie_enable_notification(ctrl);
703}
704
705static void pcie_disable_notification(struct controller *ctrl) 732static void pcie_disable_notification(struct controller *ctrl)
706{ 733{
707 u16 mask; 734 u16 mask;
@@ -715,6 +742,12 @@ static void pcie_disable_notification(struct controller *ctrl)
715 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); 742 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0);
716} 743}
717 744
745void pcie_clear_hotplug_events(struct controller *ctrl)
746{
747 pcie_capability_write_word(ctrl_dev(ctrl), PCI_EXP_SLTSTA,
748 PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
749}
750
718/* 751/*
719 * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary 752 * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary
720 * bus reset of the bridge, but at the same time we want to ensure that it is 753 * bus reset of the bridge, but at the same time we want to ensure that it is
@@ -732,6 +765,8 @@ int pciehp_reset_slot(struct slot *slot, int probe)
732 if (probe) 765 if (probe)
733 return 0; 766 return 0;
734 767
768 down_write(&ctrl->reset_lock);
769
735 if (!ATTN_BUTTN(ctrl)) { 770 if (!ATTN_BUTTN(ctrl)) {
736 ctrl_mask |= PCI_EXP_SLTCTL_PDCE; 771 ctrl_mask |= PCI_EXP_SLTCTL_PDCE;
737 stat_mask |= PCI_EXP_SLTSTA_PDC; 772 stat_mask |= PCI_EXP_SLTSTA_PDC;
@@ -742,8 +777,6 @@ int pciehp_reset_slot(struct slot *slot, int probe)
742 pcie_write_cmd(ctrl, 0, ctrl_mask); 777 pcie_write_cmd(ctrl, 0, ctrl_mask);
743 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, 778 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
744 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); 779 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0);
745 if (pciehp_poll_mode)
746 del_timer_sync(&ctrl->poll_timer);
747 780
748 pci_reset_bridge_secondary_bus(ctrl->pcie->port); 781 pci_reset_bridge_secondary_bus(ctrl->pcie->port);
749 782
@@ -751,8 +784,8 @@ int pciehp_reset_slot(struct slot *slot, int probe)
751 pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask); 784 pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask);
752 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, 785 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
753 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); 786 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask);
754 if (pciehp_poll_mode) 787
755 int_poll_timeout(&ctrl->poll_timer); 788 up_write(&ctrl->reset_lock);
756 return 0; 789 return 0;
757} 790}
758 791
@@ -765,7 +798,7 @@ int pcie_init_notification(struct controller *ctrl)
765 return 0; 798 return 0;
766} 799}
767 800
768static void pcie_shutdown_notification(struct controller *ctrl) 801void pcie_shutdown_notification(struct controller *ctrl)
769{ 802{
770 if (ctrl->notification_enabled) { 803 if (ctrl->notification_enabled) {
771 pcie_disable_notification(ctrl); 804 pcie_disable_notification(ctrl);
@@ -776,32 +809,29 @@ static void pcie_shutdown_notification(struct controller *ctrl)
776 809
777static int pcie_init_slot(struct controller *ctrl) 810static int pcie_init_slot(struct controller *ctrl)
778{ 811{
812 struct pci_bus *subordinate = ctrl_dev(ctrl)->subordinate;
779 struct slot *slot; 813 struct slot *slot;
780 814
781 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 815 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
782 if (!slot) 816 if (!slot)
783 return -ENOMEM; 817 return -ENOMEM;
784 818
785 slot->wq = alloc_ordered_workqueue("pciehp-%u", 0, PSN(ctrl)); 819 down_read(&pci_bus_sem);
786 if (!slot->wq) 820 slot->state = list_empty(&subordinate->devices) ? OFF_STATE : ON_STATE;
787 goto abort; 821 up_read(&pci_bus_sem);
788 822
789 slot->ctrl = ctrl; 823 slot->ctrl = ctrl;
790 mutex_init(&slot->lock); 824 mutex_init(&slot->lock);
791 mutex_init(&slot->hotplug_lock);
792 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); 825 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
793 ctrl->slot = slot; 826 ctrl->slot = slot;
794 return 0; 827 return 0;
795abort:
796 kfree(slot);
797 return -ENOMEM;
798} 828}
799 829
800static void pcie_cleanup_slot(struct controller *ctrl) 830static void pcie_cleanup_slot(struct controller *ctrl)
801{ 831{
802 struct slot *slot = ctrl->slot; 832 struct slot *slot = ctrl->slot;
803 cancel_delayed_work(&slot->work); 833
804 destroy_workqueue(slot->wq); 834 cancel_delayed_work_sync(&slot->work);
805 kfree(slot); 835 kfree(slot);
806} 836}
807 837
@@ -826,6 +856,7 @@ struct controller *pcie_init(struct pcie_device *dev)
826{ 856{
827 struct controller *ctrl; 857 struct controller *ctrl;
828 u32 slot_cap, link_cap; 858 u32 slot_cap, link_cap;
859 u8 occupied, poweron;
829 struct pci_dev *pdev = dev->port; 860 struct pci_dev *pdev = dev->port;
830 861
831 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); 862 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
@@ -847,6 +878,8 @@ struct controller *pcie_init(struct pcie_device *dev)
847 878
848 ctrl->slot_cap = slot_cap; 879 ctrl->slot_cap = slot_cap;
849 mutex_init(&ctrl->ctrl_lock); 880 mutex_init(&ctrl->ctrl_lock);
881 init_rwsem(&ctrl->reset_lock);
882 init_waitqueue_head(&ctrl->requester);
850 init_waitqueue_head(&ctrl->queue); 883 init_waitqueue_head(&ctrl->queue);
851 dbg_ctrl(ctrl); 884 dbg_ctrl(ctrl);
852 885
@@ -855,16 +888,11 @@ struct controller *pcie_init(struct pcie_device *dev)
855 if (link_cap & PCI_EXP_LNKCAP_DLLLARC) 888 if (link_cap & PCI_EXP_LNKCAP_DLLLARC)
856 ctrl->link_active_reporting = 1; 889 ctrl->link_active_reporting = 1;
857 890
858 /* 891 /* Clear all remaining event bits in Slot Status register. */
859 * Clear all remaining event bits in Slot Status register except
860 * Presence Detect Changed. We want to make sure possible
861 * hotplug event is triggered when the interrupt is unmasked so
862 * that we don't lose that event.
863 */
864 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, 892 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
865 PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | 893 PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
866 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_CC | 894 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_CC |
867 PCI_EXP_SLTSTA_DLLSC); 895 PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC);
868 896
869 ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c Interlock%c NoCompl%c LLActRep%c%s\n", 897 ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c Interlock%c NoCompl%c LLActRep%c%s\n",
870 (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, 898 (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19,
@@ -883,6 +911,19 @@ struct controller *pcie_init(struct pcie_device *dev)
883 if (pcie_init_slot(ctrl)) 911 if (pcie_init_slot(ctrl))
884 goto abort_ctrl; 912 goto abort_ctrl;
885 913
914 /*
915 * If empty slot's power status is on, turn power off. The IRQ isn't
916 * requested yet, so avoid triggering a notification with this command.
917 */
918 if (POWER_CTRL(ctrl)) {
919 pciehp_get_adapter_status(ctrl->slot, &occupied);
920 pciehp_get_power_status(ctrl->slot, &poweron);
921 if (!occupied && poweron) {
922 pcie_disable_notification(ctrl);
923 pciehp_power_off_slot(ctrl->slot);
924 }
925 }
926
886 return ctrl; 927 return ctrl;
887 928
888abort_ctrl: 929abort_ctrl:
@@ -893,7 +934,6 @@ abort:
893 934
894void pciehp_release_ctrl(struct controller *ctrl) 935void pciehp_release_ctrl(struct controller *ctrl)
895{ 936{
896 pcie_shutdown_notification(ctrl);
897 pcie_cleanup_slot(ctrl); 937 pcie_cleanup_slot(ctrl);
898 kfree(ctrl); 938 kfree(ctrl);
899} 939}
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 3f518dea856d..5c58c22e0c08 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -62,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot)
62 return ret; 62 return ret;
63} 63}
64 64
65int pciehp_unconfigure_device(struct slot *p_slot) 65void pciehp_unconfigure_device(struct slot *p_slot)
66{ 66{
67 int rc = 0;
68 u8 presence = 0; 67 u8 presence = 0;
69 struct pci_dev *dev, *temp; 68 struct pci_dev *dev, *temp;
70 struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; 69 struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
@@ -107,5 +106,4 @@ int pciehp_unconfigure_device(struct slot *p_slot)
107 } 106 }
108 107
109 pci_unlock_rescan_remove(); 108 pci_unlock_rescan_remove();
110 return rc;
111} 109}
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
deleted file mode 100644
index c19694a04d2c..000000000000
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ /dev/null
@@ -1,348 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PCI Hot Plug Controller Skeleton Driver - 0.3
4 *
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001,2003 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This driver is to be used as a skeleton driver to show how to interface
11 * with the pci hotplug core easily.
12 *
13 * Send feedback to <greg@kroah.com>
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/pci.h>
22#include <linux/pci_hotplug.h>
23#include <linux/init.h>
24
25#define SLOT_NAME_SIZE 10
26struct slot {
27 u8 number;
28 struct hotplug_slot *hotplug_slot;
29 struct list_head slot_list;
30 char name[SLOT_NAME_SIZE];
31};
32
33static LIST_HEAD(slot_list);
34
35#define MY_NAME "pcihp_skeleton"
36
37#define dbg(format, arg...) \
38 do { \
39 if (debug) \
40 printk(KERN_DEBUG "%s: " format "\n", \
41 MY_NAME, ## arg); \
42 } while (0)
43#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
44#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
45#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
46
47/* local variables */
48static bool debug;
49static int num_slots;
50
51#define DRIVER_VERSION "0.3"
52#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
53#define DRIVER_DESC "Hot Plug PCI Controller Skeleton Driver"
54
55MODULE_AUTHOR(DRIVER_AUTHOR);
56MODULE_DESCRIPTION(DRIVER_DESC);
57MODULE_LICENSE("GPL");
58module_param(debug, bool, 0644);
59MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
60
61static int enable_slot(struct hotplug_slot *slot);
62static int disable_slot(struct hotplug_slot *slot);
63static int set_attention_status(struct hotplug_slot *slot, u8 value);
64static int hardware_test(struct hotplug_slot *slot, u32 value);
65static int get_power_status(struct hotplug_slot *slot, u8 *value);
66static int get_attention_status(struct hotplug_slot *slot, u8 *value);
67static int get_latch_status(struct hotplug_slot *slot, u8 *value);
68static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
69
70static struct hotplug_slot_ops skel_hotplug_slot_ops = {
71 .enable_slot = enable_slot,
72 .disable_slot = disable_slot,
73 .set_attention_status = set_attention_status,
74 .hardware_test = hardware_test,
75 .get_power_status = get_power_status,
76 .get_attention_status = get_attention_status,
77 .get_latch_status = get_latch_status,
78 .get_adapter_status = get_adapter_status,
79};
80
81static int enable_slot(struct hotplug_slot *hotplug_slot)
82{
83 struct slot *slot = hotplug_slot->private;
84 int retval = 0;
85
86 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
87
88 /*
89 * Fill in code here to enable the specified slot
90 */
91
92 return retval;
93}
94
95static int disable_slot(struct hotplug_slot *hotplug_slot)
96{
97 struct slot *slot = hotplug_slot->private;
98 int retval = 0;
99
100 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
101
102 /*
103 * Fill in code here to disable the specified slot
104 */
105
106 return retval;
107}
108
109static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
110{
111 struct slot *slot = hotplug_slot->private;
112 int retval = 0;
113
114 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
115
116 switch (status) {
117 case 0:
118 /*
119 * Fill in code here to turn light off
120 */
121 break;
122
123 case 1:
124 default:
125 /*
126 * Fill in code here to turn light on
127 */
128 break;
129 }
130
131 return retval;
132}
133
134static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
135{
136 struct slot *slot = hotplug_slot->private;
137 int retval = 0;
138
139 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
140
141 switch (value) {
142 case 0:
143 /* Specify a test here */
144 break;
145 case 1:
146 /* Specify another test here */
147 break;
148 }
149
150 return retval;
151}
152
153static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
154{
155 struct slot *slot = hotplug_slot->private;
156 int retval = 0;
157
158 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
159
160 /*
161 * Fill in logic to get the current power status of the specific
162 * slot and store it in the *value location.
163 */
164
165 return retval;
166}
167
168static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
169{
170 struct slot *slot = hotplug_slot->private;
171 int retval = 0;
172
173 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
174
175 /*
176 * Fill in logic to get the current attention status of the specific
177 * slot and store it in the *value location.
178 */
179
180 return retval;
181}
182
183static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
184{
185 struct slot *slot = hotplug_slot->private;
186 int retval = 0;
187
188 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
189
190 /*
191 * Fill in logic to get the current latch status of the specific
192 * slot and store it in the *value location.
193 */
194
195 return retval;
196}
197
198static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
199{
200 struct slot *slot = hotplug_slot->private;
201 int retval = 0;
202
203 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
204
205 /*
206 * Fill in logic to get the current adapter status of the specific
207 * slot and store it in the *value location.
208 */
209
210 return retval;
211}
212
213static void release_slot(struct hotplug_slot *hotplug_slot)
214{
215 struct slot *slot = hotplug_slot->private;
216
217 dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
218 kfree(slot->hotplug_slot->info);
219 kfree(slot->hotplug_slot);
220 kfree(slot);
221}
222
223static void make_slot_name(struct slot *slot)
224{
225 /*
226 * Stupid way to make a filename out of the slot name.
227 * replace this if your hardware provides a better way to name slots.
228 */
229 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d", slot->number);
230}
231
232/**
233 * init_slots - initialize 'struct slot' structures for each slot
234 *
235 */
236static int __init init_slots(void)
237{
238 struct slot *slot;
239 struct hotplug_slot *hotplug_slot;
240 struct hotplug_slot_info *info;
241 int retval;
242 int i;
243
244 /*
245 * Create a structure for each slot, and register that slot
246 * with the pci_hotplug subsystem.
247 */
248 for (i = 0; i < num_slots; ++i) {
249 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
250 if (!slot) {
251 retval = -ENOMEM;
252 goto error;
253 }
254
255 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
256 if (!hotplug_slot) {
257 retval = -ENOMEM;
258 goto error_slot;
259 }
260 slot->hotplug_slot = hotplug_slot;
261
262 info = kzalloc(sizeof(*info), GFP_KERNEL);
263 if (!info) {
264 retval = -ENOMEM;
265 goto error_hpslot;
266 }
267 hotplug_slot->info = info;
268
269 slot->number = i;
270
271 hotplug_slot->name = slot->name;
272 hotplug_slot->private = slot;
273 hotplug_slot->release = &release_slot;
274 make_slot_name(slot);
275 hotplug_slot->ops = &skel_hotplug_slot_ops;
276
277 /*
278 * Initialize the slot info structure with some known
279 * good values.
280 */
281 get_power_status(hotplug_slot, &info->power_status);
282 get_attention_status(hotplug_slot, &info->attention_status);
283 get_latch_status(hotplug_slot, &info->latch_status);
284 get_adapter_status(hotplug_slot, &info->adapter_status);
285
286 dbg("registering slot %d\n", i);
287 retval = pci_hp_register(slot->hotplug_slot);
288 if (retval) {
289 err("pci_hp_register failed with error %d\n", retval);
290 goto error_info;
291 }
292
293 /* add slot to our internal list */
294 list_add(&slot->slot_list, &slot_list);
295 }
296
297 return 0;
298error_info:
299 kfree(info);
300error_hpslot:
301 kfree(hotplug_slot);
302error_slot:
303 kfree(slot);
304error:
305 return retval;
306}
307
308static void __exit cleanup_slots(void)
309{
310 struct slot *slot, *next;
311
312 /*
313 * Unregister all of our slots with the pci_hotplug subsystem.
314 * Memory will be freed in release_slot() callback after slot's
315 * lifespan is finished.
316 */
317 list_for_each_entry_safe(slot, next, &slot_list, slot_list) {
318 list_del(&slot->slot_list);
319 pci_hp_deregister(slot->hotplug_slot);
320 }
321}
322
323static int __init pcihp_skel_init(void)
324{
325 int retval;
326
327 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
328 /*
329 * Do specific initialization stuff for your driver here
330 * like initializing your controller hardware (if any) and
331 * determining the number of slots you have in the system
332 * right now.
333 */
334 num_slots = 5;
335
336 return init_slots();
337}
338
339static void __exit pcihp_skel_exit(void)
340{
341 /*
342 * Clean everything up.
343 */
344 cleanup_slots();
345}
346
347module_init(pcihp_skel_init);
348module_exit(pcihp_skel_exit);
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 6c2e8d7307c6..3276a5e4c430 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -538,9 +538,8 @@ static struct hotplug_slot_ops php_slot_ops = {
538 .disable_slot = pnv_php_disable_slot, 538 .disable_slot = pnv_php_disable_slot,
539}; 539};
540 540
541static void pnv_php_release(struct hotplug_slot *slot) 541static void pnv_php_release(struct pnv_php_slot *php_slot)
542{ 542{
543 struct pnv_php_slot *php_slot = slot->private;
544 unsigned long flags; 543 unsigned long flags;
545 544
546 /* Remove from global or child list */ 545 /* Remove from global or child list */
@@ -596,7 +595,6 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
596 php_slot->power_state_check = false; 595 php_slot->power_state_check = false;
597 php_slot->slot.ops = &php_slot_ops; 596 php_slot->slot.ops = &php_slot_ops;
598 php_slot->slot.info = &php_slot->slot_info; 597 php_slot->slot.info = &php_slot->slot_info;
599 php_slot->slot.release = pnv_php_release;
600 php_slot->slot.private = php_slot; 598 php_slot->slot.private = php_slot;
601 599
602 INIT_LIST_HEAD(&php_slot->children); 600 INIT_LIST_HEAD(&php_slot->children);
@@ -924,6 +922,7 @@ static void pnv_php_unregister_one(struct device_node *dn)
924 922
925 php_slot->state = PNV_PHP_STATE_OFFLINE; 923 php_slot->state = PNV_PHP_STATE_OFFLINE;
926 pci_hp_deregister(&php_slot->slot); 924 pci_hp_deregister(&php_slot->slot);
925 pnv_php_release(php_slot);
927 pnv_php_put_slot(php_slot); 926 pnv_php_put_slot(php_slot);
928} 927}
929 928
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index fb5e0845429d..857c358b727b 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -404,13 +404,13 @@ static void __exit cleanup_slots(void)
404 /* 404 /*
405 * Unregister all of our slots with the pci_hotplug subsystem, 405 * Unregister all of our slots with the pci_hotplug subsystem,
406 * and free up all memory that we had allocated. 406 * and free up all memory that we had allocated.
407 * memory will be freed in release_slot callback.
408 */ 407 */
409 408
410 list_for_each_entry_safe(slot, next, &rpaphp_slot_head, 409 list_for_each_entry_safe(slot, next, &rpaphp_slot_head,
411 rpaphp_slot_list) { 410 rpaphp_slot_list) {
412 list_del(&slot->rpaphp_slot_list); 411 list_del(&slot->rpaphp_slot_list);
413 pci_hp_deregister(slot->hotplug_slot); 412 pci_hp_deregister(slot->hotplug_slot);
413 dealloc_slot_struct(slot);
414 } 414 }
415 return; 415 return;
416} 416}
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 3840a2075e6a..b916c8e4372d 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -19,12 +19,6 @@
19#include "rpaphp.h" 19#include "rpaphp.h"
20 20
21/* free up the memory used by a slot */ 21/* free up the memory used by a slot */
22static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
23{
24 struct slot *slot = (struct slot *) hotplug_slot->private;
25 dealloc_slot_struct(slot);
26}
27
28void dealloc_slot_struct(struct slot *slot) 22void dealloc_slot_struct(struct slot *slot)
29{ 23{
30 kfree(slot->hotplug_slot->info); 24 kfree(slot->hotplug_slot->info);
@@ -56,7 +50,6 @@ struct slot *alloc_slot_struct(struct device_node *dn,
56 slot->power_domain = power_domain; 50 slot->power_domain = power_domain;
57 slot->hotplug_slot->private = slot; 51 slot->hotplug_slot->private = slot;
58 slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; 52 slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
59 slot->hotplug_slot->release = &rpaphp_release_slot;
60 53
61 return (slot); 54 return (slot);
62 55
@@ -90,10 +83,8 @@ int rpaphp_deregister_slot(struct slot *slot)
90 __func__, slot->name); 83 __func__, slot->name);
91 84
92 list_del(&slot->rpaphp_slot_list); 85 list_del(&slot->rpaphp_slot_list);
93 86 pci_hp_deregister(php_slot);
94 retval = pci_hp_deregister(php_slot); 87 dealloc_slot_struct(slot);
95 if (retval)
96 err("Problem unregistering a slot %s\n", slot->name);
97 88
98 dbg("%s - Exit: rc[%d]\n", __func__, retval); 89 dbg("%s - Exit: rc[%d]\n", __func__, retval);
99 return retval; 90 return retval;
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index ffdc2977395d..93b5341d282c 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -130,15 +130,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
130 return 0; 130 return 0;
131} 131}
132 132
133static void release_slot(struct hotplug_slot *hotplug_slot)
134{
135 struct slot *slot = hotplug_slot->private;
136
137 kfree(slot->hotplug_slot->info);
138 kfree(slot->hotplug_slot);
139 kfree(slot);
140}
141
142static struct hotplug_slot_ops s390_hotplug_slot_ops = { 133static struct hotplug_slot_ops s390_hotplug_slot_ops = {
143 .enable_slot = enable_slot, 134 .enable_slot = enable_slot,
144 .disable_slot = disable_slot, 135 .disable_slot = disable_slot,
@@ -175,7 +166,6 @@ int zpci_init_slot(struct zpci_dev *zdev)
175 hotplug_slot->info = info; 166 hotplug_slot->info = info;
176 167
177 hotplug_slot->ops = &s390_hotplug_slot_ops; 168 hotplug_slot->ops = &s390_hotplug_slot_ops;
178 hotplug_slot->release = &release_slot;
179 169
180 get_power_status(hotplug_slot, &info->power_status); 170 get_power_status(hotplug_slot, &info->power_status);
181 get_adapter_status(hotplug_slot, &info->adapter_status); 171 get_adapter_status(hotplug_slot, &info->adapter_status);
@@ -209,5 +199,8 @@ void zpci_exit_slot(struct zpci_dev *zdev)
209 continue; 199 continue;
210 list_del(&slot->slot_list); 200 list_del(&slot->slot_list);
211 pci_hp_deregister(slot->hotplug_slot); 201 pci_hp_deregister(slot->hotplug_slot);
202 kfree(slot->hotplug_slot->info);
203 kfree(slot->hotplug_slot);
204 kfree(slot);
212 } 205 }
213} 206}
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 78b6bdbb3a39..babd23409f61 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -628,7 +628,6 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
628 goto alloc_err; 628 goto alloc_err;
629 } 629 }
630 bss_hotplug_slot->ops = &sn_hotplug_slot_ops; 630 bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
631 bss_hotplug_slot->release = &sn_release_slot;
632 631
633 rc = pci_hp_register(bss_hotplug_slot, pci_bus, device, name); 632 rc = pci_hp_register(bss_hotplug_slot, pci_bus, device, name);
634 if (rc) 633 if (rc)
@@ -656,8 +655,10 @@ alloc_err:
656 sn_release_slot(bss_hotplug_slot); 655 sn_release_slot(bss_hotplug_slot);
657 656
658 /* destroy anything else on the list */ 657 /* destroy anything else on the list */
659 while ((bss_hotplug_slot = sn_hp_destroy())) 658 while ((bss_hotplug_slot = sn_hp_destroy())) {
660 pci_hp_deregister(bss_hotplug_slot); 659 pci_hp_deregister(bss_hotplug_slot);
660 sn_release_slot(bss_hotplug_slot);
661 }
661 662
662 return rc; 663 return rc;
663} 664}
@@ -703,8 +704,10 @@ static void __exit sn_pci_hotplug_exit(void)
703{ 704{
704 struct hotplug_slot *bss_hotplug_slot; 705 struct hotplug_slot *bss_hotplug_slot;
705 706
706 while ((bss_hotplug_slot = sn_hp_destroy())) 707 while ((bss_hotplug_slot = sn_hp_destroy())) {
707 pci_hp_deregister(bss_hotplug_slot); 708 pci_hp_deregister(bss_hotplug_slot);
709 sn_release_slot(bss_hotplug_slot);
710 }
708 711
709 if (!list_empty(&sn_hp_list)) 712 if (!list_empty(&sn_hp_list))
710 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__); 713 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index e91be287f292..97cee23f3d51 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -61,22 +61,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
61 .get_adapter_status = get_adapter_status, 61 .get_adapter_status = get_adapter_status,
62}; 62};
63 63
64/**
65 * release_slot - free up the memory used by a slot
66 * @hotplug_slot: slot to free
67 */
68static void release_slot(struct hotplug_slot *hotplug_slot)
69{
70 struct slot *slot = hotplug_slot->private;
71
72 ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
73 __func__, slot_name(slot));
74
75 kfree(slot->hotplug_slot->info);
76 kfree(slot->hotplug_slot);
77 kfree(slot);
78}
79
80static int init_slots(struct controller *ctrl) 64static int init_slots(struct controller *ctrl)
81{ 65{
82 struct slot *slot; 66 struct slot *slot;
@@ -125,7 +109,6 @@ static int init_slots(struct controller *ctrl)
125 109
126 /* register this slot with the hotplug pci core */ 110 /* register this slot with the hotplug pci core */
127 hotplug_slot->private = slot; 111 hotplug_slot->private = slot;
128 hotplug_slot->release = &release_slot;
129 snprintf(name, SLOT_NAME_SIZE, "%d", slot->number); 112 snprintf(name, SLOT_NAME_SIZE, "%d", slot->number);
130 hotplug_slot->ops = &shpchp_hotplug_slot_ops; 113 hotplug_slot->ops = &shpchp_hotplug_slot_ops;
131 114
@@ -171,6 +154,9 @@ void cleanup_slots(struct controller *ctrl)
171 cancel_delayed_work(&slot->work); 154 cancel_delayed_work(&slot->work);
172 destroy_workqueue(slot->wq); 155 destroy_workqueue(slot->wq);
173 pci_hp_deregister(slot->hotplug_slot); 156 pci_hp_deregister(slot->hotplug_slot);
157 kfree(slot->hotplug_slot->info);
158 kfree(slot->hotplug_slot);
159 kfree(slot);
174 } 160 }
175} 161}
176 162
@@ -270,11 +256,30 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
270 return 0; 256 return 0;
271} 257}
272 258
259static bool shpc_capable(struct pci_dev *bridge)
260{
261 /*
262 * It is assumed that AMD GOLAM chips support SHPC but they do not
263 * have SHPC capability.
264 */
265 if (bridge->vendor == PCI_VENDOR_ID_AMD &&
266 bridge->device == PCI_DEVICE_ID_AMD_GOLAM_7450)
267 return true;
268
269 if (pci_find_capability(bridge, PCI_CAP_ID_SHPC))
270 return true;
271
272 return false;
273}
274
273static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 275static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
274{ 276{
275 int rc; 277 int rc;
276 struct controller *ctrl; 278 struct controller *ctrl;
277 279
280 if (!shpc_capable(pdev))
281 return -ENODEV;
282
278 if (acpi_get_hp_hw_control_from_firmware(pdev)) 283 if (acpi_get_hp_hw_control_from_firmware(pdev))
279 return -ENODEV; 284 return -ENODEV;
280 285
@@ -303,6 +308,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
303 if (rc) 308 if (rc)
304 goto err_cleanup_slots; 309 goto err_cleanup_slots;
305 310
311 pdev->shpc_managed = 1;
306 return 0; 312 return 0;
307 313
308err_cleanup_slots: 314err_cleanup_slots:
@@ -319,6 +325,7 @@ static void shpc_remove(struct pci_dev *dev)
319{ 325{
320 struct controller *ctrl = pci_get_drvdata(dev); 326 struct controller *ctrl = pci_get_drvdata(dev);
321 327
328 dev->shpc_managed = 0;
322 shpchp_remove_ctrl_files(ctrl); 329 shpchp_remove_ctrl_files(ctrl);
323 ctrl->hpc_ops->release_ctlr(ctrl); 330 ctrl->hpc_ops->release_ctlr(ctrl);
324 kfree(ctrl); 331 kfree(ctrl);