aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-06-13 15:58:35 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-06-16 13:47:59 -0400
commit4283c70e91dcabe36f3545afabc5ee2b7d4da34a (patch)
treea21257faabcd4bff13e254e4a3c7a3446f2ca459 /drivers/pci/hotplug
parent62e4492c3063048a163d238cd1734273f2fc757d (diff)
PCI: pciehp: Make pcie_wait_cmd() self-contained
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>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c33
2 files changed, 18 insertions, 16 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 8e9012dca450..f7bc886c20be 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -92,6 +92,7 @@ struct controller {
92 struct slot *slot; 92 struct slot *slot;
93 wait_queue_head_t queue; /* sleep & wake process */ 93 wait_queue_head_t queue; /* sleep & wake process */
94 u32 slot_cap; 94 u32 slot_cap;
95 u32 slot_ctrl;
95 struct timer_list poll_timer; 96 struct timer_list poll_timer;
96 unsigned int cmd_busy:1; 97 unsigned int cmd_busy:1;
97 unsigned int no_cmd_complete:1; 98 unsigned int no_cmd_complete:1;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 42914e04d110..7c2a9dd6f6a4 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -129,16 +129,27 @@ static int pcie_poll_cmd(struct controller *ctrl)
129 return 0; /* timeout */ 129 return 0; /* timeout */
130} 130}
131 131
132static void pcie_wait_cmd(struct controller *ctrl, int poll) 132static void pcie_wait_cmd(struct controller *ctrl)
133{ 133{
134 unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; 134 unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
135 unsigned long timeout = msecs_to_jiffies(msecs); 135 unsigned long timeout = msecs_to_jiffies(msecs);
136 int rc; 136 int rc;
137 137
138 if (poll) 138 /*
139 rc = pcie_poll_cmd(ctrl); 139 * If the controller does not generate notifications for command
140 else 140 * completions, we never need to wait between writes.
141 */
142 if (ctrl->no_cmd_complete)
143 return;
144
145 if (!ctrl->cmd_busy)
146 return;
147
148 if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE &&
149 ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE)
141 rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); 150 rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
151 else
152 rc = pcie_poll_cmd(ctrl);
142 if (!rc) 153 if (!rc)
143 ctrl_dbg(ctrl, "Command not completed in 1000 msec\n"); 154 ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
144} 155}
@@ -187,22 +198,12 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
187 ctrl->cmd_busy = 1; 198 ctrl->cmd_busy = 1;
188 smp_mb(); 199 smp_mb();
189 pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl); 200 pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
201 ctrl->slot_ctrl = slot_ctrl;
190 202
191 /* 203 /*
192 * Wait for command completion. 204 * Wait for command completion.
193 */ 205 */
194 if (!ctrl->no_cmd_complete) { 206 pcie_wait_cmd(ctrl);
195 int poll = 0;
196 /*
197 * if hotplug interrupt is not enabled or command
198 * completed interrupt is not enabled, we need to poll
199 * command completed event.
200 */
201 if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) ||
202 !(slot_ctrl & PCI_EXP_SLTCTL_CCIE))
203 poll = 1;
204 pcie_wait_cmd(ctrl, poll);
205 }
206 mutex_unlock(&ctrl->ctrl_lock); 207 mutex_unlock(&ctrl->ctrl_lock);
207} 208}
208 209