diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-06-13 15:58:35 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-06-16 13:47:59 -0400 |
commit | 4283c70e91dcabe36f3545afabc5ee2b7d4da34a (patch) | |
tree | a21257faabcd4bff13e254e4a3c7a3446f2ca459 /drivers/pci/hotplug | |
parent | 62e4492c3063048a163d238cd1734273f2fc757d (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.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 33 |
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 | ||
132 | static void pcie_wait_cmd(struct controller *ctrl, int poll) | 132 | static 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 | ||