static int q6venc_release(struct inode *inode, struct file *file) { struct q6venc_dev *q6venc; int id, err; q6venc = file->private_data; file->private_data = NULL; pr_info("q6venc_close() handle=%p\n", q6venc->venc); for (id = 0; id < q6venc->num_enc_bufs; id++) put_buf_info(&q6venc->enc_bufs[id]); put_buf_info(&q6venc->rlc_bufs[0]); put_buf_info(&q6venc->rlc_bufs[1]); if(!q6venc->stop_encode) { err = dal_call_f0(q6venc->venc, VENC_DALRPC_STOP, 1); if (err) pr_err("%s: dal_rpc STOP call failed\n", __func__); q6venc->stop_encode = true; } dal_detach(q6venc->venc); mutex_destroy(&q6venc->lock); kfree(q6venc); return 0; }
static inline int adie_close(struct dal_client *client) { return dal_call_f0(client, DAL_OP_CLOSE, 0); }
static inline int adie_open(struct dal_client *client) { return dal_call_f0(client, DAL_OP_OPEN, 0); }
static int q6venc_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { struct q6venc_dev *q6venc = file->private_data; struct init_config config; struct encode_param encode_param; struct intra_refresh intra_refresh; struct rc_config rc_config; struct frame_type frame_done; unsigned int id; unsigned long flags; int err = 0; if (!q6venc) { pr_err("%s: file has no private data\n", __func__); return -ENODEV; } pr_debug("%s\n", __func__); switch (cmd) { case VENC_IOCTL_INITIALIZE: pr_debug("%s: VENC_IOCTL_INITIALIZE\n", __func__); if (copy_from_user(&config, (void __user *)arg, sizeof(config))) return -EFAULT; err = q6_config_encode(q6venc, VENC_DALRPC_INITIALIZE, &config); break; case VENC_IOCTL_ENCODE_CONFIG: pr_debug("%s: VENC_IOCTL_ENCODE_CONFIG\n", __func__); if (copy_from_user(&config, (void __user *)arg, sizeof(config))) return -EFAULT; err = q6_config_encode(q6venc, VENC_DALRPC_ENCODE_CONFIG, &config); break; case VENC_IOCTL_ENCODE: pr_debug("%s: VENC_IOCTL_ENCODE\n", __func__); if (copy_from_user(&encode_param, (void __user *)arg, sizeof(encode_param))) return -EFAULT; err = q6_encode(q6venc, &encode_param); break; case VENC_IOCTL_INTRA_REFRESH: pr_debug("%s: VENC_IOCTL_INTRA_REFRESH\n", __func__); if (copy_from_user(&intra_refresh, (void __user *)arg, sizeof(intra_refresh))) return -EFAULT; mutex_lock(&q6venc->lock); err = dal_call_f5(q6venc->venc, VENC_DALRPC_INTRA_REFRESH, &intra_refresh, sizeof(struct intra_refresh)); mutex_unlock(&q6venc->lock); if (err) pr_err("%s: intra_refresh rpc failed\n", __func__); break; case VENC_IOCTL_RC_CONFIG: pr_debug("%s: VENC_IOCTL_RC_CONFIG\n", __func__); if (copy_from_user(&rc_config, (void __user *)arg, sizeof(rc_config))) return -EFAULT; mutex_lock(&q6venc->lock); err = dal_call_f5(q6venc->venc, VENC_DALRPC_RC_CONFIG, &rc_config, sizeof(rc_config)); mutex_unlock(&q6venc->lock); if (err) pr_err("%s: dal_call_f5 failed\n", __func__); break; case VENC_IOCTL_STOP: pr_debug("%s: VENC_IOCTL_STOP\n", __func__); mutex_lock(&q6venc->lock); err = dal_call_f0(q6venc->venc, VENC_DALRPC_STOP, 1); if (err) pr_err("%s: dal_rpc STOP call failed\n", __func__); /* XXX: if the dal call fails we still want to continue to free * the buffers. Is this correct? */ for (id = 0; id < q6venc->num_enc_bufs; id++) put_buf_info(&q6venc->enc_bufs[id]); put_buf_info(&q6venc->rlc_bufs[0]); put_buf_info(&q6venc->rlc_bufs[1]); q6venc->num_enc_bufs = 0; q6venc->stop_encode = true; mutex_unlock(&q6venc->lock); break; case VENC_IOCTL_WAIT_FOR_ENCODE: pr_debug("%s: waiting for encode done event \n", __func__); err = wait_event_interruptible(q6venc->encode_wq, (q6venc->encode_done || q6venc->stop_encode)); if (err < 0) { err = -ERESTARTSYS; break; } mutex_lock(&q6venc->lock); if (q6venc->stop_encode) { q6venc->stop_encode = false; mutex_unlock(&q6venc->lock); pr_debug("%s: Received Stop encode event \n", __func__); err = -EINTR; break; } spin_lock_irqsave(&q6venc->done_lock, flags); if (!q6venc->encode_done) { spin_unlock_irqrestore(&q6venc->done_lock, flags); pr_err("%s: encoding not stopped, and is not done.\n", __func__); err = -EIO; break; } memcpy(&frame_done, &q6venc->done_frame, sizeof(struct frame_type)); q6venc->encode_done = false; spin_unlock_irqrestore(&q6venc->done_lock, flags); mutex_unlock(&q6venc->lock); if (frame_done.q6_frame_type.frame_len == 0) { pr_debug("%s: got incorrect address from q6\n", __func__); err = -EIO; break; } pr_debug("%s: done encoding \n", __func__); if (copy_to_user((void __user *)arg, &frame_done, sizeof(struct frame_type))) err = -EFAULT; break; case VENC_IOCTL_STOP_ENCODE: pr_debug("%s: Stop encode event \n", __func__); mutex_lock(&q6venc->lock); q6venc->stop_encode = true; wake_up_interruptible(&q6venc->encode_wq); mutex_unlock(&q6venc->lock); break; default: err = -ENOTTY; break; } return err; }