aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-12-21 20:01:10 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:50:05 -0500
commit262303fe329a51463925f3749aafc358a4201397 (patch)
treef9b82b164c8a25d94c9602d640f1b853e7633295 /drivers/pci/hotplug/pciehp_hpc.c
parent44ef4cefb0168740184ee3d7d18254339741e9d5 (diff)
pciehp: fix wait command completion
This patch fixes this problem that pciehp driver will sleep unnecessarily long when waiting for command completion. With this patch, modprobe pciehp driver becomes very faster as follows for instance. o Without this patch # time /sbin/modprobe pciehp real 0m4.976s user 0m0.000s sys 0m0.004s o With this patch # time /sbin/modprobe pciehp real 0m0.640s user 0m0.000s sys 0m0.004s Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9fbd9b9f9824..eb1862b50bb1 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
251 251
252static inline int pcie_wait_cmd(struct controller *ctrl) 252static inline int pcie_wait_cmd(struct controller *ctrl)
253{ 253{
254 DECLARE_WAITQUEUE(wait, current); 254 int retval = 0;
255 255 unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
256 add_wait_queue(&ctrl->queue, &wait); 256 unsigned long timeout = msecs_to_jiffies(msecs);
257 if (!pciehp_poll_mode) 257 int rc;
258 /* Sleep for up to 1 second */
259 msleep_interruptible(1000);
260 else
261 msleep_interruptible(2500);
262 258
263 remove_wait_queue(&ctrl->queue, &wait); 259 rc = wait_event_interruptible_timeout(ctrl->queue,
264 if (signal_pending(current)) 260 !ctrl->cmd_busy, timeout);
265 return -EINTR; 261 if (!rc)
262 dbg("Command not completed in 1000 msec\n");
263 else if (rc < 0) {
264 retval = -EINTR;
265 info("Command was interrupted by a signal\n");
266 }
266 267
267 return 0; 268 return retval;
268} 269}
269 270
270static int pcie_write_cmd(struct slot *slot, u16 cmd) 271static int pcie_write_cmd(struct slot *slot, u16 cmd)
@@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
291 __FUNCTION__); 292 __FUNCTION__);
292 } 293 }
293 294
295 ctrl->cmd_busy = 1;
294 retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); 296 retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
295 if (retval) { 297 if (retval) {
296 err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); 298 err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
@@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
773 /* 775 /*
774 * Command Complete Interrupt Pending 776 * Command Complete Interrupt Pending
775 */ 777 */
778 ctrl->cmd_busy = 0;
776 wake_up_interruptible(&ctrl->queue); 779 wake_up_interruptible(&ctrl->queue);
777 } 780 }
778 781