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;
}
Example #2
0
static inline int adie_close(struct dal_client *client)
{
    return dal_call_f0(client, DAL_OP_CLOSE, 0);
}
Example #3
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;
}