static void vpe_send_outmsg(void) { unsigned long flags; struct v4l2_event v4l2_evt; struct msm_queue_cmd *event_qcmd; spin_lock_irqsave(&vpe_ctrl->lock, flags); if (vpe_ctrl->state == VPE_STATE_IDLE) { pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__); spin_unlock_irqrestore(&vpe_ctrl->lock, flags); return; } event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC); atomic_set(&event_qcmd->on_heap, 1); event_qcmd->command = (void *)vpe_ctrl->pp_frame_info; vpe_ctrl->pp_frame_info = NULL; vpe_ctrl->state = VPE_STATE_INIT; /* put it back to idle. */ /* Enqueue the event payload. */ msm_enqueue(&vpe_ctrl->eventData_q, &event_qcmd->list_eventdata); /* Now queue the event. */ v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_MCTL_PP_EVENT; v4l2_evt.id = 0; v4l2_event_queue(vpe_ctrl->subdev.devnode, &v4l2_evt); spin_unlock_irqrestore(&vpe_ctrl->lock, flags); }
static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev) { struct v4l2_event v4l2_evt; struct msm_queue_cmd *frame_qcmd; struct msm_queue_cmd *event_qcmd; struct msm_cpp_frame_info_t *processed_frame; struct msm_device_queue *queue = &cpp_dev->processing_q; if (queue->len > 0) { frame_qcmd = msm_dequeue(queue, list_frame); processed_frame = frame_qcmd->command; event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL); if (!event_qcmd) { pr_err("%s Insufficient memory. return", __func__); return -ENOMEM; } atomic_set(&event_qcmd->on_heap, 1); event_qcmd->command = processed_frame; CPP_DBG("fid %d\n", processed_frame->frame_id); msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata); v4l2_evt.id = processed_frame->inst_id; v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE; v4l2_event_queue(cpp_dev->subdev.devnode, &v4l2_evt); } return 0; }
static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev) { struct msm_queue_cmd *frame_qcmd; struct msm_cpp_frame_info_t *process_frame; struct msm_device_queue *queue; if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) { while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) { if (cpp_dev->realtime_q.len != 0) { queue = &cpp_dev->realtime_q; } else if (cpp_dev->offline_q.len != 0) { queue = &cpp_dev->offline_q; } else { pr_debug("%s: All frames queued\n", __func__); break; } frame_qcmd = msm_dequeue(queue, list_frame); /*TBD Code to actually sending to harware*/ process_frame = frame_qcmd->command; msm_enqueue(&cpp_dev->processing_q, &frame_qcmd->list_frame); } } return 0; }
long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd); struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg; int rc = 0; CPP_DBG("%s: %d\n", __func__, __LINE__); mutex_lock(&cpp_dev->mutex); CPP_DBG("%s cmd: %d\n", __func__, cmd); switch (cmd) { case VIDIOC_MSM_CPP_CFG: { struct msm_queue_cmd *frame_qcmd; struct msm_cpp_frame_info_t *new_frame = kzalloc(sizeof(struct msm_cpp_frame_info_t), GFP_KERNEL); if (!new_frame) { pr_err("%s Insufficient memory. return", __func__); mutex_unlock(&cpp_dev->mutex); return -ENOMEM; } COPY_FROM_USER(rc, new_frame, (void __user *)ioctl_ptr->ioctl_ptr, sizeof(struct msm_cpp_frame_info_t)); if (rc) { ERR_COPY_FROM_USER(); kfree(new_frame); mutex_unlock(&cpp_dev->mutex); return -EINVAL; } frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL); if (!frame_qcmd) { pr_err("%s Insufficient memory. return", __func__); kfree(new_frame); mutex_unlock(&cpp_dev->mutex); return -ENOMEM; } atomic_set(&frame_qcmd->on_heap, 1); frame_qcmd->command = new_frame; if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) { msm_enqueue(&cpp_dev->realtime_q, &frame_qcmd->list_frame); } else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) { msm_enqueue(&cpp_dev->offline_q, &frame_qcmd->list_frame); } else { pr_err("%s: Invalid frame type\n", __func__); kfree(new_frame); kfree(frame_qcmd); mutex_unlock(&cpp_dev->mutex); return -EINVAL; } break; } case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: { struct msm_device_queue *queue = &cpp_dev->eventData_q; struct msm_queue_cmd *event_qcmd; struct msm_cpp_frame_info_t *process_frame; event_qcmd = msm_dequeue(queue, list_eventdata); process_frame = event_qcmd->command; CPP_DBG("fid %d\n", process_frame->frame_id); if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr, process_frame, sizeof(struct msm_cpp_frame_info_t))) { mutex_unlock(&cpp_dev->mutex); return -EINVAL; } kfree(process_frame); kfree(event_qcmd); break; } } mutex_unlock(&cpp_dev->mutex); CPP_DBG("%s: %d\n", __func__, __LINE__); return 0; }