Loading drivers/media/platform/msm/cvp/cvp_hfi.c +5 −2 Original line number Diff line number Diff line Loading @@ -2575,6 +2575,9 @@ static void iris_hfi_pm_handler(struct work_struct *work) } mutex_lock(&device->lock); if (gfa_cv.state == DSP_SUSPEND) rc = __power_collapse(device, true); else rc = __power_collapse(device, false); mutex_unlock(&device->lock); switch (rc) { Loading Loading @@ -2693,7 +2696,7 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) return rc; skip_power_off: dprintk(CVP_WARN, "Skip PC(%#x, %#x, %#x)\n", dprintk(CVP_PWR, "Skip PC(%#x, %#x, %#x)\n", wfi_status, idle_status, pc_ready); __flush_debug_queue(device, device->raw_packet); return -EAGAIN; Loading drivers/media/platform/msm/cvp/msm_cvp_dsp.c +132 −21 Original line number Diff line number Diff line Loading @@ -10,17 +10,7 @@ #include "msm_cvp_dsp.h" #include "msm_cvp_internal.h" struct cvp_dsp_apps { struct mutex lock; struct rpmsg_device *chan; uint32_t state; bool hyp_assigned; uint64_t addr; uint32_t size; struct completion completions[CVP_DSP_MAX_CMD]; }; static struct cvp_dsp_apps gfa_cv; struct cvp_dsp_apps gfa_cv; static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, Loading Loading @@ -71,6 +61,8 @@ static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len) goto exit; } me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; exit: return rc; } Loading @@ -81,7 +73,7 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, int rc = 0; struct cvp_dsp_cmd_msg cmd; cmd.type = CVP_DSP_SEND_HFI_QUEUE; cmd.type = CPU2DSP_SEND_HFI_QUEUE; cmd.msg_ptr = (uint64_t)phys_addr; cmd.msg_ptr_len = size_in_bytes; cmd.ddr_type = of_fdt_get_ddrtype(); Loading Loading @@ -193,12 +185,34 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, dprintk(CVP_DSP, "%s: type = 0x%x ret = 0x%x\n", __func__, rsp->type, rsp->ret); if (rsp->type >= CVP_DSP_MAX_CMD) { dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); if (rsp->type == CPU2DSP_SUSPEND || rsp->type == CPU2DSP_RESUME) { me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; return 0; } if (me->pending_dsp2cpu_rsp.type != CVP_INVALID_RPMSG_TYPE || me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) goto exit; if (rsp->type < CPU2DSP_MAX_CMD) { memcpy(&me->pending_dsp2cpu_rsp, rsp, sizeof(struct cvp_dsp_rsp_msg)); complete(&me->completions[rsp->type]); } else if (rsp->type < CVP_DSP_MAX_CMD) { memcpy(&me->pending_dsp2cpu_cmd, rsp, sizeof(struct cvp_dsp2cpu_cmd_msg)); complete(&me->completions[CPU2DSP_MAX_CMD]); } else { dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); return 0; } return 0; exit: dprintk(CVP_ERR, "concurrent dsp cmd type = %d, rsp type = %d\n", me->pending_dsp2cpu_cmd.type, me->pending_dsp2cpu_rsp.type); return 0; } Loading @@ -208,7 +222,7 @@ int cvp_dsp_suspend(uint32_t session_flag) struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_SUSPEND; cmd.type = CPU2DSP_SUSPEND; mutex_lock(&me->lock); if (me->state != DSP_READY) Loading Loading @@ -237,7 +251,7 @@ int cvp_dsp_resume(uint32_t session_flag) struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_RESUME; cmd.type = CPU2DSP_RESUME; mutex_lock(&me->lock); if (me->state != DSP_SUSPEND) Loading Loading @@ -266,7 +280,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) int rc = 0; struct cvp_dsp_cmd_msg cmd; cmd.type = CVP_DSP_SHUTDOWN; cmd.type = CPU2DSP_SHUTDOWN; mutex_lock(&me->lock); if (me->state == DSP_INVALID) Loading Loading @@ -297,7 +311,7 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, int rc; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_REGISTER_BUFFER; cmd.type = CPU2DSP_REGISTER_BUFFER; cmd.session_id = session_id; cmd.buff_fd = buff_fd; cmd.buff_fd_size = buff_fd_size; Loading Loading @@ -335,7 +349,7 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, int rc; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_DEREGISTER_BUFFER; cmd.type = CPU2DSP_DEREGISTER_BUFFER; cmd.session_id = session_id; cmd.buff_fd = buff_fd; cmd.buff_fd_size = buff_fd_size; Loading Loading @@ -439,9 +453,93 @@ void cvp_dsp_send_hfi_queue(void) mutex_unlock(&device->lock); } static int cvp_dsp_thread(void *data) { int rc = 0, old_state; struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_cmd_msg cmd; struct cvp_hfi_device *hdev; struct msm_cvp_core *core; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (!core) { dprintk(CVP_ERR, "%s: Failed to find core\n", __func__); rc = -EINVAL; goto exit; } hdev = (struct cvp_hfi_device *)core->device; if (!hdev) { dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); rc = -EINVAL; goto exit; } wait_dsp: rc = wait_for_completion_interruptible( &me->completions[CPU2DSP_MAX_CMD]); if (me->state == DSP_INVALID) goto exit; cmd.type = me->pending_dsp2cpu_cmd.type; if (rc == -ERESTARTSYS) { dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); } else { mutex_lock(&me->lock); switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: { if (me->state == DSP_READY) break; mutex_unlock(&me->lock); old_state = me->state; me->state = DSP_READY; rc = call_hfi_op(hdev, resume, hdev->hfi_device_data); if (rc) { dprintk(CVP_WARN, "%s Failed to resume cvp\n", __func__); mutex_lock(&me->lock); me->state = old_state; cmd.ret = 1; break; } mutex_lock(&me->lock); cmd.ret = 0; break; } case DSP2CPU_POWEROFF: { me->state = DSP_SUSPEND; cmd.ret = 0; break; } default: dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", me->pending_dsp2cpu_cmd.type); break; } me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; mutex_unlock(&me->lock); } /* Responds to DSP */ rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg)); if (rc) dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc = %d cmd type=%d\n", __func__, rc, cmd.type); goto wait_dsp; exit: dprintk(CVP_DBG, "dsp thread exit\n"); do_exit(rc); } int cvp_dsp_device_init(void) { struct cvp_dsp_apps *me = &gfa_cv; char tname[16]; int rc; int i; Loading @@ -449,9 +547,12 @@ int cvp_dsp_device_init(void) me->state = DSP_INVALID; me->hyp_assigned = false; for (i = 0; i < CVP_DSP_MAX_CMD; i++) for (i = 0; i <= CPU2DSP_MAX_CMD; i++) init_completion(&me->completions[i]); me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client); if (rc) { dprintk(CVP_ERR, Loading @@ -459,7 +560,13 @@ int cvp_dsp_device_init(void) __func__, rc); goto register_bail; } snprintf(tname, sizeof(tname), "cvp-dsp-thread"); me->dsp_thread = kthread_run(cvp_dsp_thread, me, tname); if (!me->dsp_thread) { dprintk(CVP_ERR, "%s create %s fail", __func__, tname); rc = -ECHILD; goto register_bail; } me->state = DSP_UNINIT; return 0; Loading @@ -470,11 +577,15 @@ int cvp_dsp_device_init(void) void cvp_dsp_device_exit(void) { struct cvp_dsp_apps *me = &gfa_cv; int i; mutex_lock(&me->lock); me->state = DSP_INVALID; mutex_unlock(&me->lock); for (i = 0; i <= CPU2DSP_MAX_CMD; i++) complete_all(&me->completions[i]); mutex_destroy(&me->lock); unregister_rpmsg_driver(&cvp_dsp_rpmsg_client); } drivers/media/platform/msm/cvp/msm_cvp_dsp.h +34 −8 Original line number Diff line number Diff line Loading @@ -17,20 +17,25 @@ #define HLOS_VM_NUM 1 #define DSP_VM_NUM 2 #define CVP_DSP_MAX_RESERVED 5 #define CVP_DSP2CPU_RESERVED 8 #define CVP_DSP_RESPONSE_TIMEOUT 1000 #define CVP_INVALID_RPMSG_TYPE 0xBADDFACE int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); void cvp_dsp_send_hfi_queue(void); enum DSP_COMMAND { CVP_DSP_SEND_HFI_QUEUE = 0, CVP_DSP_SUSPEND = 1, CVP_DSP_RESUME = 2, CVP_DSP_SHUTDOWN = 3, CVP_DSP_REGISTER_BUFFER = 4, CVP_DSP_DEREGISTER_BUFFER = 5, CVP_DSP_MAX_CMD enum CVP_DSP_COMMAND { CPU2DSP_SEND_HFI_QUEUE = 0, CPU2DSP_SUSPEND = 1, CPU2DSP_RESUME = 2, CPU2DSP_SHUTDOWN = 3, CPU2DSP_REGISTER_BUFFER = 4, CPU2DSP_DEREGISTER_BUFFER = 5, CPU2DSP_MAX_CMD = 6, DSP2CPU_POWERON = 6, DSP2CPU_POWEROFF = 7, CVP_DSP_MAX_CMD = 8, }; struct cvp_dsp_cmd_msg { Loading @@ -56,6 +61,27 @@ struct cvp_dsp_rsp_msg { uint32_t reserved[CVP_DSP_MAX_RESERVED]; }; struct cvp_dsp2cpu_cmd_msg { uint32_t type; uint32_t ver; uint32_t len; uint32_t data[CVP_DSP2CPU_RESERVED]; }; struct cvp_dsp_apps { struct mutex lock; struct rpmsg_device *chan; uint32_t state; bool hyp_assigned; uint64_t addr; uint32_t size; struct completion completions[CPU2DSP_MAX_CMD + 1]; struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd; struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp; struct task_struct *dsp_thread; }; extern struct cvp_dsp_apps gfa_cv; /* * API for CVP driver to suspend CVP session during * power collapse Loading Loading
drivers/media/platform/msm/cvp/cvp_hfi.c +5 −2 Original line number Diff line number Diff line Loading @@ -2575,6 +2575,9 @@ static void iris_hfi_pm_handler(struct work_struct *work) } mutex_lock(&device->lock); if (gfa_cv.state == DSP_SUSPEND) rc = __power_collapse(device, true); else rc = __power_collapse(device, false); mutex_unlock(&device->lock); switch (rc) { Loading Loading @@ -2693,7 +2696,7 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) return rc; skip_power_off: dprintk(CVP_WARN, "Skip PC(%#x, %#x, %#x)\n", dprintk(CVP_PWR, "Skip PC(%#x, %#x, %#x)\n", wfi_status, idle_status, pc_ready); __flush_debug_queue(device, device->raw_packet); return -EAGAIN; Loading
drivers/media/platform/msm/cvp/msm_cvp_dsp.c +132 −21 Original line number Diff line number Diff line Loading @@ -10,17 +10,7 @@ #include "msm_cvp_dsp.h" #include "msm_cvp_internal.h" struct cvp_dsp_apps { struct mutex lock; struct rpmsg_device *chan; uint32_t state; bool hyp_assigned; uint64_t addr; uint32_t size; struct completion completions[CVP_DSP_MAX_CMD]; }; static struct cvp_dsp_apps gfa_cv; struct cvp_dsp_apps gfa_cv; static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, Loading Loading @@ -71,6 +61,8 @@ static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len) goto exit; } me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; exit: return rc; } Loading @@ -81,7 +73,7 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, int rc = 0; struct cvp_dsp_cmd_msg cmd; cmd.type = CVP_DSP_SEND_HFI_QUEUE; cmd.type = CPU2DSP_SEND_HFI_QUEUE; cmd.msg_ptr = (uint64_t)phys_addr; cmd.msg_ptr_len = size_in_bytes; cmd.ddr_type = of_fdt_get_ddrtype(); Loading Loading @@ -193,12 +185,34 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, dprintk(CVP_DSP, "%s: type = 0x%x ret = 0x%x\n", __func__, rsp->type, rsp->ret); if (rsp->type >= CVP_DSP_MAX_CMD) { dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); if (rsp->type == CPU2DSP_SUSPEND || rsp->type == CPU2DSP_RESUME) { me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; return 0; } if (me->pending_dsp2cpu_rsp.type != CVP_INVALID_RPMSG_TYPE || me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) goto exit; if (rsp->type < CPU2DSP_MAX_CMD) { memcpy(&me->pending_dsp2cpu_rsp, rsp, sizeof(struct cvp_dsp_rsp_msg)); complete(&me->completions[rsp->type]); } else if (rsp->type < CVP_DSP_MAX_CMD) { memcpy(&me->pending_dsp2cpu_cmd, rsp, sizeof(struct cvp_dsp2cpu_cmd_msg)); complete(&me->completions[CPU2DSP_MAX_CMD]); } else { dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); return 0; } return 0; exit: dprintk(CVP_ERR, "concurrent dsp cmd type = %d, rsp type = %d\n", me->pending_dsp2cpu_cmd.type, me->pending_dsp2cpu_rsp.type); return 0; } Loading @@ -208,7 +222,7 @@ int cvp_dsp_suspend(uint32_t session_flag) struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_SUSPEND; cmd.type = CPU2DSP_SUSPEND; mutex_lock(&me->lock); if (me->state != DSP_READY) Loading Loading @@ -237,7 +251,7 @@ int cvp_dsp_resume(uint32_t session_flag) struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_RESUME; cmd.type = CPU2DSP_RESUME; mutex_lock(&me->lock); if (me->state != DSP_SUSPEND) Loading Loading @@ -266,7 +280,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) int rc = 0; struct cvp_dsp_cmd_msg cmd; cmd.type = CVP_DSP_SHUTDOWN; cmd.type = CPU2DSP_SHUTDOWN; mutex_lock(&me->lock); if (me->state == DSP_INVALID) Loading Loading @@ -297,7 +311,7 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, int rc; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_REGISTER_BUFFER; cmd.type = CPU2DSP_REGISTER_BUFFER; cmd.session_id = session_id; cmd.buff_fd = buff_fd; cmd.buff_fd_size = buff_fd_size; Loading Loading @@ -335,7 +349,7 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, int rc; struct cvp_dsp_apps *me = &gfa_cv; cmd.type = CVP_DSP_DEREGISTER_BUFFER; cmd.type = CPU2DSP_DEREGISTER_BUFFER; cmd.session_id = session_id; cmd.buff_fd = buff_fd; cmd.buff_fd_size = buff_fd_size; Loading Loading @@ -439,9 +453,93 @@ void cvp_dsp_send_hfi_queue(void) mutex_unlock(&device->lock); } static int cvp_dsp_thread(void *data) { int rc = 0, old_state; struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_cmd_msg cmd; struct cvp_hfi_device *hdev; struct msm_cvp_core *core; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (!core) { dprintk(CVP_ERR, "%s: Failed to find core\n", __func__); rc = -EINVAL; goto exit; } hdev = (struct cvp_hfi_device *)core->device; if (!hdev) { dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); rc = -EINVAL; goto exit; } wait_dsp: rc = wait_for_completion_interruptible( &me->completions[CPU2DSP_MAX_CMD]); if (me->state == DSP_INVALID) goto exit; cmd.type = me->pending_dsp2cpu_cmd.type; if (rc == -ERESTARTSYS) { dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); } else { mutex_lock(&me->lock); switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: { if (me->state == DSP_READY) break; mutex_unlock(&me->lock); old_state = me->state; me->state = DSP_READY; rc = call_hfi_op(hdev, resume, hdev->hfi_device_data); if (rc) { dprintk(CVP_WARN, "%s Failed to resume cvp\n", __func__); mutex_lock(&me->lock); me->state = old_state; cmd.ret = 1; break; } mutex_lock(&me->lock); cmd.ret = 0; break; } case DSP2CPU_POWEROFF: { me->state = DSP_SUSPEND; cmd.ret = 0; break; } default: dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", me->pending_dsp2cpu_cmd.type); break; } me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; mutex_unlock(&me->lock); } /* Responds to DSP */ rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg)); if (rc) dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc = %d cmd type=%d\n", __func__, rc, cmd.type); goto wait_dsp; exit: dprintk(CVP_DBG, "dsp thread exit\n"); do_exit(rc); } int cvp_dsp_device_init(void) { struct cvp_dsp_apps *me = &gfa_cv; char tname[16]; int rc; int i; Loading @@ -449,9 +547,12 @@ int cvp_dsp_device_init(void) me->state = DSP_INVALID; me->hyp_assigned = false; for (i = 0; i < CVP_DSP_MAX_CMD; i++) for (i = 0; i <= CPU2DSP_MAX_CMD; i++) init_completion(&me->completions[i]); me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client); if (rc) { dprintk(CVP_ERR, Loading @@ -459,7 +560,13 @@ int cvp_dsp_device_init(void) __func__, rc); goto register_bail; } snprintf(tname, sizeof(tname), "cvp-dsp-thread"); me->dsp_thread = kthread_run(cvp_dsp_thread, me, tname); if (!me->dsp_thread) { dprintk(CVP_ERR, "%s create %s fail", __func__, tname); rc = -ECHILD; goto register_bail; } me->state = DSP_UNINIT; return 0; Loading @@ -470,11 +577,15 @@ int cvp_dsp_device_init(void) void cvp_dsp_device_exit(void) { struct cvp_dsp_apps *me = &gfa_cv; int i; mutex_lock(&me->lock); me->state = DSP_INVALID; mutex_unlock(&me->lock); for (i = 0; i <= CPU2DSP_MAX_CMD; i++) complete_all(&me->completions[i]); mutex_destroy(&me->lock); unregister_rpmsg_driver(&cvp_dsp_rpmsg_client); }
drivers/media/platform/msm/cvp/msm_cvp_dsp.h +34 −8 Original line number Diff line number Diff line Loading @@ -17,20 +17,25 @@ #define HLOS_VM_NUM 1 #define DSP_VM_NUM 2 #define CVP_DSP_MAX_RESERVED 5 #define CVP_DSP2CPU_RESERVED 8 #define CVP_DSP_RESPONSE_TIMEOUT 1000 #define CVP_INVALID_RPMSG_TYPE 0xBADDFACE int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); void cvp_dsp_send_hfi_queue(void); enum DSP_COMMAND { CVP_DSP_SEND_HFI_QUEUE = 0, CVP_DSP_SUSPEND = 1, CVP_DSP_RESUME = 2, CVP_DSP_SHUTDOWN = 3, CVP_DSP_REGISTER_BUFFER = 4, CVP_DSP_DEREGISTER_BUFFER = 5, CVP_DSP_MAX_CMD enum CVP_DSP_COMMAND { CPU2DSP_SEND_HFI_QUEUE = 0, CPU2DSP_SUSPEND = 1, CPU2DSP_RESUME = 2, CPU2DSP_SHUTDOWN = 3, CPU2DSP_REGISTER_BUFFER = 4, CPU2DSP_DEREGISTER_BUFFER = 5, CPU2DSP_MAX_CMD = 6, DSP2CPU_POWERON = 6, DSP2CPU_POWEROFF = 7, CVP_DSP_MAX_CMD = 8, }; struct cvp_dsp_cmd_msg { Loading @@ -56,6 +61,27 @@ struct cvp_dsp_rsp_msg { uint32_t reserved[CVP_DSP_MAX_RESERVED]; }; struct cvp_dsp2cpu_cmd_msg { uint32_t type; uint32_t ver; uint32_t len; uint32_t data[CVP_DSP2CPU_RESERVED]; }; struct cvp_dsp_apps { struct mutex lock; struct rpmsg_device *chan; uint32_t state; bool hyp_assigned; uint64_t addr; uint32_t size; struct completion completions[CPU2DSP_MAX_CMD + 1]; struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd; struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp; struct task_struct *dsp_thread; }; extern struct cvp_dsp_apps gfa_cv; /* * API for CVP driver to suspend CVP session during * power collapse Loading