PCI: pciehp: Make pcie_wait_cmd() self-contained
authorBjorn Helgaas <bhelgaas@google.com>
Fri, 13 Jun 2014 19:58:35 +0000 (13:58 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 16 Jun 2014 17:47:59 +0000 (11:47 -0600)
pcie_wait_cmd() waits for the controller to finish a hotplug command.  Move
the associated logic (to determine whether waiting is required and whether
we're using interrupts or polling) from pcie_write_cmd() to
pcie_wait_cmd().

No functional change.

Tested-by: Rajat Jain <rajatxjain@gmail.com> (IDT 807a controller)
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_hpc.c

index 8e9012dca450df581f718431e25e85d469827534..f7bc886c20befcdcf03204d31e51d42076326d18 100644 (file)
@@ -92,6 +92,7 @@ struct controller {
        struct slot *slot;
        wait_queue_head_t queue;        /* sleep & wake process */
        u32 slot_cap;
+       u32 slot_ctrl;
        struct timer_list poll_timer;
        unsigned int cmd_busy:1;
        unsigned int no_cmd_complete:1;
index 42914e04d11070e4daefccc9eeb80d52a610b549..7c2a9dd6f6a40ba21a894e0c4c3bb09bdef813fe 100644 (file)
@@ -129,16 +129,27 @@ static int pcie_poll_cmd(struct controller *ctrl)
        return 0;       /* timeout */
 }
 
-static void pcie_wait_cmd(struct controller *ctrl, int poll)
+static void pcie_wait_cmd(struct controller *ctrl)
 {
        unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
        unsigned long timeout = msecs_to_jiffies(msecs);
        int rc;
 
-       if (poll)
-               rc = pcie_poll_cmd(ctrl);
-       else
+       /*
+        * If the controller does not generate notifications for command
+        * completions, we never need to wait between writes.
+        */
+       if (ctrl->no_cmd_complete)
+               return;
+
+       if (!ctrl->cmd_busy)
+               return;
+
+       if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE &&
+           ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE)
                rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
+       else
+               rc = pcie_poll_cmd(ctrl);
        if (!rc)
                ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
 }
@@ -187,22 +198,12 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
        ctrl->cmd_busy = 1;
        smp_mb();
        pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
+       ctrl->slot_ctrl = slot_ctrl;
 
        /*
         * Wait for command completion.
         */
-       if (!ctrl->no_cmd_complete) {
-               int poll = 0;
-               /*
-                * if hotplug interrupt is not enabled or command
-                * completed interrupt is not enabled, we need to poll
-                * command completed event.
-                */
-               if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) ||
-                   !(slot_ctrl & PCI_EXP_SLTCTL_CCIE))
-                       poll = 1;
-               pcie_wait_cmd(ctrl, poll);
-       }
+       pcie_wait_cmd(ctrl);
        mutex_unlock(&ctrl->ctrl_lock);
 }