aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/shpchp_hpc.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2005-11-24 22:28:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-09 15:13:17 -0500
commitbd62e271401c5ebf33a0dd24d89baf706f213251 (patch)
tree77b8e2cd249df83b0d256f8126047a037a1fc542 /drivers/pci/hotplug/shpchp_hpc.c
parentf467f6187fc60c954a9509b3a3e17ef89a4f6f22 (diff)
[PATCH] shpchp: fix improper wait for command completion
Current SHPCHP driver uses msleep_interruptible() function to wait for a command completion event. But I think this would cause an unnecessary long wait until timeout, if command completion interrupt came before task state was changed to TASK_INTERRUPTIBLE. This patch fixes this issue. With this patch, command completion becomes faster as follows: o Without this patch # time echo 1 > power real 0m4.708s user 0m0.000s sys 0m0.524s o With this patch # time echo 1 > power real 0m2.221s user 0m0.000s sys 0m0.532s Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index f25e11645071..b4226ff3a854 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -275,6 +275,25 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
275 return; 275 return;
276} 276}
277 277
278static inline int shpc_wait_cmd(struct controller *ctrl)
279{
280 int retval = 0;
281 unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
282 unsigned long timeout = msecs_to_jiffies(timeout_msec);
283 int rc = wait_event_interruptible_timeout(ctrl->queue,
284 !ctrl->cmd_busy, timeout);
285 if (!rc) {
286 retval = -EIO;
287 err("Command not completed in %d msec\n", timeout_msec);
288 } else if (rc < 0) {
289 retval = -EINTR;
290 info("Command was interrupted by a signal\n");
291 }
292 ctrl->cmd_busy = 0;
293
294 return retval;
295}
296
278static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) 297static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
279{ 298{
280 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 299 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
@@ -314,8 +333,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
314 /* To make sure the Controller Busy bit is 0 before we send out the 333 /* To make sure the Controller Busy bit is 0 before we send out the
315 * command. 334 * command.
316 */ 335 */
336 slot->ctrl->cmd_busy = 1;
317 writew(temp_word, php_ctlr->creg + CMD); 337 writew(temp_word, php_ctlr->creg + CMD);
318 338
339 /*
340 * Wait for command completion.
341 */
342 retval = shpc_wait_cmd(slot->ctrl);
343
319 DBG_LEAVE_ROUTINE 344 DBG_LEAVE_ROUTINE
320 return retval; 345 return retval;
321} 346}
@@ -1064,6 +1089,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1064 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1089 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1065 temp_dword &= 0xfffdffff; 1090 temp_dword &= 0xfffdffff;
1066 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1091 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1092 ctrl->cmd_busy = 0;
1067 wake_up_interruptible(&ctrl->queue); 1093 wake_up_interruptible(&ctrl->queue);
1068 } 1094 }
1069 1095