diff options
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 27 |
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 | ||
252 | static inline int pcie_wait_cmd(struct controller *ctrl) | 252 | static 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 | ||
270 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 271 | static 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 | ||