up(&ctrl->crit_sect);
                return WRONG_BUS_FREQUENCY;
        }
-       wait_for_ctrl_irq (ctrl);
                
        if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
                err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
                up(&ctrl->crit_sect);
                return -1;
        }
-                       
-       /* Wait for the command to complete */
-       wait_for_ctrl_irq (ctrl);
        
        rc = p_slot->hpc_ops->check_cmd_status(ctrl);
        if (rc) {
                        up(&ctrl->crit_sect);
                        return WRONG_BUS_FREQUENCY;
                }
-               wait_for_ctrl_irq (ctrl);
                
                if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
                        err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
                        up(&ctrl->crit_sect);
                        return rc;
                }
-               wait_for_ctrl_irq (ctrl);
 
                if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
                        err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
                up(&ctrl->crit_sect);
                return rc;
        }
-       wait_for_ctrl_irq (ctrl);
 
        if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
                err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
 
        p_slot->hpc_ops->green_led_on(p_slot);
 
-       /* Wait for the command to complete */
-       wait_for_ctrl_irq (ctrl);
-
        /* Done with exclusive hardware access */
        up(&ctrl->crit_sect);
 
                up(&ctrl->crit_sect);
                return rc;
        }
-       /* Wait for the command to complete */
-       wait_for_ctrl_irq (ctrl);
 
        rc = p_slot->hpc_ops->check_cmd_status(ctrl);
        if (rc) {
                up(&ctrl->crit_sect);
                return rc;
        }
-       /* Wait for the command to complete */
-       wait_for_ctrl_irq (ctrl);
 
        rc = p_slot->hpc_ops->check_cmd_status(ctrl);
        if (rc) {
                up(&ctrl->crit_sect);
                return rc;
        }
-       /* Wait for the command to complete */
-       wait_for_ctrl_irq (ctrl);
 
        /* Done with exclusive hardware access */
        up(&ctrl->crit_sect);
 
                        p_slot->hpc_ops->green_led_off(p_slot);
 
-                       /* Wait for the command to complete */
-                       wait_for_ctrl_irq (p_slot->ctrl);
-
                        /* Done with exclusive hardware access */
                        up(&p_slot->ctrl->crit_sect);
                }
                                                down(&ctrl->crit_sect);
 
                                                p_slot->hpc_ops->green_led_on(p_slot);
-                                               /* Wait for the command to complete */
-                                               wait_for_ctrl_irq (ctrl);
 
                                                p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-                                               /* Wait for the command to complete */
-                                               wait_for_ctrl_irq (ctrl);
-
                                                /* Done with exclusive hardware access */
                                                up(&ctrl->crit_sect);
                                                break;
                                                down(&ctrl->crit_sect);
 
                                                p_slot->hpc_ops->green_led_off(p_slot);
-                                               /* Wait for the command to complete */
-                                               wait_for_ctrl_irq (ctrl);
 
                                                p_slot->hpc_ops->set_attention_status(p_slot, 0);
-                                               /* Wait for the command to complete */
-                                               wait_for_ctrl_irq (ctrl);
 
                                                /* Done with exclusive hardware access */
                                                up(&ctrl->crit_sect);
 
                                        /* blink green LED and turn off amber */
                                        p_slot->hpc_ops->green_led_blink(p_slot);
-                                       /* Wait for the command to complete */
-                                       wait_for_ctrl_irq (ctrl);
                                        
                                        p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-                                       /* Wait for the command to complete */
-                                       wait_for_ctrl_irq (ctrl);
-
                                        /* Done with exclusive hardware access */
                                        up(&ctrl->crit_sect);
 
                                        down(&ctrl->crit_sect);
 
                                        p_slot->hpc_ops->set_attention_status(p_slot, 1);
-                                       /* Wait for the command to complete */
-                                       wait_for_ctrl_irq (ctrl);
                                        
                                        p_slot->hpc_ops->green_led_off(p_slot);
-                                       /* Wait for the command to complete */
-                                       wait_for_ctrl_irq (ctrl);
 
                                        /* Done with exclusive hardware access */
                                        up(&ctrl->crit_sect);
 
        return;
 }
 
+static inline int shpc_wait_cmd(struct controller *ctrl)
+{
+       int retval = 0;
+       unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
+       unsigned long timeout = msecs_to_jiffies(timeout_msec);
+       int rc = wait_event_interruptible_timeout(ctrl->queue,
+                                                 !ctrl->cmd_busy, timeout);
+       if (!rc) {
+               retval = -EIO;
+               err("Command not completed in %d msec\n", timeout_msec);
+       } else if (rc < 0) {
+               retval = -EINTR;
+               info("Command was interrupted by a signal\n");
+       }
+       ctrl->cmd_busy = 0;
+
+       return retval;
+}
+
 static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
 {
        struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
        /* To make sure the Controller Busy bit is 0 before we send out the
         * command. 
         */
+       slot->ctrl->cmd_busy = 1;
        writew(temp_word, php_ctlr->creg + CMD);
 
+       /*
+        * Wait for command completion.
+        */
+       retval = shpc_wait_cmd(slot->ctrl);
+
        DBG_LEAVE_ROUTINE 
        return retval;
 }
                temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
                temp_dword &= 0xfffdffff;
                writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+               ctrl->cmd_busy = 0;
                wake_up_interruptible(&ctrl->queue);
        }