Loading arch/arm/mach-msm/include/mach/msm_pcie.h +12 −0 Original line number Diff line number Diff line Loading @@ -14,11 +14,13 @@ #define __ASM_ARCH_MSM_PCIE_H #include <linux/types.h> #include <linux/pci.h> enum msm_pcie_config { MSM_PCIE_CONFIG_INVALID = 0, MSM_PCIE_CONFIG_NO_CFG_RESTORE = 0x1, MSM_PCIE_CONFIG_LINKDOWN = 0x2, MSM_PCIE_CONFIG_NO_RECOVERY = 0x4, }; enum msm_pcie_pm_opt { Loading Loading @@ -91,4 +93,14 @@ int msm_pcie_register_event(struct msm_pcie_register_event *reg); * Return: 0 on success, negative value on error */ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg); /** * msm_pcie_recover_config - recover config space. * @dev: pci device structure * * This function recovers the config space of both RC and Endpoint. * * Return: 0 on success, negative value on error */ int msm_pcie_recover_config(struct pci_dev *dev); #endif arch/arm/mach-msm/pcie.c +35 −0 Original line number Diff line number Diff line Loading @@ -2020,3 +2020,38 @@ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg) return ret; } EXPORT_SYMBOL(msm_pcie_deregister_event); int msm_pcie_recover_config(struct pci_dev *dev) { int ret = 0; struct msm_pcie_dev_t *pcie_dev; PCIE_DBG("\n"); if (dev) { pcie_dev = PCIE_BUS_PRIV_DATA(dev); PCIE_DBG("Recovery for the link of RC%d\n", pcie_dev->rc_idx); } else { pr_err("PCIe: the input pci dev is NULL.\n"); return -ENODEV; } if (msm_pcie_confirm_linkup(pcie_dev)) { PCIE_DBG("Recover config space of RC%d and its EP\n", pcie_dev->rc_idx); pcie_dev->shadow_en = false; PCIE_DBG("Recover RC%d\n", pcie_dev->rc_idx); msm_pcie_cfg_recover(pcie_dev, true); PCIE_DBG("Recover EP of RC%d\n", pcie_dev->rc_idx); msm_pcie_cfg_recover(pcie_dev, false); pcie_dev->shadow_en = true; } else { pr_err( "PCIe: the link of RC%d is not up yet; can't recover config space.\n", pcie_dev->rc_idx); ret = -ENODEV; } return ret; } EXPORT_SYMBOL(msm_pcie_recover_config); arch/arm/mach-msm/pcie_irq.c +9 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ static void handle_linkdown_func(struct work_struct *work) PCIE_DBG("PCIe: Linkdown callback for RC%d\n", dev->rc_idx); dev->event_reg->callback(notify); if (dev->event_reg->options & MSM_PCIE_CONFIG_NO_RECOVERY) { dev->user_suspend = true; PCIE_DBG( "PCIe: Client of RC%d will recover the link later.\n", dev->rc_idx); goto out; } if (dev->link_status == MSM_PCIE_LINK_DISABLED) { PCIE_DBG( "PCIe: Client of RC%d does not enable link in callback; so disable the link\n", Loading Loading @@ -258,6 +266,7 @@ static void handle_linkdown_func(struct work_struct *work) dev->rc_idx); } out: dev->handling_linkdown--; if (dev->handling_linkdown < 0) pr_err("PCIe:handling_linkdown for RC%d is %d\n", Loading Loading
arch/arm/mach-msm/include/mach/msm_pcie.h +12 −0 Original line number Diff line number Diff line Loading @@ -14,11 +14,13 @@ #define __ASM_ARCH_MSM_PCIE_H #include <linux/types.h> #include <linux/pci.h> enum msm_pcie_config { MSM_PCIE_CONFIG_INVALID = 0, MSM_PCIE_CONFIG_NO_CFG_RESTORE = 0x1, MSM_PCIE_CONFIG_LINKDOWN = 0x2, MSM_PCIE_CONFIG_NO_RECOVERY = 0x4, }; enum msm_pcie_pm_opt { Loading Loading @@ -91,4 +93,14 @@ int msm_pcie_register_event(struct msm_pcie_register_event *reg); * Return: 0 on success, negative value on error */ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg); /** * msm_pcie_recover_config - recover config space. * @dev: pci device structure * * This function recovers the config space of both RC and Endpoint. * * Return: 0 on success, negative value on error */ int msm_pcie_recover_config(struct pci_dev *dev); #endif
arch/arm/mach-msm/pcie.c +35 −0 Original line number Diff line number Diff line Loading @@ -2020,3 +2020,38 @@ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg) return ret; } EXPORT_SYMBOL(msm_pcie_deregister_event); int msm_pcie_recover_config(struct pci_dev *dev) { int ret = 0; struct msm_pcie_dev_t *pcie_dev; PCIE_DBG("\n"); if (dev) { pcie_dev = PCIE_BUS_PRIV_DATA(dev); PCIE_DBG("Recovery for the link of RC%d\n", pcie_dev->rc_idx); } else { pr_err("PCIe: the input pci dev is NULL.\n"); return -ENODEV; } if (msm_pcie_confirm_linkup(pcie_dev)) { PCIE_DBG("Recover config space of RC%d and its EP\n", pcie_dev->rc_idx); pcie_dev->shadow_en = false; PCIE_DBG("Recover RC%d\n", pcie_dev->rc_idx); msm_pcie_cfg_recover(pcie_dev, true); PCIE_DBG("Recover EP of RC%d\n", pcie_dev->rc_idx); msm_pcie_cfg_recover(pcie_dev, false); pcie_dev->shadow_en = true; } else { pr_err( "PCIe: the link of RC%d is not up yet; can't recover config space.\n", pcie_dev->rc_idx); ret = -ENODEV; } return ret; } EXPORT_SYMBOL(msm_pcie_recover_config);
arch/arm/mach-msm/pcie_irq.c +9 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ static void handle_linkdown_func(struct work_struct *work) PCIE_DBG("PCIe: Linkdown callback for RC%d\n", dev->rc_idx); dev->event_reg->callback(notify); if (dev->event_reg->options & MSM_PCIE_CONFIG_NO_RECOVERY) { dev->user_suspend = true; PCIE_DBG( "PCIe: Client of RC%d will recover the link later.\n", dev->rc_idx); goto out; } if (dev->link_status == MSM_PCIE_LINK_DISABLED) { PCIE_DBG( "PCIe: Client of RC%d does not enable link in callback; so disable the link\n", Loading Loading @@ -258,6 +266,7 @@ static void handle_linkdown_func(struct work_struct *work) dev->rc_idx); } out: dev->handling_linkdown--; if (dev->handling_linkdown < 0) pr_err("PCIe:handling_linkdown for RC%d is %d\n", Loading