Loading drivers/pci/host/pci-msm.c +43 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ #define RD 0 #define WR 1 #define MSM_PCIE_ERROR -1 #define PERST_PROPAGATION_DELAY_US_MIN 10000 #define PERST_PROPAGATION_DELAY_US_MAX 10005 Loading Loading @@ -406,6 +407,7 @@ struct msm_pcie_dev_t { enum msm_pcie_link_status link_status; bool user_suspend; bool disable_pc; struct pci_saved_state *saved_state; struct wakeup_source ws; Loading Loading @@ -2668,6 +2670,7 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_dev[rc_idx].parf_swing = 0; msm_pcie_dev[rc_idx].link_status = MSM_PCIE_LINK_DEINIT; msm_pcie_dev[rc_idx].user_suspend = false; msm_pcie_dev[rc_idx].disable_pc = false; msm_pcie_dev[rc_idx].saved_state = NULL; msm_pcie_dev[rc_idx].enumerated = false; msm_pcie_dev[rc_idx].linkdown_counter = 0; Loading Loading @@ -2925,6 +2928,19 @@ static void msm_pcie_fixup_suspend(struct pci_dev *dev) if (pcie_dev->link_status != MSM_PCIE_LINK_ENABLED) return; spin_lock_irqsave(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); if (pcie_dev->disable_pc) { PCIE_DBG(pcie_dev, "RC%d: Skip suspend because of user request\n", pcie_dev->rc_idx); spin_unlock_irqrestore(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); return; } spin_unlock_irqrestore(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); mutex_lock(&pcie_dev->recovery_lock); ret = msm_pcie_pm_suspend(dev, NULL, NULL, 0); Loading Loading @@ -3120,6 +3136,33 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user, mutex_unlock(&msm_pcie_dev[rc_idx].recovery_lock); break; case MSM_PCIE_DISABLE_PC: PCIE_DBG(&msm_pcie_dev[rc_idx], "User of RC%d requests to keep the link always alive.\n", rc_idx); spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); if (msm_pcie_dev[rc_idx].suspending) { PCIE_ERR(&msm_pcie_dev[rc_idx], "PCIe: RC%d Link has been suspended before request\n", rc_idx); ret = MSM_PCIE_ERROR; } else { msm_pcie_dev[rc_idx].disable_pc = true; } spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); break; case MSM_PCIE_ENABLE_PC: PCIE_DBG(&msm_pcie_dev[rc_idx], "User of RC%d cancels the request of alive link.\n", rc_idx); spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); msm_pcie_dev[rc_idx].disable_pc = false; spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); break; default: PCIE_ERR(&msm_pcie_dev[rc_idx], "PCIe: RC%d: unsupported pm operation:%d.\n", Loading include/linux/msm_pcie.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ enum msm_pcie_config { enum msm_pcie_pm_opt { MSM_PCIE_SUSPEND, MSM_PCIE_RESUME MSM_PCIE_RESUME, MSM_PCIE_DISABLE_PC, MSM_PCIE_ENABLE_PC, }; enum msm_pcie_event { Loading Loading
drivers/pci/host/pci-msm.c +43 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ #define RD 0 #define WR 1 #define MSM_PCIE_ERROR -1 #define PERST_PROPAGATION_DELAY_US_MIN 10000 #define PERST_PROPAGATION_DELAY_US_MAX 10005 Loading Loading @@ -406,6 +407,7 @@ struct msm_pcie_dev_t { enum msm_pcie_link_status link_status; bool user_suspend; bool disable_pc; struct pci_saved_state *saved_state; struct wakeup_source ws; Loading Loading @@ -2668,6 +2670,7 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_dev[rc_idx].parf_swing = 0; msm_pcie_dev[rc_idx].link_status = MSM_PCIE_LINK_DEINIT; msm_pcie_dev[rc_idx].user_suspend = false; msm_pcie_dev[rc_idx].disable_pc = false; msm_pcie_dev[rc_idx].saved_state = NULL; msm_pcie_dev[rc_idx].enumerated = false; msm_pcie_dev[rc_idx].linkdown_counter = 0; Loading Loading @@ -2925,6 +2928,19 @@ static void msm_pcie_fixup_suspend(struct pci_dev *dev) if (pcie_dev->link_status != MSM_PCIE_LINK_ENABLED) return; spin_lock_irqsave(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); if (pcie_dev->disable_pc) { PCIE_DBG(pcie_dev, "RC%d: Skip suspend because of user request\n", pcie_dev->rc_idx); spin_unlock_irqrestore(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); return; } spin_unlock_irqrestore(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags); mutex_lock(&pcie_dev->recovery_lock); ret = msm_pcie_pm_suspend(dev, NULL, NULL, 0); Loading Loading @@ -3120,6 +3136,33 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user, mutex_unlock(&msm_pcie_dev[rc_idx].recovery_lock); break; case MSM_PCIE_DISABLE_PC: PCIE_DBG(&msm_pcie_dev[rc_idx], "User of RC%d requests to keep the link always alive.\n", rc_idx); spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); if (msm_pcie_dev[rc_idx].suspending) { PCIE_ERR(&msm_pcie_dev[rc_idx], "PCIe: RC%d Link has been suspended before request\n", rc_idx); ret = MSM_PCIE_ERROR; } else { msm_pcie_dev[rc_idx].disable_pc = true; } spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); break; case MSM_PCIE_ENABLE_PC: PCIE_DBG(&msm_pcie_dev[rc_idx], "User of RC%d cancels the request of alive link.\n", rc_idx); spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); msm_pcie_dev[rc_idx].disable_pc = false; spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock, msm_pcie_dev[rc_idx].irqsave_flags); break; default: PCIE_ERR(&msm_pcie_dev[rc_idx], "PCIe: RC%d: unsupported pm operation:%d.\n", Loading
include/linux/msm_pcie.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ enum msm_pcie_config { enum msm_pcie_pm_opt { MSM_PCIE_SUSPEND, MSM_PCIE_RESUME MSM_PCIE_RESUME, MSM_PCIE_DISABLE_PC, MSM_PCIE_ENABLE_PC, }; enum msm_pcie_event { Loading