Loading drivers/pci/controller/pci-msm.c +44 −10 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/uaccess.h> #include <soc/qcom/subsystem_notif.h> #include "../pci.h" Loading Loading @@ -66,6 +67,10 @@ #define PCIE20_PARF_L1SUB_AHB_CLK_MAX_TIMER (0x180) #define PCIE20_PARF_DEBUG_INT_EN (0x190) #define PCIE20_PARF_CLKREQ_OVERRIDE (0x2b0) #define PCIE20_PARF_CLKREQ_IN_VALUE (BIT(3)) #define PCIE20_PARF_CLKREQ_IN_ENABLE (BIT(1)) #define PCIE20_ELBI_SYS_CTRL (0x04) #define PCIE20_ELBI_SYS_STTS (0x08) Loading Loading @@ -6531,36 +6536,45 @@ static int msm_pcie_drv_rpmsg_probe(struct rpmsg_device *rpdev) return 0; } static void msm_pcie_drv_rpmsg_remove(struct rpmsg_device *rpdev) static void msm_pcie_drv_notify_client(struct pcie_drv_sta *pcie_drv, enum msm_pcie_event event) { struct pcie_drv_sta *pcie_drv = dev_get_drvdata(&rpdev->dev); struct msm_pcie_dev_t *pcie_dev = pcie_drv->msm_pcie_dev; int i; pcie_drv->rpdev = NULL; flush_work(&pcie_drv->drv_connect); for (i = 0; i < MAX_RC_NUM; i++, pcie_dev++) { struct msm_pcie_drv_info *drv_info = pcie_dev->drv_info; struct msm_pcie_register_event *event_reg = pcie_dev->event_reg; PCIE_DBG(pcie_dev, "PCIe: RC%d: event %d received\n", pcie_dev->rc_idx, event); /* does not support DRV or has not been probed yet */ if (!drv_info) continue; if (!event_reg || !(event_reg->events & MSM_PCIE_EVENT_DRV_DISCONNECT)) if (!event_reg || !(event_reg->events & event)) continue; if (drv_info->ep_connected) { msm_pcie_notify_client(pcie_dev, MSM_PCIE_EVENT_DRV_DISCONNECT); msm_pcie_notify_client(pcie_dev, event); if (event & MSM_PCIE_EVENT_DRV_DISCONNECT) drv_info->ep_connected = false; } } } static void msm_pcie_drv_rpmsg_remove(struct rpmsg_device *rpdev) { struct pcie_drv_sta *pcie_drv = dev_get_drvdata(&rpdev->dev); pcie_drv->rpdev = NULL; flush_work(&pcie_drv->drv_connect); msm_pcie_drv_notify_client(pcie_drv, MSM_PCIE_EVENT_DRV_DISCONNECT); } static int msm_pcie_drv_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { Loading Loading @@ -6667,6 +6681,15 @@ static struct rpmsg_driver msm_pcie_drv_rpmsg_driver = { }, }; static void msm_pcie_early_notifier(void *data) { struct pcie_drv_sta *pcie_drv = data; pcie_drv->rpdev = NULL; msm_pcie_drv_notify_client(pcie_drv, MSM_PCIE_EVENT_WAKEUP); }; static void msm_pcie_drv_connect_worker(struct work_struct *work) { struct pcie_drv_sta *pcie_drv = container_of(work, struct pcie_drv_sta, Loading Loading @@ -6699,6 +6722,9 @@ static void msm_pcie_drv_connect_worker(struct work_struct *work) MSM_PCIE_EVENT_DRV_CONNECT); drv_info->ep_connected = true; } subsys_register_early_notifier("adsp", PCIE_DRV_LAYER_NOTIF, msm_pcie_early_notifier, pcie_drv); } static int __init pcie_init(void) Loading Loading @@ -7139,6 +7165,14 @@ static int msm_pcie_drv_resume(struct msm_pcie_dev_t *pcie_dev) } } /* always ungate clkreq */ msm_pcie_write_reg_field(pcie_dev->parf, PCIE20_PARF_CLKREQ_OVERRIDE, PCIE20_PARF_CLKREQ_IN_ENABLE, 0); msm_pcie_write_reg_field(pcie_dev->parf, PCIE20_PARF_CLKREQ_OVERRIDE, PCIE20_PARF_CLKREQ_IN_VALUE, 0); pcie_dev->user_suspend = false; spin_lock_irq(&pcie_dev->cfg_lock); pcie_dev->cfg_access = true; Loading include/soc/qcom/subsystem_notif.h +1 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ enum subsys_notif_type { enum early_subsys_notif_type { XPORT_LAYER_NOTIF, PCIE_DRV_LAYER_NOTIF, NUM_EARLY_NOTIFS }; Loading Loading
drivers/pci/controller/pci-msm.c +44 −10 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/uaccess.h> #include <soc/qcom/subsystem_notif.h> #include "../pci.h" Loading Loading @@ -66,6 +67,10 @@ #define PCIE20_PARF_L1SUB_AHB_CLK_MAX_TIMER (0x180) #define PCIE20_PARF_DEBUG_INT_EN (0x190) #define PCIE20_PARF_CLKREQ_OVERRIDE (0x2b0) #define PCIE20_PARF_CLKREQ_IN_VALUE (BIT(3)) #define PCIE20_PARF_CLKREQ_IN_ENABLE (BIT(1)) #define PCIE20_ELBI_SYS_CTRL (0x04) #define PCIE20_ELBI_SYS_STTS (0x08) Loading Loading @@ -6531,36 +6536,45 @@ static int msm_pcie_drv_rpmsg_probe(struct rpmsg_device *rpdev) return 0; } static void msm_pcie_drv_rpmsg_remove(struct rpmsg_device *rpdev) static void msm_pcie_drv_notify_client(struct pcie_drv_sta *pcie_drv, enum msm_pcie_event event) { struct pcie_drv_sta *pcie_drv = dev_get_drvdata(&rpdev->dev); struct msm_pcie_dev_t *pcie_dev = pcie_drv->msm_pcie_dev; int i; pcie_drv->rpdev = NULL; flush_work(&pcie_drv->drv_connect); for (i = 0; i < MAX_RC_NUM; i++, pcie_dev++) { struct msm_pcie_drv_info *drv_info = pcie_dev->drv_info; struct msm_pcie_register_event *event_reg = pcie_dev->event_reg; PCIE_DBG(pcie_dev, "PCIe: RC%d: event %d received\n", pcie_dev->rc_idx, event); /* does not support DRV or has not been probed yet */ if (!drv_info) continue; if (!event_reg || !(event_reg->events & MSM_PCIE_EVENT_DRV_DISCONNECT)) if (!event_reg || !(event_reg->events & event)) continue; if (drv_info->ep_connected) { msm_pcie_notify_client(pcie_dev, MSM_PCIE_EVENT_DRV_DISCONNECT); msm_pcie_notify_client(pcie_dev, event); if (event & MSM_PCIE_EVENT_DRV_DISCONNECT) drv_info->ep_connected = false; } } } static void msm_pcie_drv_rpmsg_remove(struct rpmsg_device *rpdev) { struct pcie_drv_sta *pcie_drv = dev_get_drvdata(&rpdev->dev); pcie_drv->rpdev = NULL; flush_work(&pcie_drv->drv_connect); msm_pcie_drv_notify_client(pcie_drv, MSM_PCIE_EVENT_DRV_DISCONNECT); } static int msm_pcie_drv_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { Loading Loading @@ -6667,6 +6681,15 @@ static struct rpmsg_driver msm_pcie_drv_rpmsg_driver = { }, }; static void msm_pcie_early_notifier(void *data) { struct pcie_drv_sta *pcie_drv = data; pcie_drv->rpdev = NULL; msm_pcie_drv_notify_client(pcie_drv, MSM_PCIE_EVENT_WAKEUP); }; static void msm_pcie_drv_connect_worker(struct work_struct *work) { struct pcie_drv_sta *pcie_drv = container_of(work, struct pcie_drv_sta, Loading Loading @@ -6699,6 +6722,9 @@ static void msm_pcie_drv_connect_worker(struct work_struct *work) MSM_PCIE_EVENT_DRV_CONNECT); drv_info->ep_connected = true; } subsys_register_early_notifier("adsp", PCIE_DRV_LAYER_NOTIF, msm_pcie_early_notifier, pcie_drv); } static int __init pcie_init(void) Loading Loading @@ -7139,6 +7165,14 @@ static int msm_pcie_drv_resume(struct msm_pcie_dev_t *pcie_dev) } } /* always ungate clkreq */ msm_pcie_write_reg_field(pcie_dev->parf, PCIE20_PARF_CLKREQ_OVERRIDE, PCIE20_PARF_CLKREQ_IN_ENABLE, 0); msm_pcie_write_reg_field(pcie_dev->parf, PCIE20_PARF_CLKREQ_OVERRIDE, PCIE20_PARF_CLKREQ_IN_VALUE, 0); pcie_dev->user_suspend = false; spin_lock_irq(&pcie_dev->cfg_lock); pcie_dev->cfg_access = true; Loading
include/soc/qcom/subsystem_notif.h +1 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ enum subsys_notif_type { enum early_subsys_notif_type { XPORT_LAYER_NOTIF, PCIE_DRV_LAYER_NOTIF, NUM_EARLY_NOTIFS }; Loading