Loading Documentation/devicetree/bindings/pci/msm_ep_pcie.txt +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ Optional Properties: - qcom,phy-status-reg: Register offset for PHY status. - qcom,dbi-base-reg: Register offset for DBI base address. - qcom,slv-space-reg: Register offset for slave address space size. - qcom,pcie-vendor-id: Vendor id to be written to the Vendor ID register. - qcom,pcie-device-id: Device id to be written to the Device ID register. - qcom,pcie-link-speed: generation of PCIe link speed. The value could be 1, 2 or 3. - qcom,pcie-active-config: boolean type; active configuration of PCIe Loading drivers/platform/msm/ep_pcie/ep_pcie_com.h +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ #define PCIE20_ELBI_CS2_ENABLE 0xA4 #define PCIE20_DEVICE_ID_VENDOR_ID 0x00 #define PCIE20_MASK_DEVICE_ID GENMASK(31, 16) #define PCIE20_MASK_VENDOR_ID GENMASK(15, 0) #define PCIE20_COMMAND_STATUS 0x04 #define PCIE20_CLASS_CODE_REVISION_ID 0x08 #define PCIE20_BIST_HDR_TYPE 0x0C Loading Loading @@ -328,6 +330,8 @@ struct ep_pcie_dev_t { struct msm_bus_scale_pdata *bus_scale_table; u32 bus_client; u16 vendor_id; u16 device_id; u32 link_speed; bool active_config; bool aggregated_irq; Loading drivers/platform/msm/ep_pcie/ep_pcie_core.c +35 −0 Original line number Diff line number Diff line Loading @@ -659,6 +659,17 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) ep_pcie_write_mask(dev->dm_core + PCIE20_MISC_CONTROL_1, 0, BIT(0)); /* Set Vendor ID and Device ID */ if (ep_pcie_dev.device_id != 0xFFFF) ep_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_ID_VENDOR_ID, PCIE20_MASK_DEVICE_ID, ep_pcie_dev.device_id); if (ep_pcie_dev.vendor_id != 0xFFFF) ep_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_ID_VENDOR_ID, PCIE20_MASK_VENDOR_ID, ep_pcie_dev.vendor_id); /* Set class code and revision ID */ ep_pcie_write_reg(dev->dm_core, PCIE20_CLASS_CODE_REVISION_ID, 0xff000000); Loading Loading @@ -2512,6 +2523,30 @@ static int ep_pcie_probe(struct platform_device *pdev) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-link-speed:%d\n", ep_pcie_dev.rev, ep_pcie_dev.link_speed); ep_pcie_dev.vendor_id = 0xFFFF; ret = of_property_read_u16((&pdev->dev)->of_node, "qcom,pcie-vendor-id", &ep_pcie_dev.vendor_id); if (ret) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id does not exist.\n", ep_pcie_dev.rev); else EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id:%d.\n", ep_pcie_dev.rev, ep_pcie_dev.vendor_id); ep_pcie_dev.device_id = 0xFFFF; ret = of_property_read_u16((&pdev->dev)->of_node, "qcom,pcie-device-id", &ep_pcie_dev.device_id); if (ret) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id does not exist.\n", ep_pcie_dev.rev); else EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id:%d.\n", ep_pcie_dev.rev, ep_pcie_dev.device_id); ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,dbi-base-reg", &ep_pcie_dev.dbi_base_reg); Loading drivers/platform/msm/mhi_dev/mhi.c +62 −35 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) uint32_t bhi_imgtxdb; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; void *mhi_ipc_log; Loading Loading @@ -1243,8 +1244,6 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, struct mhi_addr host_addr; struct mhi_dev_channel *ch; struct mhi_dev_ring *ring; char *connected[2] = { "MHI_CHANNEL_STATE_12=CONNECTED", NULL}; char *disconnected[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL}; union mhi_dev_ring_ctx *evt_ctx; ch_id = el->generic.chid; Loading Loading @@ -1349,9 +1348,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mhi_update_state_info(ch_id, MHI_STATE_CONNECTED); /* Trigger callback to clients */ mhi_dev_trigger_cb(ch_id); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, connected); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_CONNECTED); break; case MHI_DEV_RING_EL_STOP: if (ch_id >= HW_CHANNEL_BASE) { Loading Loading @@ -1405,9 +1402,10 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mutex_unlock(&ch->ch_lock); mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected); /* Trigger callback to clients */ mhi_dev_trigger_cb(ch_id); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_DISCONNECTED); } break; case MHI_DEV_RING_EL_RESET: Loading Loading @@ -1481,9 +1479,9 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, pr_err("Error sending command completion event\n"); mutex_unlock(&ch->ch_lock); mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected); mhi_dev_trigger_cb(ch_id); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_DISCONNECTED); } break; default: Loading Loading @@ -1646,13 +1644,28 @@ static void mhi_dev_check_channel_interrupt(struct mhi_dev *mhi) } } static void mhi_update_state_info_all(enum mhi_ctrl_info info) { int i; struct mhi_dev_client_cb_reason reason; mhi_ctx->ctrl_info = info; for (i = 0; i < MHI_MAX_CHANNELS; ++i) { channel_state_info[i].ctrl_info = info; /* Notify kernel clients */ mhi_dev_trigger_cb(i); } /* For legacy reasons for QTI client */ reason.reason = MHI_DEV_CTRL_UPDATE; uci_ctrl_update(&reason); } static int mhi_dev_abort(struct mhi_dev *mhi) { struct mhi_dev_channel *ch; struct mhi_dev_ring *ring; int ch_id = 0, rc = 0; char *disconnected_12[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL}; char *disconnected_14[2] = { "MHI_CHANNEL_STATE_14=DISCONNECTED", NULL}; /* Hard stop all the channels */ for (ch_id = 0; ch_id < mhi->cfg.channels; ch_id++) { Loading @@ -1666,19 +1679,9 @@ static int mhi_dev_abort(struct mhi_dev *mhi) mutex_unlock(&ch->ch_lock); } /* Update ctrl node */ mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_DISCONNECTED); mhi_update_state_info(MHI_CLIENT_MBIM_OUT, MHI_STATE_DISCONNECTED); mhi_update_state_info(MHI_CLIENT_QMI_OUT, MHI_STATE_DISCONNECTED); rc = kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected_12); if (rc) pr_err("Error sending uevent:%d\n", rc); rc = kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected_14); if (rc) pr_err("Error sending uevent:%d\n", rc); /* Update channel state and notify clients */ mhi_update_state_info_all(MHI_STATE_DISCONNECTED); mhi_uci_chan_state_notify_all(mhi, MHI_STATE_DISCONNECTED); flush_workqueue(mhi->ring_init_wq); flush_workqueue(mhi->pending_ring_wq); Loading Loading @@ -1818,8 +1821,7 @@ static void mhi_dev_scheduler(struct work_struct *work) struct mhi_dev_ring *ring; enum mhi_dev_state state; enum mhi_dev_event event = 0; bool mhi_reset = false; uint32_t bhi_imgtxdb = 0; u32 mhi_reset; mutex_lock(&mhi_ctx->mhi_lock); /* Check for interrupts */ Loading @@ -1828,6 +1830,10 @@ static void mhi_dev_scheduler(struct work_struct *work) if (int_value & MHI_MMIO_CTRL_INT_STATUS_A7_MSK) { mhi_log(MHI_MSG_VERBOSE, "processing ctrl interrupt with %d\n", int_value); rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb); mhi_log(MHI_MSG_DBG, "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb); rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset); if (rc) { pr_err("%s: get mhi state failed\n", __func__); Loading Loading @@ -1857,10 +1863,6 @@ static void mhi_dev_scheduler(struct work_struct *work) pr_err("error sending SM event\n"); goto fail; } rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb); mhi_log(MHI_MSG_VERBOSE, "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb); } if (int_value & MHI_MMIO_CTRL_CRDB_STATUS_MSK) { Loading Loading @@ -2677,7 +2679,7 @@ static int mhi_dev_recover(struct mhi_dev *mhi) { int rc = 0; uint32_t syserr, max_cnt = 0, bhi_intvec = 0; bool mhi_reset; u32 mhi_reset; enum mhi_dev_state state; /* Check if MHI is in syserr */ Loading @@ -2687,6 +2689,16 @@ static int mhi_dev_recover(struct mhi_dev *mhi) mhi_log(MHI_MSG_VERBOSE, "mhi_syserr = 0x%X\n", syserr); if (syserr) { /* Poll for the host to set the reset bit */ rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset); if (rc) { pr_err("%s: get mhi state failed\n", __func__); return rc; } mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n", state, mhi_reset); rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec); if (rc) return rc; Loading @@ -2706,7 +2718,11 @@ static int mhi_dev_recover(struct mhi_dev *mhi) pr_err("%s: get mhi state failed\n", __func__); return rc; } while (mhi_reset != true && max_cnt < MHI_SUSPEND_TIMEOUT) { mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n", state, mhi_reset); while (mhi_reset != 0x1 && max_cnt < MHI_SUSPEND_TIMEOUT) { /* Wait for Host to set the reset */ msleep(MHI_SUSPEND_MIN); rc = mhi_dev_mmio_get_mhi_state(mhi, &state, Loading Loading @@ -2737,7 +2753,7 @@ static void mhi_dev_enable(struct work_struct *work) struct ep_pcie_msi_config msi_cfg; struct mhi_dev *mhi = container_of(work, struct mhi_dev, ring_init_cb_work); bool mhi_reset; u32 mhi_reset; enum mhi_dev_state state; uint32_t max_cnt = 0, bhi_intvec = 0; Loading Loading @@ -3215,6 +3231,15 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) struct platform_device *pdev; int rc = 0; /* * There could be multiple calls to this function if device gets * multiple link-up events (bme irqs). */ if (mhi_ctx->init_done) { mhi_log(MHI_MSG_INFO, "mhi init already done, returning\n"); return 0; } pdev = mhi_ctx->pdev; INIT_WORK(&mhi_ctx->chdb_ctrl_work, mhi_dev_scheduler); Loading Loading @@ -3346,6 +3371,8 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) if (mhi_ctx->use_edma) mhi_ring_init_cb(mhi_ctx); mhi_ctx->init_done = true; return 0; } Loading drivers/platform/msm/mhi_dev/mhi.h +18 −2 Original line number Diff line number Diff line Loading @@ -567,6 +567,9 @@ struct mhi_dev { /* iATU is required to map control and data region */ bool config_iatu; /* Indicates if mhi init is done */ bool init_done; /* MHI state info */ enum mhi_ctrl_info ctrl_info; Loading Loading @@ -606,6 +609,7 @@ enum mhi_msg_level { MHI_MSG_reserved = 0x80000000 }; extern uint32_t bhi_imgtxdb; extern enum mhi_msg_level mhi_msg_lvl; extern enum mhi_msg_level mhi_ipc_msg_lvl; extern void *mhi_ipc_log; Loading @@ -616,7 +620,7 @@ extern void *mhi_ipc_log; } \ if (mhi_ipc_log && (_msg_lvl >= mhi_ipc_msg_lvl)) { \ ipc_log_string(mhi_ipc_log, \ "[%s] " _msg, __func__, ##__VA_ARGS__); \ "[0x%x %s] " _msg, bhi_imgtxdb, __func__, ##__VA_ARGS__); \ } \ } while (0) Loading Loading @@ -959,7 +963,7 @@ int mhi_dev_get_mhi_addr(struct mhi_dev *dev); * @mhi_reset: MHI device reset from host. */ int mhi_dev_mmio_get_mhi_state(struct mhi_dev *dev, enum mhi_dev_state *state, bool *mhi_reset); u32 *mhi_reset); /** * mhi_dev_mmio_init() - Initializes the MMIO and reads the Number of event Loading Loading @@ -1069,5 +1073,17 @@ int mhi_dev_net_interface_init(void); void mhi_dev_notify_a7_event(struct mhi_dev *mhi); void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason); /** * mhi_uci_chan_state_notify_all - Notifies channel state updates for * all clients who have uevents enabled. */ void mhi_uci_chan_state_notify_all(struct mhi_dev *mhi, enum mhi_ctrl_info ch_state); /** * mhi_uci_chan_state_notify - Notifies channel state update to the client * if uevents are enabled. */ void mhi_uci_chan_state_notify(struct mhi_dev *mhi, enum mhi_client_channel ch_id, enum mhi_ctrl_info ch_state); #endif /* _MHI_H */ Loading
Documentation/devicetree/bindings/pci/msm_ep_pcie.txt +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ Optional Properties: - qcom,phy-status-reg: Register offset for PHY status. - qcom,dbi-base-reg: Register offset for DBI base address. - qcom,slv-space-reg: Register offset for slave address space size. - qcom,pcie-vendor-id: Vendor id to be written to the Vendor ID register. - qcom,pcie-device-id: Device id to be written to the Device ID register. - qcom,pcie-link-speed: generation of PCIe link speed. The value could be 1, 2 or 3. - qcom,pcie-active-config: boolean type; active configuration of PCIe Loading
drivers/platform/msm/ep_pcie/ep_pcie_com.h +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ #define PCIE20_ELBI_CS2_ENABLE 0xA4 #define PCIE20_DEVICE_ID_VENDOR_ID 0x00 #define PCIE20_MASK_DEVICE_ID GENMASK(31, 16) #define PCIE20_MASK_VENDOR_ID GENMASK(15, 0) #define PCIE20_COMMAND_STATUS 0x04 #define PCIE20_CLASS_CODE_REVISION_ID 0x08 #define PCIE20_BIST_HDR_TYPE 0x0C Loading Loading @@ -328,6 +330,8 @@ struct ep_pcie_dev_t { struct msm_bus_scale_pdata *bus_scale_table; u32 bus_client; u16 vendor_id; u16 device_id; u32 link_speed; bool active_config; bool aggregated_irq; Loading
drivers/platform/msm/ep_pcie/ep_pcie_core.c +35 −0 Original line number Diff line number Diff line Loading @@ -659,6 +659,17 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) ep_pcie_write_mask(dev->dm_core + PCIE20_MISC_CONTROL_1, 0, BIT(0)); /* Set Vendor ID and Device ID */ if (ep_pcie_dev.device_id != 0xFFFF) ep_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_ID_VENDOR_ID, PCIE20_MASK_DEVICE_ID, ep_pcie_dev.device_id); if (ep_pcie_dev.vendor_id != 0xFFFF) ep_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_ID_VENDOR_ID, PCIE20_MASK_VENDOR_ID, ep_pcie_dev.vendor_id); /* Set class code and revision ID */ ep_pcie_write_reg(dev->dm_core, PCIE20_CLASS_CODE_REVISION_ID, 0xff000000); Loading Loading @@ -2512,6 +2523,30 @@ static int ep_pcie_probe(struct platform_device *pdev) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-link-speed:%d\n", ep_pcie_dev.rev, ep_pcie_dev.link_speed); ep_pcie_dev.vendor_id = 0xFFFF; ret = of_property_read_u16((&pdev->dev)->of_node, "qcom,pcie-vendor-id", &ep_pcie_dev.vendor_id); if (ret) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id does not exist.\n", ep_pcie_dev.rev); else EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id:%d.\n", ep_pcie_dev.rev, ep_pcie_dev.vendor_id); ep_pcie_dev.device_id = 0xFFFF; ret = of_property_read_u16((&pdev->dev)->of_node, "qcom,pcie-device-id", &ep_pcie_dev.device_id); if (ret) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id does not exist.\n", ep_pcie_dev.rev); else EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id:%d.\n", ep_pcie_dev.rev, ep_pcie_dev.device_id); ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,dbi-base-reg", &ep_pcie_dev.dbi_base_reg); Loading
drivers/platform/msm/mhi_dev/mhi.c +62 −35 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) uint32_t bhi_imgtxdb; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; void *mhi_ipc_log; Loading Loading @@ -1243,8 +1244,6 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, struct mhi_addr host_addr; struct mhi_dev_channel *ch; struct mhi_dev_ring *ring; char *connected[2] = { "MHI_CHANNEL_STATE_12=CONNECTED", NULL}; char *disconnected[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL}; union mhi_dev_ring_ctx *evt_ctx; ch_id = el->generic.chid; Loading Loading @@ -1349,9 +1348,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mhi_update_state_info(ch_id, MHI_STATE_CONNECTED); /* Trigger callback to clients */ mhi_dev_trigger_cb(ch_id); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, connected); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_CONNECTED); break; case MHI_DEV_RING_EL_STOP: if (ch_id >= HW_CHANNEL_BASE) { Loading Loading @@ -1405,9 +1402,10 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mutex_unlock(&ch->ch_lock); mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected); /* Trigger callback to clients */ mhi_dev_trigger_cb(ch_id); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_DISCONNECTED); } break; case MHI_DEV_RING_EL_RESET: Loading Loading @@ -1481,9 +1479,9 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi, pr_err("Error sending command completion event\n"); mutex_unlock(&ch->ch_lock); mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED); if (ch_id == MHI_CLIENT_MBIM_OUT) kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected); mhi_dev_trigger_cb(ch_id); mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_DISCONNECTED); } break; default: Loading Loading @@ -1646,13 +1644,28 @@ static void mhi_dev_check_channel_interrupt(struct mhi_dev *mhi) } } static void mhi_update_state_info_all(enum mhi_ctrl_info info) { int i; struct mhi_dev_client_cb_reason reason; mhi_ctx->ctrl_info = info; for (i = 0; i < MHI_MAX_CHANNELS; ++i) { channel_state_info[i].ctrl_info = info; /* Notify kernel clients */ mhi_dev_trigger_cb(i); } /* For legacy reasons for QTI client */ reason.reason = MHI_DEV_CTRL_UPDATE; uci_ctrl_update(&reason); } static int mhi_dev_abort(struct mhi_dev *mhi) { struct mhi_dev_channel *ch; struct mhi_dev_ring *ring; int ch_id = 0, rc = 0; char *disconnected_12[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL}; char *disconnected_14[2] = { "MHI_CHANNEL_STATE_14=DISCONNECTED", NULL}; /* Hard stop all the channels */ for (ch_id = 0; ch_id < mhi->cfg.channels; ch_id++) { Loading @@ -1666,19 +1679,9 @@ static int mhi_dev_abort(struct mhi_dev *mhi) mutex_unlock(&ch->ch_lock); } /* Update ctrl node */ mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_DISCONNECTED); mhi_update_state_info(MHI_CLIENT_MBIM_OUT, MHI_STATE_DISCONNECTED); mhi_update_state_info(MHI_CLIENT_QMI_OUT, MHI_STATE_DISCONNECTED); rc = kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected_12); if (rc) pr_err("Error sending uevent:%d\n", rc); rc = kobject_uevent_env(&mhi_ctx->dev->kobj, KOBJ_CHANGE, disconnected_14); if (rc) pr_err("Error sending uevent:%d\n", rc); /* Update channel state and notify clients */ mhi_update_state_info_all(MHI_STATE_DISCONNECTED); mhi_uci_chan_state_notify_all(mhi, MHI_STATE_DISCONNECTED); flush_workqueue(mhi->ring_init_wq); flush_workqueue(mhi->pending_ring_wq); Loading Loading @@ -1818,8 +1821,7 @@ static void mhi_dev_scheduler(struct work_struct *work) struct mhi_dev_ring *ring; enum mhi_dev_state state; enum mhi_dev_event event = 0; bool mhi_reset = false; uint32_t bhi_imgtxdb = 0; u32 mhi_reset; mutex_lock(&mhi_ctx->mhi_lock); /* Check for interrupts */ Loading @@ -1828,6 +1830,10 @@ static void mhi_dev_scheduler(struct work_struct *work) if (int_value & MHI_MMIO_CTRL_INT_STATUS_A7_MSK) { mhi_log(MHI_MSG_VERBOSE, "processing ctrl interrupt with %d\n", int_value); rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb); mhi_log(MHI_MSG_DBG, "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb); rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset); if (rc) { pr_err("%s: get mhi state failed\n", __func__); Loading Loading @@ -1857,10 +1863,6 @@ static void mhi_dev_scheduler(struct work_struct *work) pr_err("error sending SM event\n"); goto fail; } rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb); mhi_log(MHI_MSG_VERBOSE, "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb); } if (int_value & MHI_MMIO_CTRL_CRDB_STATUS_MSK) { Loading Loading @@ -2677,7 +2679,7 @@ static int mhi_dev_recover(struct mhi_dev *mhi) { int rc = 0; uint32_t syserr, max_cnt = 0, bhi_intvec = 0; bool mhi_reset; u32 mhi_reset; enum mhi_dev_state state; /* Check if MHI is in syserr */ Loading @@ -2687,6 +2689,16 @@ static int mhi_dev_recover(struct mhi_dev *mhi) mhi_log(MHI_MSG_VERBOSE, "mhi_syserr = 0x%X\n", syserr); if (syserr) { /* Poll for the host to set the reset bit */ rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset); if (rc) { pr_err("%s: get mhi state failed\n", __func__); return rc; } mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n", state, mhi_reset); rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec); if (rc) return rc; Loading @@ -2706,7 +2718,11 @@ static int mhi_dev_recover(struct mhi_dev *mhi) pr_err("%s: get mhi state failed\n", __func__); return rc; } while (mhi_reset != true && max_cnt < MHI_SUSPEND_TIMEOUT) { mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n", state, mhi_reset); while (mhi_reset != 0x1 && max_cnt < MHI_SUSPEND_TIMEOUT) { /* Wait for Host to set the reset */ msleep(MHI_SUSPEND_MIN); rc = mhi_dev_mmio_get_mhi_state(mhi, &state, Loading Loading @@ -2737,7 +2753,7 @@ static void mhi_dev_enable(struct work_struct *work) struct ep_pcie_msi_config msi_cfg; struct mhi_dev *mhi = container_of(work, struct mhi_dev, ring_init_cb_work); bool mhi_reset; u32 mhi_reset; enum mhi_dev_state state; uint32_t max_cnt = 0, bhi_intvec = 0; Loading Loading @@ -3215,6 +3231,15 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) struct platform_device *pdev; int rc = 0; /* * There could be multiple calls to this function if device gets * multiple link-up events (bme irqs). */ if (mhi_ctx->init_done) { mhi_log(MHI_MSG_INFO, "mhi init already done, returning\n"); return 0; } pdev = mhi_ctx->pdev; INIT_WORK(&mhi_ctx->chdb_ctrl_work, mhi_dev_scheduler); Loading Loading @@ -3346,6 +3371,8 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx) if (mhi_ctx->use_edma) mhi_ring_init_cb(mhi_ctx); mhi_ctx->init_done = true; return 0; } Loading
drivers/platform/msm/mhi_dev/mhi.h +18 −2 Original line number Diff line number Diff line Loading @@ -567,6 +567,9 @@ struct mhi_dev { /* iATU is required to map control and data region */ bool config_iatu; /* Indicates if mhi init is done */ bool init_done; /* MHI state info */ enum mhi_ctrl_info ctrl_info; Loading Loading @@ -606,6 +609,7 @@ enum mhi_msg_level { MHI_MSG_reserved = 0x80000000 }; extern uint32_t bhi_imgtxdb; extern enum mhi_msg_level mhi_msg_lvl; extern enum mhi_msg_level mhi_ipc_msg_lvl; extern void *mhi_ipc_log; Loading @@ -616,7 +620,7 @@ extern void *mhi_ipc_log; } \ if (mhi_ipc_log && (_msg_lvl >= mhi_ipc_msg_lvl)) { \ ipc_log_string(mhi_ipc_log, \ "[%s] " _msg, __func__, ##__VA_ARGS__); \ "[0x%x %s] " _msg, bhi_imgtxdb, __func__, ##__VA_ARGS__); \ } \ } while (0) Loading Loading @@ -959,7 +963,7 @@ int mhi_dev_get_mhi_addr(struct mhi_dev *dev); * @mhi_reset: MHI device reset from host. */ int mhi_dev_mmio_get_mhi_state(struct mhi_dev *dev, enum mhi_dev_state *state, bool *mhi_reset); u32 *mhi_reset); /** * mhi_dev_mmio_init() - Initializes the MMIO and reads the Number of event Loading Loading @@ -1069,5 +1073,17 @@ int mhi_dev_net_interface_init(void); void mhi_dev_notify_a7_event(struct mhi_dev *mhi); void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason); /** * mhi_uci_chan_state_notify_all - Notifies channel state updates for * all clients who have uevents enabled. */ void mhi_uci_chan_state_notify_all(struct mhi_dev *mhi, enum mhi_ctrl_info ch_state); /** * mhi_uci_chan_state_notify - Notifies channel state update to the client * if uevents are enabled. */ void mhi_uci_chan_state_notify(struct mhi_dev *mhi, enum mhi_client_channel ch_id, enum mhi_ctrl_info ch_state); #endif /* _MHI_H */