Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp4204082imm; Tue, 11 Sep 2018 08:25:19 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYTAVJ6kS6NJXjgEGBcUgbxkvGZQciJIl29s7oIXkbC6TpVYsMH9/2iv64/SnhD+DmN3Ff8 X-Received: by 2002:a63:26c6:: with SMTP id m189-v6mr28777562pgm.70.1536679519272; Tue, 11 Sep 2018 08:25:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536679519; cv=none; d=google.com; s=arc-20160816; b=N0NvhkJpzaaVxyb9INc13giqe9wSgT1RLpTjvbNumBAtHqEI1qLvg0XI8wrvi3Hgq3 WxUswhoP19EPkJLhEeSbQVkYnFj+t2kAEruPSAKMiEUO/cesy+qBM0TFZp93SGuMtuSb 0nXtDbPMmFWwyuGCOLLDxtWyA/dGcl/4ecpikGBMJiwhtz2qqVbDDjtnBf1lKYwux/FG wNIHXfz+qIFwRrGDgJ5sCJIL+fJKFPBTEPV8PqOkDU7fpYztM9YhWW2USCbbrxnIkUEA GWLrBaimKUySpIm48H4c76XWJjCd2MWbdoBEbu/qrcVk4UTHbjlkOv++zejI2/79xaPO VwEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :dkim-signature; bh=ekqIfI1rjzFxMIXsfANJRyiUrtkPVbCG2Xkv41JkkE4=; b=tsl+C/VOdOWVR5+1F/ldvAnAdmpVwep6tcPVUOScNe1JxwplX9QmQ+4usQHkW2Z5vz CPbNPm5qkKVsAmIntVd9aqbgWFejQrEox+vedFddilItYnGdrCIrVC92aPDsp0vLxzFt cRiHZsUQXMlu1D+tp9rzLUN/Wwmid8EA9WzELa2vhDewVCipaB/IXeSoF0z0lHjL1nGj 7XsGuT+VSRni5wBG8BoBaqM+EbYXIN6aCPldmzYHeLOqY0j12wPoxdPH96h5A5O50d2D nfbX99UEW4kMHmuN0oW+EhhTOiI14lHN7cajVCKGzv2i2UbBdFiLUbK22dsNI3K1QIgG vLVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=XfAZn+UN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d130-v6si20871786pgc.189.2018.09.11.08.25.03; Tue, 11 Sep 2018 08:25:19 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=XfAZn+UN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727153AbeIKUYg (ORCPT + 99 others); Tue, 11 Sep 2018 16:24:36 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:54626 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726800AbeIKUYf (ORCPT ); Tue, 11 Sep 2018 16:24:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Subject:Cc:To: From:Date:Sender:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ekqIfI1rjzFxMIXsfANJRyiUrtkPVbCG2Xkv41JkkE4=; b=XfAZn+UNOybI6euz2dHMBlmoF EMxoyrP5lCFnRPp7FmhJlIo0mSBct1IR7481McRGWOFNihZ1RR2nAYUv1e/f4MQy4X+XeN7+s293D TQaaX9wSR3uXhPvNkIvRKdpuksi0h467njvLsST3yaup7s5QJ16xucvaOS6E/LOjP54yUm+ymppMj DtojHCSc4OiRPSYQk6cpE/Mu5/dx3+5kbB5qg1t+p1dljaKeza00wDtf8ZlWzPRUd5nVGaSjLUvRo iS8F5I+Tu9Pr8DxgSGcHWptxNaX6Z2z7xBdxUAau28bXWKo84j//IzXPUPt9lwxgJprUE/U6eCuwT cvURiSs+w==; Received: from 177.17.246.211.dynamic.adsl.gvt.net.br ([177.17.246.211] helo=coco.lan) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1fzkX0-0002sK-Nm; Tue, 11 Sep 2018 15:24:47 +0000 Date: Tue, 11 Sep 2018 12:24:39 -0300 From: Mauro Carvalho Chehab To: Paul Kocialkowski Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devel@driverdev.osuosl.org, Mauro Carvalho Chehab , Rob Herring , Mark Rutland , Maxime Ripard , Chen-Yu Tsai , Greg Kroah-Hartman , Paul Kocialkowski , Thomas Petazzoni , linux-sunxi@googlegroups.com, Randy Li , Hans Verkuil , Ezequiel Garcia , Tomasz Figa , Alexandre Courbot , Philipp Zabel , Laurent Pinchart , Sakari Ailus Subject: Re: [PATCH v9 5/9] media: platform: Add Cedrus VPU decoder driver Message-ID: <20180911122349.7d448fcf@coco.lan> In-Reply-To: <20180906222442.14825-6-contact@paulk.fr> References: <20180906222442.14825-1-contact@paulk.fr> <20180906222442.14825-6-contact@paulk.fr> X-Mailer: Claws Mail 3.16.0 (GTK+ 2.24.32; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Em Fri, 7 Sep 2018 00:24:38 +0200 Paul Kocialkowski escreveu: > From: Paul Kocialkowski > > This introduces the Cedrus VPU driver that supports the VPU found in > Allwinner SoCs, also known as Video Engine. It is implemented through > a V4L2 M2M decoder device and a media device (used for media requests). > So far, it only supports MPEG-2 decoding. > > Since this VPU is stateless, synchronization with media requests is > required in order to ensure consistency between frame headers that > contain metadata about the frame to process and the raw slice data that > is used to generate the frame. > > This driver was made possible thanks to the long-standing effort > carried out by the linux-sunxi community in the interest of reverse > engineering, documenting and implementing support for the Allwinner VPU. > > Signed-off-by: Paul Kocialkowski > Acked-by: Maxime Ripard > --- > MAINTAINERS | 7 + > drivers/staging/media/Kconfig | 2 + > drivers/staging/media/Makefile | 1 + > drivers/staging/media/sunxi/Kconfig | 15 + > drivers/staging/media/sunxi/Makefile | 1 + > drivers/staging/media/sunxi/cedrus/Kconfig | 14 + > drivers/staging/media/sunxi/cedrus/Makefile | 3 + > drivers/staging/media/sunxi/cedrus/cedrus.c | 422 ++++++++++++++ > drivers/staging/media/sunxi/cedrus/cedrus.h | 165 ++++++ > .../staging/media/sunxi/cedrus/cedrus_dec.c | 70 +++ > .../staging/media/sunxi/cedrus/cedrus_dec.h | 27 + > .../staging/media/sunxi/cedrus/cedrus_hw.c | 322 +++++++++++ > .../staging/media/sunxi/cedrus/cedrus_hw.h | 30 + > .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 237 ++++++++ > .../staging/media/sunxi/cedrus/cedrus_regs.h | 233 ++++++++ > .../staging/media/sunxi/cedrus/cedrus_video.c | 544 ++++++++++++++++++ > .../staging/media/sunxi/cedrus/cedrus_video.h | 30 + > 17 files changed, 2123 insertions(+) > create mode 100644 drivers/staging/media/sunxi/Kconfig > create mode 100644 drivers/staging/media/sunxi/Makefile > create mode 100644 drivers/staging/media/sunxi/cedrus/Kconfig > create mode 100644 drivers/staging/media/sunxi/cedrus/Makefile > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus.c > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus.h > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_dec.c > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_dec.h > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_hw.c > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_hw.h > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_regs.h > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_video.c > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_video.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index a5b256b25905..6d69f3ad1aa9 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -663,6 +663,13 @@ L: linux-crypto@vger.kernel.org > S: Maintained > F: drivers/crypto/sunxi-ss/ > > +ALLWINNER VPU DRIVER > +M: Maxime Ripard > +M: Paul Kocialkowski > +L: linux-media@vger.kernel.org > +S: Maintained > +F: drivers/staging/media/sunxi/cedrus/ > + > ALPHA PORT > M: Richard Henderson > M: Ivan Kokshaysky > diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig > index db5cf67047ad..b3620a8f2d9f 100644 > --- a/drivers/staging/media/Kconfig > +++ b/drivers/staging/media/Kconfig > @@ -31,6 +31,8 @@ source "drivers/staging/media/mt9t031/Kconfig" > > source "drivers/staging/media/omap4iss/Kconfig" > > +source "drivers/staging/media/sunxi/Kconfig" > + > source "drivers/staging/media/tegra-vde/Kconfig" > > source "drivers/staging/media/zoran/Kconfig" > diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile > index 503fbe47fa58..42948f805548 100644 > --- a/drivers/staging/media/Makefile > +++ b/drivers/staging/media/Makefile > @@ -5,5 +5,6 @@ obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074/ > obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031/ > obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ > obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ > +obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ > obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ > obj-$(CONFIG_VIDEO_ZORAN) += zoran/ > diff --git a/drivers/staging/media/sunxi/Kconfig b/drivers/staging/media/sunxi/Kconfig > new file mode 100644 > index 000000000000..c78d92240ceb > --- /dev/null > +++ b/drivers/staging/media/sunxi/Kconfig > @@ -0,0 +1,15 @@ > +config VIDEO_SUNXI > + bool "Allwinner sunXi family Video Devices" > + depends on ARCH_SUNXI || COMPILE_TEST > + help > + If you have an Allwinner SoC based on the sunXi family, say Y. > + > + Note that this option doesn't include new drivers in the > + kernel: saying N will just cause Kconfig to skip all the > + questions about Allwinner media devices. > + > +if VIDEO_SUNXI > + > +source "drivers/staging/media/sunxi/cedrus/Kconfig" > + > +endif > diff --git a/drivers/staging/media/sunxi/Makefile b/drivers/staging/media/sunxi/Makefile > new file mode 100644 > index 000000000000..cee2846c3ecf > --- /dev/null > +++ b/drivers/staging/media/sunxi/Makefile > @@ -0,0 +1 @@ > +obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += cedrus/ > diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig > new file mode 100644 > index 000000000000..afd7d7ee0388 > --- /dev/null > +++ b/drivers/staging/media/sunxi/cedrus/Kconfig > @@ -0,0 +1,14 @@ > +config VIDEO_SUNXI_CEDRUS > + tristate "Allwinner Cedrus VPU driver" > + depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER > + depends on HAS_DMA > + depends on OF > + select VIDEOBUF2_DMA_CONTIG > + select MEDIA_REQUEST_API > + select V4L2_MEM2MEM_DEV > + help > + Support for the VPU found in Allwinner SoCs, also known as the Cedar > + video engine. > + > + To compile this driver as a module, choose M here: the module > + will be called sunxi-cedrus. > diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile > new file mode 100644 > index 000000000000..e9dc68b7bcb6 > --- /dev/null > +++ b/drivers/staging/media/sunxi/cedrus/Makefile > @@ -0,0 +1,3 @@ > +obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o > + > +sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o cedrus_mpeg2.o > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c > new file mode 100644 > index 000000000000..09ab1b732c31 > --- /dev/null > +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c > @@ -0,0 +1,422 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cedrus VPU driver > + * > + * Copyright (C) 2016 Florent Revest > + * Copyright (C) 2018 Paul Kocialkowski > + * Copyright (C) 2018 Bootlin > + * > + * Based on the vim2m driver, that is: > + * > + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. > + * Pawel Osciak, > + * Marek Szyprowski, > + */ > + > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#include "cedrus.h" > +#include "cedrus_video.h" > +#include "cedrus_dec.h" > +#include "cedrus_hw.h" > + > +static const struct cedrus_control cedrus_controls[] = { > + { > + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, > + .elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params), > + .codec = CEDRUS_CODEC_MPEG2, > + .required = true, > + }, > + { > + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, > + .elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization), > + .codec = CEDRUS_CODEC_MPEG2, > + .required = false, > + }, > +}; > + > +#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls) > + > +void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id) > +{ > + unsigned int i; > + > + for (i = 0; ctx->ctrls[i] != NULL; i++) > + if (ctx->ctrls[i]->id == id) > + return ctx->ctrls[i]->p_cur.p; > + > + return NULL; > +} > + > +static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx) > +{ > + struct v4l2_ctrl_handler *hdl = &ctx->hdl; > + struct v4l2_ctrl *ctrl; > + unsigned int ctrl_size; > + unsigned int i; > + > + v4l2_ctrl_handler_init(hdl, CEDRUS_CONTROLS_COUNT); > + if (hdl->error) { > + v4l2_err(&dev->v4l2_dev, > + "Failed to initialize control handler\n"); > + return hdl->error; > + } > + > + ctrl_size = sizeof(ctrl) * CEDRUS_CONTROLS_COUNT + 1; > + > + ctx->ctrls = kzalloc(ctrl_size, GFP_KERNEL); > + memset(ctx->ctrls, 0, ctrl_size); > + > + for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) { > + struct v4l2_ctrl_config cfg = { 0 }; > + > + cfg.elem_size = cedrus_controls[i].elem_size; > + cfg.id = cedrus_controls[i].id; > + > + ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL); > + if (hdl->error) { > + v4l2_err(&dev->v4l2_dev, > + "Failed to create new custom control\n"); > + > + v4l2_ctrl_handler_free(hdl); > + kfree(ctx->ctrls); > + return hdl->error; > + } > + > + ctx->ctrls[i] = ctrl; > + } > + > + ctx->fh.ctrl_handler = hdl; > + v4l2_ctrl_handler_setup(hdl); > + > + return 0; > +} > + > +static int cedrus_request_validate(struct media_request *req) > +{ > + struct media_request_object *obj; > + struct v4l2_ctrl_handler *parent_hdl, *hdl; > + struct cedrus_ctx *ctx = NULL; > + struct v4l2_ctrl *ctrl_test; > + unsigned int i; > + > + if (vb2_request_buffer_cnt(req) != 1) > + return -ENOENT; > + > + list_for_each_entry(obj, &req->objects, list) { > + struct vb2_buffer *vb; > + > + if (vb2_request_object_is_buffer(obj)) { > + vb = container_of(obj, struct vb2_buffer, req_obj); > + ctx = vb2_get_drv_priv(vb->vb2_queue); > + > + break; > + } > + } > + > + if (!ctx) > + return -ENOENT; > + > + parent_hdl = &ctx->hdl; > + > + hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl); > + if (!hdl) { > + v4l2_err(&ctx->dev->v4l2_dev, "Missing codec control(s)\n"); > + return -ENOENT; > + } > + > + for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) { > + if (cedrus_controls[i].codec != ctx->current_codec || > + !cedrus_controls[i].required) > + continue; > + > + ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl, > + cedrus_controls[i].id); > + if (!ctrl_test) { > + v4l2_err(&ctx->dev->v4l2_dev, > + "Missing required codec control\n"); > + return -ENOENT; > + } > + } > + > + v4l2_ctrl_request_hdl_put(hdl); > + > + return vb2_request_validate(req); > +} > + > +static int cedrus_open(struct file *file) > +{ > + struct cedrus_dev *dev = video_drvdata(file); > + struct cedrus_ctx *ctx = NULL; > + int ret; > + > + if (mutex_lock_interruptible(&dev->dev_mutex)) > + return -ERESTARTSYS; > + > + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); > + if (!ctx) { > + mutex_unlock(&dev->dev_mutex); > + return -ENOMEM; > + } > + > + v4l2_fh_init(&ctx->fh, video_devdata(file)); > + file->private_data = &ctx->fh; > + ctx->dev = dev; > + > + ret = cedrus_init_ctrls(dev, ctx); > + if (ret) > + goto err_free; > + > + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, > + &cedrus_queue_init); > + if (IS_ERR(ctx->fh.m2m_ctx)) { > + ret = PTR_ERR(ctx->fh.m2m_ctx); > + goto err_ctrls; > + } > + > + v4l2_fh_add(&ctx->fh); > + > + mutex_unlock(&dev->dev_mutex); > + > + return 0; > + > +err_ctrls: > + v4l2_ctrl_handler_free(&ctx->hdl); > +err_free: > + kfree(ctx); > + mutex_unlock(&dev->dev_mutex); > + > + return ret; > +} > + > +static int cedrus_release(struct file *file) > +{ > + struct cedrus_dev *dev = video_drvdata(file); > + struct cedrus_ctx *ctx = container_of(file->private_data, > + struct cedrus_ctx, fh); > + > + mutex_lock(&dev->dev_mutex); > + > + v4l2_fh_del(&ctx->fh); > + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); > + > + v4l2_ctrl_handler_free(&ctx->hdl); > + kfree(ctx->ctrls); > + > + v4l2_fh_exit(&ctx->fh); > + > + kfree(ctx); > + > + mutex_unlock(&dev->dev_mutex); > + > + return 0; > +} > + > +static const struct v4l2_file_operations cedrus_fops = { > + .owner = THIS_MODULE, > + .open = cedrus_open, > + .release = cedrus_release, > + .poll = v4l2_m2m_fop_poll, > + .unlocked_ioctl = video_ioctl2, > + .mmap = v4l2_m2m_fop_mmap, > +}; > + > +static const struct video_device cedrus_video_device = { > + .name = CEDRUS_NAME, > + .vfl_dir = VFL_DIR_M2M, > + .fops = &cedrus_fops, > + .ioctl_ops = &cedrus_ioctl_ops, > + .minor = -1, > + .release = video_device_release_empty, > + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, > +}; > + > +static const struct v4l2_m2m_ops cedrus_m2m_ops = { > + .device_run = cedrus_device_run, > +}; > + > +static const struct media_device_ops cedrus_m2m_media_ops = { > + .req_validate = cedrus_request_validate, > + .req_queue = vb2_m2m_request_queue, > +}; > + > +static int cedrus_probe(struct platform_device *pdev) > +{ > + struct cedrus_dev *dev; > + struct video_device *vfd; > + int ret; > + > + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); > + if (!dev) > + return -ENOMEM; > + > + dev->vfd = cedrus_video_device; > + dev->dev = &pdev->dev; > + dev->pdev = pdev; > + > + ret = cedrus_hw_probe(dev); > + if (ret) { > + dev_err(&pdev->dev, "Failed to probe hardware\n"); > + return ret; > + } > + > + dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2; > + > + mutex_init(&dev->dev_mutex); > + spin_lock_init(&dev->irq_lock); > + > + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); > + if (ret) { > + dev_err(&pdev->dev, "Failed to register V4L2 device\n"); > + return ret; > + } > + > + vfd = &dev->vfd; > + vfd->lock = &dev->dev_mutex; > + vfd->v4l2_dev = &dev->v4l2_dev; > + > + snprintf(vfd->name, sizeof(vfd->name), "%s", cedrus_video_device.name); > + video_set_drvdata(vfd, dev); > + > + dev->m2m_dev = v4l2_m2m_init(&cedrus_m2m_ops); > + if (IS_ERR(dev->m2m_dev)) { > + v4l2_err(&dev->v4l2_dev, > + "Failed to initialize V4L2 M2M device\n"); > + ret = PTR_ERR(dev->m2m_dev); > + > + goto err_video; > + } > + > + dev->mdev.dev = &pdev->dev; > + strlcpy(dev->mdev.model, CEDRUS_NAME, sizeof(dev->mdev.model)); This is a minor issue: we're getting rid of strlcpy upstream. So, please send a followup patch replacing all occurrences of strcpy, strncpy and strlcpy with strscpy(). The syntax is the same as strlcpy(). Thanks, Mauro