aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h3
-rw-r--r--drivers/pci/hotplug/pciehp_core.c5
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c11
3 files changed, 18 insertions, 1 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e0a614acee05..fbadf1c8577e 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -81,6 +81,7 @@ extern int pciehp_poll_time;
* @request_result: result of last user request submitted to the IRQ thread
* @requester: wait queue to wake up on completion of user request,
* used for synchronous slot enable/disable request via sysfs
+ * @is_virtual: virtual machine pcie port.
*
* PCIe hotplug has a 1:1 relationship between controller and slot, hence
* unlike other drivers, the two aren't represented by separate structures.
@@ -112,6 +113,8 @@ struct controller {
unsigned int ist_running;
int request_result;
wait_queue_head_t requester;
+
+ bool is_virtual;
};
/**
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 4042d87d539d..cbcd78410ceb 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -227,6 +227,11 @@ static int pciehp_probe(struct pcie_device *dev)
goto err_out_shutdown_notification;
}
+ if (dev->port->vendor == PCI_VENDOR_ID_REDHAT &&
+ dev->port->device == 0x000c)
+ /* qemu pcie root port */
+ ctrl->is_virtual = true;
+
pciehp_check_presence(ctrl);
return 0;
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 529c34808440..119bb11f87d6 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -15,12 +15,17 @@
#define dev_fmt(fmt) "pciehp: " fmt
+#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include "pciehp.h"
+static bool fast_virtual_unplug = true;
+module_param(fast_virtual_unplug, bool, 0644);
+MODULE_PARM_DESC(fast_virtual_unplug, "Fast unplug (don't wait 5 seconds) for virtual machines.");
+
/* The following routines constitute the bulk of the
hotplug controller logic
*/
@@ -176,7 +181,11 @@ void pciehp_handle_button_press(struct controller *ctrl)
/* blink power indicator and turn off attention */
pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
PCI_EXP_SLTCTL_ATTN_IND_OFF);
- schedule_delayed_work(&ctrl->button_work, 5 * HZ);
+ if (ctrl->is_virtual && fast_virtual_unplug) {
+ schedule_delayed_work(&ctrl->button_work, 1);
+ } else {
+ schedule_delayed_work(&ctrl->button_work, 5 * HZ);
+ }
break;
case BLINKINGOFF_STATE:
case BLINKINGON_STATE: