Loading drivers/slimbus/slim-msm-ngd.c +21 −5 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code, /* make sure autosuspend is not called until ADSP comes up*/ pm_runtime_get_noresume(dev->dev); dev->state = MSM_CTRL_DOWN; dev->qmi.deferred_resp = false; msm_slim_sps_exit(dev, false); ngd_dom_down(dev); mutex_unlock(&dev->tx_lock); Loading Loading @@ -2019,19 +2020,18 @@ static int ngd_slim_suspend(struct device *dev) if (!pm_runtime_enabled(dev) || (!pm_runtime_suspended(dev) && cdev->state == MSM_CTRL_IDLE)) { cdev->qmi.deferred_resp = true; ret = ngd_slim_runtime_suspend(dev); /* * If runtime-PM still thinks it's active, then make sure its * status is in sync with HW status. * Since this suspend calls QMI api, it results in holding a * wakelock. That results in failure of first suspend. * Subsequent suspend should not call low-power transition * again since the HW is already in suspended state. */ if (!ret) { pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); } else { cdev->qmi.deferred_resp = false; } } if (ret == -EBUSY) { Loading @@ -2053,13 +2053,29 @@ static int ngd_slim_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev); int ret = 0; /* * If deferred response was requested for power-off and it failed, * mark runtime-pm status as active to be consistent * with HW status */ if (cdev->qmi.deferred_resp) { ret = msm_slim_qmi_deferred_status_req(cdev); if (ret) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); } cdev->qmi.deferred_resp = false; } /* * Rely on runtime-PM to call resume in case it is enabled. * Even if it's not enabled, rely on 1st client transaction to do * clock/power on */ SLIM_INFO(cdev, "system resume\n"); return 0; return ret; } #endif /* CONFIG_PM_SLEEP */ Loading drivers/slimbus/slim-msm.c +141 −12 Original line number Diff line number Diff line Loading @@ -1224,12 +1224,16 @@ void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg) #define SLIMBUS_QMI_POWER_RESP_V01 0x0021 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_REQ 0x0022 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_RESP 0x0022 #define SLIMBUS_QMI_DEFERRED_STATUS_REQ 0x0023 #define SLIMBUS_QMI_DEFERRED_STATUS_RESP 0x0023 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 7 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 14 #define SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN 14 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_CHECK_FRAMER_STAT_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_DEFERRED_STATUS_REQ_MSG_MAX_MSG_LEN 0 #define SLIMBUS_QMI_DEFERRED_STATUS_RESP_STAT_MSG_MAX_MSG_LEN 7 enum slimbus_mode_enum_type_v01 { /* To force a 32 bit signed enum. Do not change or use*/ Loading @@ -1247,6 +1251,13 @@ enum slimbus_pm_enum_type_v01 { SLIMBUS_PM_ENUM_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, }; enum slimbus_resp_enum_type_v01 { SLIMBUS_RESP_ENUM_TYPE_MIN_VAL_V01 = INT_MIN, SLIMBUS_RESP_SYNCHRONOUS_V01 = 1, SLIMBUS_RESP_DEFERRED_V01 = 2, SLIMBUS_RESP_ENUM_TYPE_MAX_VAL_V01 = INT_MAX, }; struct slimbus_select_inst_req_msg_v01 { /* Mandatory */ /* Hardware Instance Selection */ Loading @@ -1269,6 +1280,12 @@ struct slimbus_power_req_msg_v01 { /* Mandatory */ /* Power Request Operation */ enum slimbus_pm_enum_type_v01 pm_req; /* Optional */ /* Optional Deferred Response type Operation */ /* Must be set to true if type is being passed */ uint8_t resp_type_valid; enum slimbus_resp_enum_type_v01 resp_type; }; struct slimbus_power_resp_msg_v01 { Loading @@ -1283,6 +1300,9 @@ struct slimbus_chkfrm_resp_msg { struct qmi_response_type_v01 resp; }; struct slimbus_deferred_status_resp { struct qmi_response_type_v01 resp; }; static struct elem_info slimbus_select_inst_req_msg_v01_ei[] = { { Loading Loading @@ -1358,6 +1378,24 @@ static struct elem_info slimbus_power_req_msg_v01_ei[] = { .offset = offsetof(struct slimbus_power_req_msg_v01, pm_req), .ei_array = NULL, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct slimbus_power_req_msg_v01, resp_type_valid), }, { .data_type = QMI_SIGNED_4_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(enum slimbus_resp_enum_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct slimbus_power_req_msg_v01, resp_type), }, { .data_type = QMI_EOTI, .elem_len = 0, Loading Loading @@ -1411,6 +1449,22 @@ static struct elem_info slimbus_chkfrm_resp_msg_v01_ei[] = { }, }; static struct elem_info slimbus_deferred_status_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct slimbus_deferred_status_resp, resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, }, }; static void msm_slim_qmi_recv_msg(struct kthread_work *work) { int rc; Loading Loading @@ -1488,32 +1542,56 @@ static int msm_slim_qmi_send_select_inst_req(struct msm_slim_ctrl *dev, return 0; } static void slim_qmi_resp_cb(struct qmi_handle *handle, unsigned int msg_id, void *msg, void *resp_cb_data, int stat) { struct slimbus_power_resp_msg_v01 *resp = msg; struct msm_slim_ctrl *dev = resp_cb_data; if (msg_id != SLIMBUS_QMI_POWER_RESP_V01) SLIM_WARN(dev, "incorrect msg id in qmi-resp CB:0x%x", msg_id); else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) SLIM_ERR(dev, "%s: QMI power failed 0x%x (%s)\n", __func__, resp->resp.result, get_qmi_error(&resp->resp)); complete(&dev->qmi.defer_comp); } static int msm_slim_qmi_send_power_request(struct msm_slim_ctrl *dev, struct slimbus_power_req_msg_v01 *req) { struct slimbus_power_resp_msg_v01 resp = { { 0, 0 } }; struct msg_desc req_desc, resp_desc; struct slimbus_power_resp_msg_v01 *resp = (struct slimbus_power_resp_msg_v01 *)&dev->qmi.resp; struct msg_desc req_desc; struct msg_desc *resp_desc = &dev->qmi.resp_desc; int rc; req_desc.msg_id = SLIMBUS_QMI_POWER_REQ_V01; req_desc.max_msg_len = SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN; req_desc.ei_array = slimbus_power_req_msg_v01_ei; resp_desc.msg_id = SLIMBUS_QMI_POWER_RESP_V01; resp_desc.max_msg_len = SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN; resp_desc.ei_array = slimbus_power_resp_msg_v01_ei; resp_desc->msg_id = SLIMBUS_QMI_POWER_RESP_V01; resp_desc->max_msg_len = SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN; resp_desc->ei_array = slimbus_power_resp_msg_v01_ei; rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), SLIM_QMI_RESP_TOUT); if (rc < 0) { if (dev->qmi.deferred_resp) rc = qmi_send_req_nowait(dev->qmi.handle, &req_desc, req, sizeof(*req), resp_desc, resp, sizeof(*resp), slim_qmi_resp_cb, dev); else rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), resp_desc, resp, sizeof(*resp), SLIM_QMI_RESP_TOUT); if (rc < 0) SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); if (rc < 0 || dev->qmi.deferred_resp) return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); resp->resp.result, get_qmi_error(&resp->resp)); return -EREMOTEIO; } Loading @@ -1527,6 +1605,7 @@ int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master) struct slimbus_select_inst_req_msg_v01 req; kthread_init_worker(&dev->qmi.kworker); init_completion(&dev->qmi.defer_comp); dev->qmi.task = kthread_run(kthread_worker_fn, &dev->qmi.kworker, "msm_slim_qmi_clnt%d", dev->ctrl.nr); Loading Loading @@ -1604,6 +1683,13 @@ int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active) else req.pm_req = SLIMBUS_PM_INACTIVE_V01; if (dev->qmi.deferred_resp) { req.resp_type = SLIMBUS_RESP_DEFERRED_V01; req.resp_type_valid = 1; } else { req.resp_type_valid = 0; } return msm_slim_qmi_send_power_request(dev, &req); } Loading Loading @@ -1635,3 +1721,46 @@ int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev) } return 0; } int msm_slim_qmi_deferred_status_req(struct msm_slim_ctrl *dev) { struct slimbus_deferred_status_resp resp = { { 0, 0 } }; struct msg_desc req_desc, resp_desc; int rc; req_desc.msg_id = SLIMBUS_QMI_DEFERRED_STATUS_REQ; req_desc.max_msg_len = 0; req_desc.ei_array = NULL; resp_desc.msg_id = SLIMBUS_QMI_DEFERRED_STATUS_RESP; resp_desc.max_msg_len = SLIMBUS_QMI_DEFERRED_STATUS_RESP_STAT_MSG_MAX_MSG_LEN; resp_desc.ei_array = slimbus_deferred_status_resp_msg_v01_ei; rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, NULL, 0, &resp_desc, &resp, sizeof(resp), SLIM_QMI_RESP_TOUT); if (rc < 0) { SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } /* wait for the deferred response */ rc = wait_for_completion_timeout(&dev->qmi.defer_comp, HZ); if (rc == 0) { SLIM_WARN(dev, "slimbus power deferred response not rcvd\n"); return -ETIMEDOUT; } /* Check what response we got in callback */ if (dev->qmi.resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_WARN(dev, "QMI power req failed in CB"); return -EREMOTEIO; } return 0; } drivers/slimbus/slim-msm.h +5 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,10 @@ struct msm_slim_qmi { struct kthread_worker kworker; struct completion qmi_comp; struct notifier_block nb; bool deferred_resp; struct qmi_response_type_v01 resp; struct msg_desc resp_desc; struct completion defer_comp; }; enum msm_slim_dom { Loading Loading @@ -437,4 +441,5 @@ void msm_slim_qmi_exit(struct msm_slim_ctrl *dev); int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master); int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active); int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev); int msm_slim_qmi_deferred_status_req(struct msm_slim_ctrl *dev); #endif Loading
drivers/slimbus/slim-msm-ngd.c +21 −5 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code, /* make sure autosuspend is not called until ADSP comes up*/ pm_runtime_get_noresume(dev->dev); dev->state = MSM_CTRL_DOWN; dev->qmi.deferred_resp = false; msm_slim_sps_exit(dev, false); ngd_dom_down(dev); mutex_unlock(&dev->tx_lock); Loading Loading @@ -2019,19 +2020,18 @@ static int ngd_slim_suspend(struct device *dev) if (!pm_runtime_enabled(dev) || (!pm_runtime_suspended(dev) && cdev->state == MSM_CTRL_IDLE)) { cdev->qmi.deferred_resp = true; ret = ngd_slim_runtime_suspend(dev); /* * If runtime-PM still thinks it's active, then make sure its * status is in sync with HW status. * Since this suspend calls QMI api, it results in holding a * wakelock. That results in failure of first suspend. * Subsequent suspend should not call low-power transition * again since the HW is already in suspended state. */ if (!ret) { pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); } else { cdev->qmi.deferred_resp = false; } } if (ret == -EBUSY) { Loading @@ -2053,13 +2053,29 @@ static int ngd_slim_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev); int ret = 0; /* * If deferred response was requested for power-off and it failed, * mark runtime-pm status as active to be consistent * with HW status */ if (cdev->qmi.deferred_resp) { ret = msm_slim_qmi_deferred_status_req(cdev); if (ret) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); } cdev->qmi.deferred_resp = false; } /* * Rely on runtime-PM to call resume in case it is enabled. * Even if it's not enabled, rely on 1st client transaction to do * clock/power on */ SLIM_INFO(cdev, "system resume\n"); return 0; return ret; } #endif /* CONFIG_PM_SLEEP */ Loading
drivers/slimbus/slim-msm.c +141 −12 Original line number Diff line number Diff line Loading @@ -1224,12 +1224,16 @@ void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg) #define SLIMBUS_QMI_POWER_RESP_V01 0x0021 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_REQ 0x0022 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_RESP 0x0022 #define SLIMBUS_QMI_DEFERRED_STATUS_REQ 0x0023 #define SLIMBUS_QMI_DEFERRED_STATUS_RESP 0x0023 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 7 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 14 #define SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN 14 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_CHECK_FRAMER_STAT_RESP_MAX_MSG_LEN 7 #define SLIMBUS_QMI_DEFERRED_STATUS_REQ_MSG_MAX_MSG_LEN 0 #define SLIMBUS_QMI_DEFERRED_STATUS_RESP_STAT_MSG_MAX_MSG_LEN 7 enum slimbus_mode_enum_type_v01 { /* To force a 32 bit signed enum. Do not change or use*/ Loading @@ -1247,6 +1251,13 @@ enum slimbus_pm_enum_type_v01 { SLIMBUS_PM_ENUM_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, }; enum slimbus_resp_enum_type_v01 { SLIMBUS_RESP_ENUM_TYPE_MIN_VAL_V01 = INT_MIN, SLIMBUS_RESP_SYNCHRONOUS_V01 = 1, SLIMBUS_RESP_DEFERRED_V01 = 2, SLIMBUS_RESP_ENUM_TYPE_MAX_VAL_V01 = INT_MAX, }; struct slimbus_select_inst_req_msg_v01 { /* Mandatory */ /* Hardware Instance Selection */ Loading @@ -1269,6 +1280,12 @@ struct slimbus_power_req_msg_v01 { /* Mandatory */ /* Power Request Operation */ enum slimbus_pm_enum_type_v01 pm_req; /* Optional */ /* Optional Deferred Response type Operation */ /* Must be set to true if type is being passed */ uint8_t resp_type_valid; enum slimbus_resp_enum_type_v01 resp_type; }; struct slimbus_power_resp_msg_v01 { Loading @@ -1283,6 +1300,9 @@ struct slimbus_chkfrm_resp_msg { struct qmi_response_type_v01 resp; }; struct slimbus_deferred_status_resp { struct qmi_response_type_v01 resp; }; static struct elem_info slimbus_select_inst_req_msg_v01_ei[] = { { Loading Loading @@ -1358,6 +1378,24 @@ static struct elem_info slimbus_power_req_msg_v01_ei[] = { .offset = offsetof(struct slimbus_power_req_msg_v01, pm_req), .ei_array = NULL, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(uint8_t), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct slimbus_power_req_msg_v01, resp_type_valid), }, { .data_type = QMI_SIGNED_4_BYTE_ENUM, .elem_len = 1, .elem_size = sizeof(enum slimbus_resp_enum_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct slimbus_power_req_msg_v01, resp_type), }, { .data_type = QMI_EOTI, .elem_len = 0, Loading Loading @@ -1411,6 +1449,22 @@ static struct elem_info slimbus_chkfrm_resp_msg_v01_ei[] = { }, }; static struct elem_info slimbus_deferred_status_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct slimbus_deferred_status_resp, resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, }, }; static void msm_slim_qmi_recv_msg(struct kthread_work *work) { int rc; Loading Loading @@ -1488,32 +1542,56 @@ static int msm_slim_qmi_send_select_inst_req(struct msm_slim_ctrl *dev, return 0; } static void slim_qmi_resp_cb(struct qmi_handle *handle, unsigned int msg_id, void *msg, void *resp_cb_data, int stat) { struct slimbus_power_resp_msg_v01 *resp = msg; struct msm_slim_ctrl *dev = resp_cb_data; if (msg_id != SLIMBUS_QMI_POWER_RESP_V01) SLIM_WARN(dev, "incorrect msg id in qmi-resp CB:0x%x", msg_id); else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) SLIM_ERR(dev, "%s: QMI power failed 0x%x (%s)\n", __func__, resp->resp.result, get_qmi_error(&resp->resp)); complete(&dev->qmi.defer_comp); } static int msm_slim_qmi_send_power_request(struct msm_slim_ctrl *dev, struct slimbus_power_req_msg_v01 *req) { struct slimbus_power_resp_msg_v01 resp = { { 0, 0 } }; struct msg_desc req_desc, resp_desc; struct slimbus_power_resp_msg_v01 *resp = (struct slimbus_power_resp_msg_v01 *)&dev->qmi.resp; struct msg_desc req_desc; struct msg_desc *resp_desc = &dev->qmi.resp_desc; int rc; req_desc.msg_id = SLIMBUS_QMI_POWER_REQ_V01; req_desc.max_msg_len = SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN; req_desc.ei_array = slimbus_power_req_msg_v01_ei; resp_desc.msg_id = SLIMBUS_QMI_POWER_RESP_V01; resp_desc.max_msg_len = SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN; resp_desc.ei_array = slimbus_power_resp_msg_v01_ei; resp_desc->msg_id = SLIMBUS_QMI_POWER_RESP_V01; resp_desc->max_msg_len = SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN; resp_desc->ei_array = slimbus_power_resp_msg_v01_ei; rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), SLIM_QMI_RESP_TOUT); if (rc < 0) { if (dev->qmi.deferred_resp) rc = qmi_send_req_nowait(dev->qmi.handle, &req_desc, req, sizeof(*req), resp_desc, resp, sizeof(*resp), slim_qmi_resp_cb, dev); else rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), resp_desc, resp, sizeof(*resp), SLIM_QMI_RESP_TOUT); if (rc < 0) SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); if (rc < 0 || dev->qmi.deferred_resp) return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); resp->resp.result, get_qmi_error(&resp->resp)); return -EREMOTEIO; } Loading @@ -1527,6 +1605,7 @@ int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master) struct slimbus_select_inst_req_msg_v01 req; kthread_init_worker(&dev->qmi.kworker); init_completion(&dev->qmi.defer_comp); dev->qmi.task = kthread_run(kthread_worker_fn, &dev->qmi.kworker, "msm_slim_qmi_clnt%d", dev->ctrl.nr); Loading Loading @@ -1604,6 +1683,13 @@ int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active) else req.pm_req = SLIMBUS_PM_INACTIVE_V01; if (dev->qmi.deferred_resp) { req.resp_type = SLIMBUS_RESP_DEFERRED_V01; req.resp_type_valid = 1; } else { req.resp_type_valid = 0; } return msm_slim_qmi_send_power_request(dev, &req); } Loading Loading @@ -1635,3 +1721,46 @@ int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev) } return 0; } int msm_slim_qmi_deferred_status_req(struct msm_slim_ctrl *dev) { struct slimbus_deferred_status_resp resp = { { 0, 0 } }; struct msg_desc req_desc, resp_desc; int rc; req_desc.msg_id = SLIMBUS_QMI_DEFERRED_STATUS_REQ; req_desc.max_msg_len = 0; req_desc.ei_array = NULL; resp_desc.msg_id = SLIMBUS_QMI_DEFERRED_STATUS_RESP; resp_desc.max_msg_len = SLIMBUS_QMI_DEFERRED_STATUS_RESP_STAT_MSG_MAX_MSG_LEN; resp_desc.ei_array = slimbus_deferred_status_resp_msg_v01_ei; rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, NULL, 0, &resp_desc, &resp, sizeof(resp), SLIM_QMI_RESP_TOUT); if (rc < 0) { SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } /* wait for the deferred response */ rc = wait_for_completion_timeout(&dev->qmi.defer_comp, HZ); if (rc == 0) { SLIM_WARN(dev, "slimbus power deferred response not rcvd\n"); return -ETIMEDOUT; } /* Check what response we got in callback */ if (dev->qmi.resp.result != QMI_RESULT_SUCCESS_V01) { SLIM_WARN(dev, "QMI power req failed in CB"); return -EREMOTEIO; } return 0; }
drivers/slimbus/slim-msm.h +5 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,10 @@ struct msm_slim_qmi { struct kthread_worker kworker; struct completion qmi_comp; struct notifier_block nb; bool deferred_resp; struct qmi_response_type_v01 resp; struct msg_desc resp_desc; struct completion defer_comp; }; enum msm_slim_dom { Loading Loading @@ -437,4 +441,5 @@ void msm_slim_qmi_exit(struct msm_slim_ctrl *dev); int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master); int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active); int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev); int msm_slim_qmi_deferred_status_req(struct msm_slim_ctrl *dev); #endif