Loading drivers/platform/msm/ep_pcie/ep_pcie_com.h +3 −0 Original line number Diff line number Diff line Loading @@ -332,10 +332,13 @@ struct ep_pcie_dev_t { bool l23_ready; bool l1ss_enabled; struct ep_pcie_msi_config msi_cfg; bool no_notify; bool client_ready; struct ep_pcie_register_event *event_reg; struct work_struct handle_perst_work; struct work_struct handle_bme_work; struct work_struct handle_d3cold_work; }; extern struct ep_pcie_dev_t ep_pcie_dev; Loading drivers/platform/msm/ep_pcie/ep_pcie_core.c +62 −7 Original line number Diff line number Diff line Loading @@ -1002,6 +1002,10 @@ static void ep_pcie_release_resources(struct ep_pcie_dev_t *dev) static void ep_pcie_enumeration_complete(struct ep_pcie_dev_t *dev) { unsigned long irqsave_flags; spin_lock_irqsave(&dev->isr_lock, irqsave_flags); dev->enumerated = true; dev->link_status = EP_PCIE_LINK_ENABLED; Loading @@ -1028,7 +1032,14 @@ static void ep_pcie_enumeration_complete(struct ep_pcie_dev_t *dev) "PCIe V%d: register driver for device 0x%x.\n", ep_pcie_dev.rev, hw_drv.device_id); ep_pcie_register_drv(&hw_drv); if (!dev->no_notify) ep_pcie_notify_event(dev, EP_PCIE_EVENT_LINKUP); else EP_PCIE_DBG(dev, "PCIe V%d: do not notify client about linkup.\n", dev->rev); spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags); return; } Loading Loading @@ -1528,7 +1539,13 @@ static irqreturn_t ep_pcie_handle_dstate_change_irq(int irq, void *data) "PCIe V%d: No. %ld change to D3 state.\n", dev->rev, dev->d3_counter); ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(1)); if (dev->enumerated) ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_HOT); else EP_PCIE_DBG(dev, "PCIe V%d: do not notify client about this D3 hot event since enumeration by HLOS is not done yet.\n", dev->rev); } else if (dstate == 0) { dev->l23_ready = false; dev->d0_counter++; Loading Loading @@ -1592,9 +1609,25 @@ static void handle_perst_func(struct work_struct *work) struct ep_pcie_dev_t *dev = container_of(work, struct ep_pcie_dev_t, handle_perst_work); EP_PCIE_DBG(dev, "PCIe V%d: Start enumeration due to PERST deassertion.\n", dev->rev); ep_pcie_enumeration(dev); } static void handle_d3cold_func(struct work_struct *work) { struct ep_pcie_dev_t *dev = container_of(work, struct ep_pcie_dev_t, handle_d3cold_work); EP_PCIE_DBG(dev, "PCIe V%d: shutdown PCIe link due to PERST assertion before BME is set.\n", dev->rev); ep_pcie_core_disable_endpoint(); dev->no_notify = false; } static void handle_bme_func(struct work_struct *work) { struct ep_pcie_dev_t *dev = container_of(work, Loading @@ -1617,10 +1650,14 @@ static irqreturn_t ep_pcie_handle_perst_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d: PCIe is not enumerated yet; PERST is %sasserted.\n", dev->rev, perst ? "de" : ""); if ((!dev->perst_enum) || !perst) goto out; if (perst) { /* start work for link enumeration with the host side */ schedule_work(&dev->handle_perst_work); } else { dev->no_notify = true; /* shutdown the link if the link is already on */ schedule_work(&dev->handle_d3cold_work); } goto out; } Loading @@ -1638,7 +1675,16 @@ static irqreturn_t ep_pcie_handle_perst_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d: No. %ld PERST assertion.\n", dev->rev, dev->perst_ast_counter); if (dev->client_ready) { ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_COLD); } else { dev->no_notify = true; EP_PCIE_DBG(dev, "PCIe V%d: Client driver is not ready when this PERST assertion happens; shutdown link now.\n", dev->rev); schedule_work(&dev->handle_d3cold_work); } } out: Loading Loading @@ -1723,6 +1769,7 @@ int32_t ep_pcie_irq_init(struct ep_pcie_dev_t *dev) /* Initialize all works to be performed before registering for IRQs*/ INIT_WORK(&dev->handle_perst_work, handle_perst_func); INIT_WORK(&dev->handle_bme_work, handle_bme_func); INIT_WORK(&dev->handle_d3cold_work, handle_d3cold_func); if (dev->aggregated_irq) { ret = devm_request_irq(pdev, Loading Loading @@ -1876,6 +1923,8 @@ int ep_pcie_core_register_event(struct ep_pcie_register_event *reg) "PCIe V%d: Event 0x%x is registered\n", ep_pcie_dev.rev, reg->events); ep_pcie_dev.client_ready = true; return 0; } Loading Loading @@ -1912,6 +1961,12 @@ enum ep_pcie_link_status ep_pcie_core_get_linkstatus(void) "PCIe V%d: PCIe link is up and BME is enabled; current SW link status:%d.\n", dev->rev, dev->link_status); dev->link_status = EP_PCIE_LINK_ENABLED; if (dev->no_notify) { EP_PCIE_DBG(dev, "PCIe V%d: BME is set now, but do not tell client about BME enable.\n", dev->rev); return EP_PCIE_LINK_UP; } } else { EP_PCIE_DBG(dev, "PCIe V%d: PCIe link is up but BME is disabled; current SW link status:%d.\n", Loading drivers/platform/msm/mhi_dev/mhi.c +23 −9 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static void mhi_ring_init_cb(void *user_data); static void mhi_update_state_info(uint32_t info); static int mhi_deinit(struct mhi_dev *mhi); static void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify); static int mhi_dev_pcie_notify_event; void mhi_dev_read_from_host(struct mhi_dev *mhi, struct mhi_addr *transfer) { Loading Loading @@ -2492,26 +2493,31 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify) { int rc = 0; if (!notify) { if (!notify || !notify->user) { pr_err("Null argument for notify\n"); return; } mhi_ctx = notify->user; if (!mhi_ctx) { pr_err("Invalid mhi_ctx\n"); return; mhi_dev_pcie_notify_event = notify->options; mhi_log(MHI_MSG_INFO, "PCIe event=0x%x\n", notify->options); queue_work(mhi_ctx->pcie_event_wq, &mhi_ctx->pcie_event); } if (notify->options == MHI_INIT) { static void mhi_dev_pcie_handle_event(struct work_struct *work) { struct mhi_dev *mhi_ctx = container_of(work, struct mhi_dev, pcie_event); int rc = 0; if (mhi_dev_pcie_notify_event == MHI_INIT) { rc = mhi_dev_resume_mmio_mhi_init(mhi_ctx); if (rc) { pr_err("Error during MHI device initialization\n"); return; } } else if (notify->options == MHI_REINIT) { } else if (mhi_dev_pcie_notify_event == MHI_REINIT) { rc = mhi_dev_resume_mmio_mhi_reinit(mhi_ctx); if (rc) { pr_err("Error during MHI device re-initialization\n"); Loading Loading @@ -2540,6 +2546,14 @@ static int mhi_dev_probe(struct platform_device *pdev) mhi_update_state_info(MHI_STATE_CONFIGURED); } INIT_WORK(&mhi_ctx->pcie_event, mhi_dev_pcie_handle_event); mhi_ctx->pcie_event_wq = alloc_workqueue("mhi_dev_pcie_event_wq", WQ_HIGHPRI, 0); if (!mhi_ctx->pcie_event_wq) { rc = -ENOMEM; return rc; } mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id); if (mhi_ctx->phandle) { /* PCIe link is already up */ Loading drivers/platform/msm/mhi_dev/mhi.h +2 −0 Original line number Diff line number Diff line Loading @@ -523,9 +523,11 @@ struct mhi_dev { struct work_struct re_init; /* EP PCIe registration */ struct workqueue_struct *pcie_event_wq; struct ep_pcie_register_event event_reg; u32 ifc_id; struct ep_pcie_hw *phandle; struct work_struct pcie_event; atomic_t write_active; atomic_t is_suspended; Loading Loading
drivers/platform/msm/ep_pcie/ep_pcie_com.h +3 −0 Original line number Diff line number Diff line Loading @@ -332,10 +332,13 @@ struct ep_pcie_dev_t { bool l23_ready; bool l1ss_enabled; struct ep_pcie_msi_config msi_cfg; bool no_notify; bool client_ready; struct ep_pcie_register_event *event_reg; struct work_struct handle_perst_work; struct work_struct handle_bme_work; struct work_struct handle_d3cold_work; }; extern struct ep_pcie_dev_t ep_pcie_dev; Loading
drivers/platform/msm/ep_pcie/ep_pcie_core.c +62 −7 Original line number Diff line number Diff line Loading @@ -1002,6 +1002,10 @@ static void ep_pcie_release_resources(struct ep_pcie_dev_t *dev) static void ep_pcie_enumeration_complete(struct ep_pcie_dev_t *dev) { unsigned long irqsave_flags; spin_lock_irqsave(&dev->isr_lock, irqsave_flags); dev->enumerated = true; dev->link_status = EP_PCIE_LINK_ENABLED; Loading @@ -1028,7 +1032,14 @@ static void ep_pcie_enumeration_complete(struct ep_pcie_dev_t *dev) "PCIe V%d: register driver for device 0x%x.\n", ep_pcie_dev.rev, hw_drv.device_id); ep_pcie_register_drv(&hw_drv); if (!dev->no_notify) ep_pcie_notify_event(dev, EP_PCIE_EVENT_LINKUP); else EP_PCIE_DBG(dev, "PCIe V%d: do not notify client about linkup.\n", dev->rev); spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags); return; } Loading Loading @@ -1528,7 +1539,13 @@ static irqreturn_t ep_pcie_handle_dstate_change_irq(int irq, void *data) "PCIe V%d: No. %ld change to D3 state.\n", dev->rev, dev->d3_counter); ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(1)); if (dev->enumerated) ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_HOT); else EP_PCIE_DBG(dev, "PCIe V%d: do not notify client about this D3 hot event since enumeration by HLOS is not done yet.\n", dev->rev); } else if (dstate == 0) { dev->l23_ready = false; dev->d0_counter++; Loading Loading @@ -1592,9 +1609,25 @@ static void handle_perst_func(struct work_struct *work) struct ep_pcie_dev_t *dev = container_of(work, struct ep_pcie_dev_t, handle_perst_work); EP_PCIE_DBG(dev, "PCIe V%d: Start enumeration due to PERST deassertion.\n", dev->rev); ep_pcie_enumeration(dev); } static void handle_d3cold_func(struct work_struct *work) { struct ep_pcie_dev_t *dev = container_of(work, struct ep_pcie_dev_t, handle_d3cold_work); EP_PCIE_DBG(dev, "PCIe V%d: shutdown PCIe link due to PERST assertion before BME is set.\n", dev->rev); ep_pcie_core_disable_endpoint(); dev->no_notify = false; } static void handle_bme_func(struct work_struct *work) { struct ep_pcie_dev_t *dev = container_of(work, Loading @@ -1617,10 +1650,14 @@ static irqreturn_t ep_pcie_handle_perst_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d: PCIe is not enumerated yet; PERST is %sasserted.\n", dev->rev, perst ? "de" : ""); if ((!dev->perst_enum) || !perst) goto out; if (perst) { /* start work for link enumeration with the host side */ schedule_work(&dev->handle_perst_work); } else { dev->no_notify = true; /* shutdown the link if the link is already on */ schedule_work(&dev->handle_d3cold_work); } goto out; } Loading @@ -1638,7 +1675,16 @@ static irqreturn_t ep_pcie_handle_perst_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d: No. %ld PERST assertion.\n", dev->rev, dev->perst_ast_counter); if (dev->client_ready) { ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_COLD); } else { dev->no_notify = true; EP_PCIE_DBG(dev, "PCIe V%d: Client driver is not ready when this PERST assertion happens; shutdown link now.\n", dev->rev); schedule_work(&dev->handle_d3cold_work); } } out: Loading Loading @@ -1723,6 +1769,7 @@ int32_t ep_pcie_irq_init(struct ep_pcie_dev_t *dev) /* Initialize all works to be performed before registering for IRQs*/ INIT_WORK(&dev->handle_perst_work, handle_perst_func); INIT_WORK(&dev->handle_bme_work, handle_bme_func); INIT_WORK(&dev->handle_d3cold_work, handle_d3cold_func); if (dev->aggregated_irq) { ret = devm_request_irq(pdev, Loading Loading @@ -1876,6 +1923,8 @@ int ep_pcie_core_register_event(struct ep_pcie_register_event *reg) "PCIe V%d: Event 0x%x is registered\n", ep_pcie_dev.rev, reg->events); ep_pcie_dev.client_ready = true; return 0; } Loading Loading @@ -1912,6 +1961,12 @@ enum ep_pcie_link_status ep_pcie_core_get_linkstatus(void) "PCIe V%d: PCIe link is up and BME is enabled; current SW link status:%d.\n", dev->rev, dev->link_status); dev->link_status = EP_PCIE_LINK_ENABLED; if (dev->no_notify) { EP_PCIE_DBG(dev, "PCIe V%d: BME is set now, but do not tell client about BME enable.\n", dev->rev); return EP_PCIE_LINK_UP; } } else { EP_PCIE_DBG(dev, "PCIe V%d: PCIe link is up but BME is disabled; current SW link status:%d.\n", Loading
drivers/platform/msm/mhi_dev/mhi.c +23 −9 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static void mhi_ring_init_cb(void *user_data); static void mhi_update_state_info(uint32_t info); static int mhi_deinit(struct mhi_dev *mhi); static void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify); static int mhi_dev_pcie_notify_event; void mhi_dev_read_from_host(struct mhi_dev *mhi, struct mhi_addr *transfer) { Loading Loading @@ -2492,26 +2493,31 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify) { int rc = 0; if (!notify) { if (!notify || !notify->user) { pr_err("Null argument for notify\n"); return; } mhi_ctx = notify->user; if (!mhi_ctx) { pr_err("Invalid mhi_ctx\n"); return; mhi_dev_pcie_notify_event = notify->options; mhi_log(MHI_MSG_INFO, "PCIe event=0x%x\n", notify->options); queue_work(mhi_ctx->pcie_event_wq, &mhi_ctx->pcie_event); } if (notify->options == MHI_INIT) { static void mhi_dev_pcie_handle_event(struct work_struct *work) { struct mhi_dev *mhi_ctx = container_of(work, struct mhi_dev, pcie_event); int rc = 0; if (mhi_dev_pcie_notify_event == MHI_INIT) { rc = mhi_dev_resume_mmio_mhi_init(mhi_ctx); if (rc) { pr_err("Error during MHI device initialization\n"); return; } } else if (notify->options == MHI_REINIT) { } else if (mhi_dev_pcie_notify_event == MHI_REINIT) { rc = mhi_dev_resume_mmio_mhi_reinit(mhi_ctx); if (rc) { pr_err("Error during MHI device re-initialization\n"); Loading Loading @@ -2540,6 +2546,14 @@ static int mhi_dev_probe(struct platform_device *pdev) mhi_update_state_info(MHI_STATE_CONFIGURED); } INIT_WORK(&mhi_ctx->pcie_event, mhi_dev_pcie_handle_event); mhi_ctx->pcie_event_wq = alloc_workqueue("mhi_dev_pcie_event_wq", WQ_HIGHPRI, 0); if (!mhi_ctx->pcie_event_wq) { rc = -ENOMEM; return rc; } mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id); if (mhi_ctx->phandle) { /* PCIe link is already up */ Loading
drivers/platform/msm/mhi_dev/mhi.h +2 −0 Original line number Diff line number Diff line Loading @@ -523,9 +523,11 @@ struct mhi_dev { struct work_struct re_init; /* EP PCIe registration */ struct workqueue_struct *pcie_event_wq; struct ep_pcie_register_event event_reg; u32 ifc_id; struct ep_pcie_hw *phandle; struct work_struct pcie_event; atomic_t write_active; atomic_t is_suspended; Loading