diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 0ebf754fc177..6d6868811e56 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -176,20 +176,17 @@ static void pcie_wait_cmd(struct controller *ctrl) | |||
176 | jiffies_to_msecs(jiffies - ctrl->cmd_started)); | 176 | jiffies_to_msecs(jiffies - ctrl->cmd_started)); |
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, |
180 | * pcie_write_cmd - Issue controller command | 180 | u16 mask, bool wait) |
181 | * @ctrl: controller to which the command is issued | ||
182 | * @cmd: command value written to slot control register | ||
183 | * @mask: bitmask of slot control register to be modified | ||
184 | */ | ||
185 | static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | ||
186 | { | 181 | { |
187 | struct pci_dev *pdev = ctrl_dev(ctrl); | 182 | struct pci_dev *pdev = ctrl_dev(ctrl); |
188 | u16 slot_ctrl; | 183 | u16 slot_ctrl; |
189 | 184 | ||
190 | mutex_lock(&ctrl->ctrl_lock); | 185 | mutex_lock(&ctrl->ctrl_lock); |
191 | 186 | ||
192 | /* Wait for any previous command that might still be in progress */ | 187 | /* |
188 | * Always wait for any previous command that might still be in progress | ||
189 | */ | ||
193 | pcie_wait_cmd(ctrl); | 190 | pcie_wait_cmd(ctrl); |
194 | 191 | ||
195 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); | 192 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); |
@@ -201,9 +198,33 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
201 | ctrl->cmd_started = jiffies; | 198 | ctrl->cmd_started = jiffies; |
202 | ctrl->slot_ctrl = slot_ctrl; | 199 | ctrl->slot_ctrl = slot_ctrl; |
203 | 200 | ||
201 | /* | ||
202 | * Optionally wait for the hardware to be ready for a new command, | ||
203 | * indicating completion of the above issued command. | ||
204 | */ | ||
205 | if (wait) | ||
206 | pcie_wait_cmd(ctrl); | ||
207 | |||
204 | mutex_unlock(&ctrl->ctrl_lock); | 208 | mutex_unlock(&ctrl->ctrl_lock); |
205 | } | 209 | } |
206 | 210 | ||
211 | /** | ||
212 | * pcie_write_cmd - Issue controller command | ||
213 | * @ctrl: controller to which the command is issued | ||
214 | * @cmd: command value written to slot control register | ||
215 | * @mask: bitmask of slot control register to be modified | ||
216 | */ | ||
217 | static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | ||
218 | { | ||
219 | pcie_do_write_cmd(ctrl, cmd, mask, true); | ||
220 | } | ||
221 | |||
222 | /* Same as above without waiting for the hardware to latch */ | ||
223 | static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask) | ||
224 | { | ||
225 | pcie_do_write_cmd(ctrl, cmd, mask, false); | ||
226 | } | ||
227 | |||
207 | bool pciehp_check_link_active(struct controller *ctrl) | 228 | bool pciehp_check_link_active(struct controller *ctrl) |
208 | { | 229 | { |
209 | struct pci_dev *pdev = ctrl_dev(ctrl); | 230 | struct pci_dev *pdev = ctrl_dev(ctrl); |
@@ -422,7 +443,7 @@ void pciehp_set_attention_status(struct slot *slot, u8 value) | |||
422 | default: | 443 | default: |
423 | return; | 444 | return; |
424 | } | 445 | } |
425 | pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); | 446 | pcie_write_cmd_nowait(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); |
426 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 447 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
427 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 448 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
428 | } | 449 | } |
@@ -434,7 +455,8 @@ void pciehp_green_led_on(struct slot *slot) | |||
434 | if (!PWR_LED(ctrl)) | 455 | if (!PWR_LED(ctrl)) |
435 | return; | 456 | return; |
436 | 457 | ||
437 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON, PCI_EXP_SLTCTL_PIC); | 458 | pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON, |
459 | PCI_EXP_SLTCTL_PIC); | ||
438 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 460 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
439 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, | 461 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, |
440 | PCI_EXP_SLTCTL_PWR_IND_ON); | 462 | PCI_EXP_SLTCTL_PWR_IND_ON); |
@@ -447,7 +469,8 @@ void pciehp_green_led_off(struct slot *slot) | |||
447 | if (!PWR_LED(ctrl)) | 469 | if (!PWR_LED(ctrl)) |
448 | return; | 470 | return; |
449 | 471 | ||
450 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, PCI_EXP_SLTCTL_PIC); | 472 | pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, |
473 | PCI_EXP_SLTCTL_PIC); | ||
451 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 474 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
452 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, | 475 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, |
453 | PCI_EXP_SLTCTL_PWR_IND_OFF); | 476 | PCI_EXP_SLTCTL_PWR_IND_OFF); |
@@ -460,7 +483,8 @@ void pciehp_green_led_blink(struct slot *slot) | |||
460 | if (!PWR_LED(ctrl)) | 483 | if (!PWR_LED(ctrl)) |
461 | return; | 484 | return; |
462 | 485 | ||
463 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, PCI_EXP_SLTCTL_PIC); | 486 | pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, |
487 | PCI_EXP_SLTCTL_PIC); | ||
464 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 488 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
465 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, | 489 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, |
466 | PCI_EXP_SLTCTL_PWR_IND_BLINK); | 490 | PCI_EXP_SLTCTL_PWR_IND_BLINK); |
@@ -613,7 +637,7 @@ void pcie_enable_notification(struct controller *ctrl) | |||
613 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | | 637 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
614 | PCI_EXP_SLTCTL_DLLSCE); | 638 | PCI_EXP_SLTCTL_DLLSCE); |
615 | 639 | ||
616 | pcie_write_cmd(ctrl, cmd, mask); | 640 | pcie_write_cmd_nowait(ctrl, cmd, mask); |
617 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 641 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
618 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); | 642 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); |
619 | } | 643 | } |
@@ -664,7 +688,7 @@ int pciehp_reset_slot(struct slot *slot, int probe) | |||
664 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); | 688 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); |
665 | 689 | ||
666 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); | 690 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); |
667 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); | 691 | pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask); |
668 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 692 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
669 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); | 693 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); |
670 | if (pciehp_poll_mode) | 694 | if (pciehp_poll_mode) |