aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c27
2 files changed, 16 insertions, 12 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 17167d594472..927dba9911ed 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -100,6 +100,7 @@ struct controller {
100 u16 vendor_id; 100 u16 vendor_id;
101 u8 cap_base; 101 u8 cap_base;
102 struct timer_list poll_timer; 102 struct timer_list poll_timer;
103 volatile int cmd_busy;
103}; 104};
104 105
105#define INT_BUTTON_IGNORE 0 106#define INT_BUTTON_IGNORE 0
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