aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-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 17167d59447..927dba9911e 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -100,6 +100,7 @@ struct controller {
u16 vendor_id;
u8 cap_base;
struct timer_list poll_timer;
+ volatile int cmd_busy;
};
#define INT_BUTTON_IGNORE 0
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9fbd9b9f982..eb1862b50bb 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)
static inline int pcie_wait_cmd(struct controller *ctrl)
{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&ctrl->queue, &wait);
- if (!pciehp_poll_mode)
- /* Sleep for up to 1 second */
- msleep_interruptible(1000);
- else
- msleep_interruptible(2500);
+ int retval = 0;
+ unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
+ unsigned long timeout = msecs_to_jiffies(msecs);
+ int rc;
- remove_wait_queue(&ctrl->queue, &wait);
- if (signal_pending(current))
- return -EINTR;
+ rc = wait_event_interruptible_timeout(ctrl->queue,
+ !ctrl->cmd_busy, timeout);
+ if (!rc)
+ dbg("Command not completed in 1000 msec\n");
+ else if (rc < 0) {
+ retval = -EINTR;
+ info("Command was interrupted by a signal\n");
+ }
- return 0;
+ return retval;
}
static int pcie_write_cmd(struct slot *slot, u16 cmd)
@@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
__FUNCTION__);
}
+ ctrl->cmd_busy = 1;
retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
if (retval) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
@@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
/*
* Command Complete Interrupt Pending
*/
+ ctrl->cmd_busy = 0;
wake_up_interruptible(&ctrl->queue);
}