From: Bjorn Helgaas Date: Fri, 13 Jun 2014 19:58:35 +0000 (-0600) Subject: PCI: pciehp: Make pcie_wait_cmd() self-contained X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=4283c70e91dc;p=linux-beck.git 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 (IDT 807a controller) Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- 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 { 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; 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) 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); }