From patchwork Fri Aug 9 21:45:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shuah Khan X-Patchwork-Id: 11087725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 85175912 for ; Fri, 9 Aug 2019 21:45:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 736752022B for ; Fri, 9 Aug 2019 21:45:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 676B72223E; Fri, 9 Aug 2019 21:45:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A082D2022B for ; Fri, 9 Aug 2019 21:45:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728214AbfHIVpu (ORCPT ); Fri, 9 Aug 2019 17:45:50 -0400 Received: from mail-ot1-f67.google.com ([209.85.210.67]:44364 "EHLO mail-ot1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726157AbfHIVpu (ORCPT ); Fri, 9 Aug 2019 17:45:50 -0400 Received: by mail-ot1-f67.google.com with SMTP id b7so87883186otl.11 for ; Fri, 09 Aug 2019 14:45:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XVpKg76iNK8Q/96SWBmPErgH7+sWQHry8Kj0z1Q3E4s=; b=VPG1KTp/U3INFqDj/Hn3VLHmSyuQMd3T6+O/C0Cmwq9AD5aPNiFJoLIbZ+qA5GiDCM nDjwxr1VqTeaeCLG9s/7Pff8yI1GJ4X7k79SpE2tRv/jSayXwVf4jyH0Z4wIloNYDZZc JvRKBhAnChodTNPzUrdwsq8CT+xfNzKB4Ukf8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XVpKg76iNK8Q/96SWBmPErgH7+sWQHry8Kj0z1Q3E4s=; b=YWHhDVh89VJYctpQz7693bEvOL8LxWrVIdZRtIyAENin7RScPdOWJosqOAOCn9q22p wcR5apElsF/GbTizAPx1dD0B8O/NTV2rHKq59wKQEpBnf30TnrFiITkbmQZ6niodBA0r H56dnhkW/lbLd5dK//U0vQQ4kt8dZo6WVhdwCRwOS+71Z9+LuFoRcwouH+0N2pkWaZm8 TnX4DUxK5a83Z65960/m6PlGlYdtWJQIHgz3u9hPGXRtTDQdL32oYwurY1TEFbkxP4Bq gs1iOwBuBPcArqYbfDg6fK/mBQtFtTg8XZ5rgtk8/XwTNvTzz9CPO6zVSBgKZrPPZnnV 7NJQ== X-Gm-Message-State: APjAAAXV/9HqKmcGnErMAYCxSpSI1I7A1g+pcKpMrpkqQQ7bVOGOTPuv h89AEhWz+q95CRF+Hv/R0AkAvw== X-Google-Smtp-Source: APXvYqym8uiYgHJ73R3fcQFikPHmj9xtcamzMx0wWGxeIp2gzZe9jI3kGz/pr3OE7haDJQqFvoVgsw== X-Received: by 2002:a6b:8f82:: with SMTP id r124mr12222862iod.6.1565387149231; Fri, 09 Aug 2019 14:45:49 -0700 (PDT) Received: from shuah-t480s.internal (c-24-9-64-241.hsd1.co.comcast.net. [24.9.64.241]) by smtp.gmail.com with ESMTPSA id n17sm75861623iog.63.2019.08.09.14.45.48 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 09 Aug 2019 14:45:48 -0700 (PDT) From: Shuah Khan To: mchehab@kernel.org, helen.koike@collabora.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com Cc: Shuah Khan , linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH 1/3] media: vimc: move private defines to a common header Date: Fri, 9 Aug 2019 15:45:41 -0600 Message-Id: <142cc5a6a10f75ed97de8b2d9b1e73b034a88b2f.1565386363.git.skhan@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In preparation for collapsing the component driver structure into a monolith, move private device structure defines to a new common header file. Signed-off-by: Shuah Khan --- drivers/media/platform/vimc/vimc-capture.c | 21 +---- drivers/media/platform/vimc/vimc-core.c | 18 +--- drivers/media/platform/vimc/vimc-debayer.c | 16 +--- drivers/media/platform/vimc/vimc-scaler.c | 15 +-- drivers/media/platform/vimc/vimc-sensor.c | 13 +-- drivers/media/platform/vimc/vimc.h | 102 +++++++++++++++++++++ 6 files changed, 107 insertions(+), 78 deletions(-) create mode 100644 drivers/media/platform/vimc/vimc.h diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index 664855708fdf..c52fc5d97c2d 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c @@ -13,6 +13,7 @@ #include #include +#include "vimc.h" #include "vimc-common.h" #include "vimc-streamer.h" @@ -44,26 +45,6 @@ static const u32 vimc_cap_supported_pixfmt[] = { V4L2_PIX_FMT_SRGGB12, }; -struct vimc_cap_device { - struct vimc_ent_device ved; - struct video_device vdev; - struct device *dev; - struct v4l2_pix_format format; - struct vb2_queue queue; - struct list_head buf_list; - /* - * NOTE: in a real driver, a spin lock must be used to access the - * queue because the frames are generated from a hardware interruption - * and the isr is not allowed to sleep. - * Even if it is not necessary a spinlock in the vimc driver, we - * use it here as a code reference - */ - spinlock_t qlock; - struct mutex lock; - u32 sequence; - struct vimc_stream stream; -}; - static const struct v4l2_pix_format fmt_default = { .width = 640, .height = 480, diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index 571c55aa0e16..c9b351472272 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c @@ -12,6 +12,7 @@ #include #include +#include "vimc.h" #include "vimc-common.h" #define VIMC_MDEV_MODEL_NAME "VIMC MDEV" @@ -24,23 +25,6 @@ .flags = link_flags, \ } -struct vimc_device { - /* The platform device */ - struct platform_device pdev; - - /* The pipeline configuration */ - const struct vimc_pipeline_config *pipe_cfg; - - /* The Associated media_device parent */ - struct media_device mdev; - - /* Internal v4l2 parent device*/ - struct v4l2_device v4l2_dev; - - /* Subdevices */ - struct platform_device **subdevs; -}; - /* Structure which describes individual configuration for each entity */ struct vimc_ent_config { const char *name; diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 00598fbf3cba..750752bb173c 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -13,6 +13,7 @@ #include #include +#include "vimc.h" #include "vimc-common.h" #define VIMC_DEB_DRV_NAME "vimc-debayer" @@ -44,21 +45,6 @@ struct vimc_deb_pix_map { enum vimc_deb_rgb_colors order[2][2]; }; -struct vimc_deb_device { - struct vimc_ent_device ved; - struct v4l2_subdev sd; - struct device *dev; - /* The active format */ - struct v4l2_mbus_framefmt sink_fmt; - u32 src_code; - void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin, - unsigned int col, unsigned int rgb[3]); - /* Values calculated when the stream starts */ - u8 *src_frame; - const struct vimc_deb_pix_map *sink_pix_map; - unsigned int sink_bpp; -}; - static const struct v4l2_mbus_framefmt sink_fmt_default = { .width = 640, .height = 480, diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index c7123a45c55b..fe99b9102ada 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -13,6 +13,7 @@ #include #include +#include "vimc.h" #include "vimc-common.h" #define VIMC_SCA_DRV_NAME "vimc-scaler" @@ -31,20 +32,6 @@ static const u32 vimc_sca_supported_pixfmt[] = { V4L2_PIX_FMT_ARGB32, }; -struct vimc_sca_device { - struct vimc_ent_device ved; - struct v4l2_subdev sd; - struct device *dev; - /* NOTE: the source fmt is the same as the sink - * with the width and hight multiplied by mult - */ - struct v4l2_mbus_framefmt sink_fmt; - /* Values calculated when the stream starts */ - u8 *src_frame; - unsigned int src_line_size; - unsigned int bpp; -}; - static const struct v4l2_mbus_framefmt sink_fmt_default = { .width = 640, .height = 480, diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 51359472eef2..6c57b1e262f9 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -16,22 +16,11 @@ #include #include +#include "vimc.h" #include "vimc-common.h" #define VIMC_SEN_DRV_NAME "vimc-sensor" -struct vimc_sen_device { - struct vimc_ent_device ved; - struct v4l2_subdev sd; - struct device *dev; - struct tpg_data tpg; - struct task_struct *kthread_sen; - u8 *frame; - /* The active format */ - struct v4l2_mbus_framefmt mbus_format; - struct v4l2_ctrl_handler hdl; -}; - static const struct v4l2_mbus_framefmt fmt_default = { .width = 640, .height = 480, diff --git a/drivers/media/platform/vimc/vimc.h b/drivers/media/platform/vimc/vimc.h new file mode 100644 index 000000000000..a5adebdda941 --- /dev/null +++ b/drivers/media/platform/vimc/vimc.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * + * Copyright (C) 2019 Shuah Khan + * + */ + +/* + * This file defines vimc driver device and sub-device structures. + */ + +#ifndef _VIMC_H_ +#define _VIMC_H_ + +#include +#include +#include +#include +#include +#include + +#include "vimc-common.h" + +struct vimc_cap_device { + struct vimc_ent_device ved; + struct video_device vdev; + struct device *dev; + struct v4l2_pix_format format; + struct vb2_queue queue; + struct list_head buf_list; + /* + * NOTE: in a real driver, a spin lock must be used to access the + * queue because the frames are generated from a hardware interruption + * and the isr is not allowed to sleep. + * Even if it is not necessary a spinlock in the vimc driver, we + * use it here as a code reference + */ + spinlock_t qlock; + struct mutex lock; + u32 sequence; + struct vimc_stream stream; +}; + +struct vimc_sca_device { + struct vimc_ent_device ved; + struct v4l2_subdev sd; + struct device *dev; + /* NOTE: the source fmt is the same as the sink + * with the width and hight multiplied by mult + */ + struct v4l2_mbus_framefmt sink_fmt; + /* Values calculated when the stream starts */ + u8 *src_frame; + unsigned int src_line_size; + unsigned int bpp; +}; + +struct vimc_deb_device { + struct vimc_ent_device ved; + struct v4l2_subdev sd; + struct device *dev; + /* The active format */ + struct v4l2_mbus_framefmt sink_fmt; + u32 src_code; + void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin, + unsigned int col, unsigned int rgb[3]); + /* Values calculated when the stream starts */ + u8 *src_frame; + const struct vimc_deb_pix_map *sink_pix_map; + unsigned int sink_bpp; +}; + +struct vimc_sen_device { + struct vimc_ent_device ved; + struct v4l2_subdev sd; + struct device *dev; + struct tpg_data tpg; + struct task_struct *kthread_sen; + u8 *frame; + /* The active format */ + struct v4l2_mbus_framefmt mbus_format; + struct v4l2_ctrl_handler hdl; +}; + +struct vimc_device { + /* The platform device */ + struct platform_device pdev; + + /* The pipeline configuration */ + const struct vimc_pipeline_config *pipe_cfg; + + /* The Associated media_device parent */ + struct media_device mdev; + + /* Internal v4l2 parent device*/ + struct v4l2_device v4l2_dev; + + /* Subdevices */ + struct platform_device **subdevs; +}; + +#endif From patchwork Fri Aug 9 21:45:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shuah Khan X-Patchwork-Id: 11087729 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B435E14D5 for ; Fri, 9 Aug 2019 21:46:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DBD7223A1 for ; Fri, 9 Aug 2019 21:46:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 91971204C1; Fri, 9 Aug 2019 21:46:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B56BA21C9A for ; Fri, 9 Aug 2019 21:46:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728558AbfHIVp6 (ORCPT ); Fri, 9 Aug 2019 17:45:58 -0400 Received: from mail-ot1-f66.google.com ([209.85.210.66]:44379 "EHLO mail-ot1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728333AbfHIVpy (ORCPT ); Fri, 9 Aug 2019 17:45:54 -0400 Received: by mail-ot1-f66.google.com with SMTP id b7so87883556otl.11 for ; Fri, 09 Aug 2019 14:45:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=16UxPzrDl3jdpKFjPRAjHfiEzXJYdGi7FWsypp9JNe0=; b=C+vrljJhjCYDMzwWmghnlpLTT4sUUbn2HtsRLcE4CC0yCkekv6GTMqax2aSkyYHr8r 5S8rtcQTEUE4H7EqsKoI6213eZcz8v7LFB2qcpER2k2SBTFeJw40EyuqiDhavH0YQ2OT TxK6kTZuTdmHlThUSPpdjhA9KyP5HbMHW5J90= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=16UxPzrDl3jdpKFjPRAjHfiEzXJYdGi7FWsypp9JNe0=; b=e3Jkf5pRtyuvTxblKhiwe+UdnvuAe6ldTVJjQgIRM05kmNSV9qU9SBmYcVK+lMjcDC kc79WGBxMQ49HSbWGktyNQQ91iG4prGMIuuONLpFiEAxJb/kYRHNCDlFJ/rgxrP2aqQV qj2RU6TRTsIn9CZExeBRvdK9a+iXtnugBb5BoghAPezcmVcKvYEdzS+z9AnX3xBZvQsM XVZckV1gapsNoawQJ0rVvVdHn+bonwUKCsmeXmEGOo1wUKxH/vxYXYiC6WtePOlFJLON MPrsu4mwBwwVzyJW27U3RpLJCU0glDeuD09RXKycLiXtNZU1po65OXZwS3H5CkK7AaJy 8HpQ== X-Gm-Message-State: APjAAAWLIAZHkFF221msAz865lvMYXpDNDnHzbnC3jdKFk9JNngthKKw 6XjSEjNMppAVFupSnZAuYpYNOg== X-Google-Smtp-Source: APXvYqzuxegDPaD3zLqiFjgmoe0UShQN+/Nmz8EiIghX0s1TBo9QxB0lIFBro+77AN8OyjnfC7x5RA== X-Received: by 2002:a02:3b62:: with SMTP id i34mr25233591jaf.91.1565387151337; Fri, 09 Aug 2019 14:45:51 -0700 (PDT) Received: from shuah-t480s.internal (c-24-9-64-241.hsd1.co.comcast.net. [24.9.64.241]) by smtp.gmail.com with ESMTPSA id n17sm75861623iog.63.2019.08.09.14.45.50 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 09 Aug 2019 14:45:50 -0700 (PDT) From: Shuah Khan To: mchehab@kernel.org, helen.koike@collabora.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com Cc: Shuah Khan , linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH 2/3] media: vimc: Collapse component structure into a single monolithic driver Date: Fri, 9 Aug 2019 15:45:42 -0600 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP vimc uses Component API to split the driver into functional components. The real hardware resembles a monolith structure than component and component structure added a level of complexity making it hard to maintain without adding any real benefit. The sensor is one vimc component that would makes sense to be a separate module to closely align with the real hardware. It would be easier to collapse vimc into single monolithic driver first and then split the sensor off as a separate module. Collapse it into a single monolithic driver removing the Component API. This patch removes the component API and makes minimal changes to the code base preserving the functional division of the code structure. Preserving the functional structure allows us to split the sensor off as a separate module in the future. Major design elements in this change are: - Use existing struct vimc_ent_config and struct vimc_pipeline_config to drive the initialization of the functional components. - Make vimc_ent_config global by moving it to vimc.h - Add two new hooks add and rm to initialize and register, unregister and free subdevs. - All component API is now gone and bind and unbind hooks are modified to do "add" and "rm" with minimal changes to just add and rm subdevs. - vimc-core's bind and unbind are now register and unregister. - vimc-core invokes "add" hooks from its vimc_register_devices(). The "add" hooks remain the same and register subdevs. They don't create platform devices of their own and use vimc's pdev.dev as their reference device. The "add" hooks save their vimc_ent_device(s) in the corresponding vimc_ent_config. - vimc-core invokes "rm" hooks from its unregister to unregister subdevs and cleanup. - vimc-core invokes "add" and "rm" hooks with pointer to struct vimc_device and the corresponding struct vimc_ent_config pointer. The following configure and stream test works on all devices. media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]' media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]' media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]' media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]' v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440 v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81 v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81 v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video1 v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video2 v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video3 Signed-off-by: Shuah Khan --- drivers/media/platform/vimc/Makefile | 7 +- drivers/media/platform/vimc/vimc-capture.c | 75 ++-------- drivers/media/platform/vimc/vimc-core.c | 156 ++++++++------------- drivers/media/platform/vimc/vimc-debayer.c | 68 ++------- drivers/media/platform/vimc/vimc-scaler.c | 68 ++------- drivers/media/platform/vimc/vimc-sensor.c | 69 ++------- drivers/media/platform/vimc/vimc.h | 25 +++- 7 files changed, 125 insertions(+), 343 deletions(-) diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile index 96d06f030c31..a53b2b532e9f 100644 --- a/drivers/media/platform/vimc/Makefile +++ b/drivers/media/platform/vimc/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -vimc-y := vimc-core.o vimc-common.o vimc-streamer.o +vimc-y := vimc-core.o vimc-common.o vimc-streamer.o vimc-capture.o \ + vimc-debayer.o vimc-scaler.o vimc-sensor.o + +obj-$(CONFIG_VIDEO_VIMC) += vimc.o -obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc-capture.o vimc-debayer.o \ - vimc-scaler.o vimc-sensor.o diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index c52fc5d97c2d..b7b2d3c3d4f8 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c @@ -5,10 +5,6 @@ * Copyright (C) 2015-2017 Helen Koike */ -#include -#include -#include -#include #include #include #include @@ -17,8 +13,6 @@ #include "vimc-common.h" #include "vimc-streamer.h" -#define VIMC_CAP_DRV_NAME "vimc-capture" - static const u32 vimc_cap_supported_pixfmt[] = { V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, @@ -348,11 +342,11 @@ static void vimc_cap_release(struct video_device *vdev) kfree(vcap); } -static void vimc_cap_comp_unbind(struct device *comp, struct device *master, - void *master_data) +void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct vimc_ent_device *ved = dev_get_drvdata(comp); - struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device, + struct vimc_ent_device *ved = vent->ved; + struct vimc_cap_device *vcap = container_of(ved, + struct vimc_cap_device, ved); vb2_queue_release(&vcap->queue); @@ -399,11 +393,9 @@ static void *vimc_cap_process_frame(struct vimc_ent_device *ved, return NULL; } -static int vimc_cap_comp_bind(struct device *comp, struct device *master, - void *master_data) +int vimc_cap_add(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct v4l2_device *v4l2_dev = master_data; - struct vimc_platform_data *pdata = comp->platform_data; + struct v4l2_device *v4l2_dev = &vimc->v4l2_dev; struct vimc_cap_device *vcap; struct video_device *vdev; struct vb2_queue *q; @@ -423,7 +415,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, } /* Initialize the media entity */ - vcap->vdev.entity.name = pdata->entity_name; + vcap->vdev.entity.name = vent->name; vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L; ret = media_entity_pads_init(&vcap->vdev.entity, 1, vcap->ved.pads); @@ -447,8 +439,8 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, ret = vb2_queue_init(q); if (ret) { - dev_err(comp, "%s: vb2 queue init failed (err=%d)\n", - pdata->entity_name, ret); + dev_err(&vimc->pdev.dev, "%s: vb2 queue init failed (err=%d)\n", + vent->name, ret); goto err_clean_m_ent; } @@ -465,8 +457,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, vcap->ved.ent = &vcap->vdev.entity; vcap->ved.process_frame = vimc_cap_process_frame; vcap->ved.vdev_get_format = vimc_cap_get_format; - dev_set_drvdata(comp, &vcap->ved); - vcap->dev = comp; + vcap->dev = &vimc->pdev.dev; /* Initialize the video_device struct */ vdev = &vcap->vdev; @@ -479,17 +470,18 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, vdev->queue = q; vdev->v4l2_dev = v4l2_dev; vdev->vfl_dir = VFL_DIR_RX; - strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name)); + strscpy(vdev->name, vent->name, sizeof(vdev->name)); video_set_drvdata(vdev, &vcap->ved); /* Register the video_device with the v4l2 and the media framework */ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) { - dev_err(comp, "%s: video register failed (err=%d)\n", + dev_err(&vimc->pdev.dev, "%s: video register failed (err=%d)\n", vcap->vdev.name, ret); goto err_release_queue; } + vent->ved = &vcap->ved; return 0; err_release_queue: @@ -503,44 +495,3 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, return ret; } - -static const struct component_ops vimc_cap_comp_ops = { - .bind = vimc_cap_comp_bind, - .unbind = vimc_cap_comp_unbind, -}; - -static int vimc_cap_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &vimc_cap_comp_ops); -} - -static int vimc_cap_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &vimc_cap_comp_ops); - - return 0; -} - -static const struct platform_device_id vimc_cap_driver_ids[] = { - { - .name = VIMC_CAP_DRV_NAME, - }, - { } -}; - -static struct platform_driver vimc_cap_pdrv = { - .probe = vimc_cap_probe, - .remove = vimc_cap_remove, - .id_table = vimc_cap_driver_ids, - .driver = { - .name = VIMC_CAP_DRV_NAME, - }, -}; - -module_platform_driver(vimc_cap_pdrv); - -MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids); - -MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Capture"); -MODULE_AUTHOR("Helen Mae Koike Fornazier "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index c9b351472272..3bd89cf38a90 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c @@ -5,7 +5,6 @@ * Copyright (C) 2015-2017 Helen Koike */ -#include #include #include #include @@ -25,12 +24,6 @@ .flags = link_flags, \ } -/* Structure which describes individual configuration for each entity */ -struct vimc_ent_config { - const char *name; - const char *drv; -}; - /* Structure which describes links between entities */ struct vimc_ent_link { unsigned int src_ent; @@ -42,7 +35,7 @@ struct vimc_ent_link { /* Structure which describes the whole topology */ struct vimc_pipeline_config { - const struct vimc_ent_config *ents; + struct vimc_ent_config *ents; size_t num_ents; const struct vimc_ent_link *links; size_t num_links; @@ -52,43 +45,61 @@ struct vimc_pipeline_config { * Topology Configuration */ -static const struct vimc_ent_config ent_config[] = { +static struct vimc_ent_config ent_config[] = { { .name = "Sensor A", .drv = "vimc-sensor", + .add = vimc_sen_add, + .rm = vimc_sen_rm, }, { .name = "Sensor B", .drv = "vimc-sensor", + .add = vimc_sen_add, + .rm = vimc_sen_rm, }, { .name = "Debayer A", .drv = "vimc-debayer", + .add = vimc_deb_add, + .rm = vimc_deb_rm, }, { .name = "Debayer B", .drv = "vimc-debayer", + .add = vimc_deb_add, + .rm = vimc_deb_rm, }, { .name = "Raw Capture 0", .drv = "vimc-capture", + .add = vimc_cap_add, + .rm = vimc_cap_rm, }, { .name = "Raw Capture 1", .drv = "vimc-capture", + .add = vimc_cap_add, + .rm = vimc_cap_rm, }, { .name = "RGB/YUV Input", /* TODO: change this to vimc-input when it is implemented */ .drv = "vimc-sensor", + .add = vimc_sen_add, + .rm = vimc_sen_rm, }, { .name = "Scaler", .drv = "vimc-scaler", + .add = vimc_sca_add, + .rm = vimc_sca_rm, }, { .name = "RGB/YUV Capture", .drv = "vimc-capture", + .add = vimc_cap_add, + .rm = vimc_cap_rm, }, }; @@ -111,7 +122,7 @@ static const struct vimc_ent_link ent_links[] = { VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), }; -static const struct vimc_pipeline_config pipe_cfg = { +static struct vimc_pipeline_config pipe_cfg = { .ents = ent_config, .num_ents = ARRAY_SIZE(ent_config), .links = ent_links, @@ -128,14 +139,11 @@ static int vimc_create_links(struct vimc_device *vimc) /* Initialize the links between entities */ for (i = 0; i < vimc->pipe_cfg->num_links; i++) { const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i]; - /* - * TODO: Check another way of retrieving ved struct without - * relying on platform_get_drvdata - */ + struct vimc_ent_device *ved_src = - platform_get_drvdata(vimc->subdevs[link->src_ent]); + vimc->pipe_cfg->ents[link->src_ent].ved; struct vimc_ent_device *ved_sink = - platform_get_drvdata(vimc->subdevs[link->sink_ent]); + vimc->pipe_cfg->ents[link->sink_ent].ved; ret = media_create_pad_link(ved_src->ent, link->src_pad, ved_sink->ent, link->sink_pad, @@ -147,13 +155,28 @@ static int vimc_create_links(struct vimc_device *vimc) return 0; } -static int vimc_comp_bind(struct device *master) +static int vimc_add_subdevs(struct vimc_device *vimc) { - struct vimc_device *vimc = container_of(to_platform_device(master), - struct vimc_device, pdev); - int ret; + int i; + int ret = 0; + + for (i = 0; i < vimc->pipe_cfg->num_ents; i++) { + dev_dbg(&vimc->pdev.dev, "new entity for %s\n", + vimc->pipe_cfg->ents[i].name); + ret = vimc->pipe_cfg->ents[i].add(vimc, + &vimc->pipe_cfg->ents[i]); + if (ret) { + dev_err(&vimc->pdev.dev, "add new entity for %s\n", + vimc->pipe_cfg->ents[i].name); + return ret; + } + } + return 0; +} - dev_dbg(master, "bind"); +static int vimc_register_devices(struct vimc_device *vimc) +{ + int ret; /* Register the v4l2 struct */ ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev); @@ -163,22 +186,20 @@ static int vimc_comp_bind(struct device *master) return ret; } - /* Bind subdevices */ - ret = component_bind_all(master, &vimc->v4l2_dev); - if (ret) - goto err_v4l2_unregister; + /* Invoke enitity config hooks to initialize and register subdevs */ + vimc_add_subdevs(vimc); /* Initialize links */ ret = vimc_create_links(vimc); if (ret) - goto err_comp_unbind_all; + goto err_v4l2_unregister; /* Register the media device */ ret = media_device_register(&vimc->mdev); if (ret) { dev_err(vimc->mdev.dev, "media device register failed (err=%d)\n", ret); - goto err_comp_unbind_all; + goto err_v4l2_unregister; } /* Expose all subdev's nodes*/ @@ -195,98 +216,36 @@ static int vimc_comp_bind(struct device *master) err_mdev_unregister: media_device_unregister(&vimc->mdev); media_device_cleanup(&vimc->mdev); -err_comp_unbind_all: - component_unbind_all(master, NULL); err_v4l2_unregister: v4l2_device_unregister(&vimc->v4l2_dev); return ret; } -static void vimc_comp_unbind(struct device *master) +static void vimc_unregister(struct vimc_device *vimc) { - struct vimc_device *vimc = container_of(to_platform_device(master), - struct vimc_device, pdev); - - dev_dbg(master, "unbind"); - media_device_unregister(&vimc->mdev); media_device_cleanup(&vimc->mdev); - component_unbind_all(master, NULL); v4l2_device_unregister(&vimc->v4l2_dev); } -static int vimc_comp_compare(struct device *comp, void *data) -{ - return comp == data; -} - -static struct component_match *vimc_add_subdevs(struct vimc_device *vimc) -{ - struct component_match *match = NULL; - struct vimc_platform_data pdata; - int i; - - for (i = 0; i < vimc->pipe_cfg->num_ents; i++) { - dev_dbg(&vimc->pdev.dev, "new pdev for %s\n", - vimc->pipe_cfg->ents[i].drv); - - strscpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name, - sizeof(pdata.entity_name)); - - vimc->subdevs[i] = platform_device_register_data(&vimc->pdev.dev, - vimc->pipe_cfg->ents[i].drv, - PLATFORM_DEVID_AUTO, - &pdata, - sizeof(pdata)); - if (IS_ERR(vimc->subdevs[i])) { - match = ERR_CAST(vimc->subdevs[i]); - while (--i >= 0) - platform_device_unregister(vimc->subdevs[i]); - - return match; - } - - component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare, - &vimc->subdevs[i]->dev); - } - - return match; -} - static void vimc_rm_subdevs(struct vimc_device *vimc) { unsigned int i; for (i = 0; i < vimc->pipe_cfg->num_ents; i++) - platform_device_unregister(vimc->subdevs[i]); + vimc->pipe_cfg->ents[i].rm(vimc, &vimc->pipe_cfg->ents[i]); } -static const struct component_master_ops vimc_comp_ops = { - .bind = vimc_comp_bind, - .unbind = vimc_comp_unbind, -}; - static int vimc_probe(struct platform_device *pdev) { struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev); - struct component_match *match = NULL; - int ret; + int ret = 0; dev_dbg(&pdev->dev, "probe"); memset(&vimc->mdev, 0, sizeof(vimc->mdev)); - /* Create platform_device for each entity in the topology*/ - vimc->subdevs = devm_kcalloc(&vimc->pdev.dev, vimc->pipe_cfg->num_ents, - sizeof(*vimc->subdevs), GFP_KERNEL); - if (!vimc->subdevs) - return -ENOMEM; - - match = vimc_add_subdevs(vimc); - if (IS_ERR(match)) - return PTR_ERR(match); - /* Link the media device within the v4l2_device */ vimc->v4l2_dev.mdev = &vimc->mdev; @@ -298,16 +257,11 @@ static int vimc_probe(struct platform_device *pdev) vimc->mdev.dev = &pdev->dev; media_device_init(&vimc->mdev); - /* Add self to the component system */ - ret = component_master_add_with_match(&pdev->dev, &vimc_comp_ops, - match); - if (ret) { + ret = vimc_register_devices(vimc); + if (ret) media_device_cleanup(&vimc->mdev); - vimc_rm_subdevs(vimc); - return ret; - } - return 0; + return ret; } static int vimc_remove(struct platform_device *pdev) @@ -316,8 +270,8 @@ static int vimc_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "remove"); - component_master_del(&pdev->dev, &vimc_comp_ops); vimc_rm_subdevs(vimc); + vimc_unregister(vimc); return 0; } diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 750752bb173c..b58e0946ac2a 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -5,10 +5,7 @@ * Copyright (C) 2015-2017 Helen Koike */ -#include #include -#include -#include #include #include #include @@ -16,9 +13,7 @@ #include "vimc.h" #include "vimc-common.h" -#define VIMC_DEB_DRV_NAME "vimc-debayer" -/* This module only supports transforming a bayer format - * to V4L2_PIX_FMT_RGB24 +/* Supports transforming a bayer format to V4L2_PIX_FMT_RGB24 */ #define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24 #define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24 @@ -499,21 +494,19 @@ static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = { .release = vimc_deb_release, }; -static void vimc_deb_comp_unbind(struct device *comp, struct device *master, - void *master_data) +void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct vimc_ent_device *ved = dev_get_drvdata(comp); - struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device, + struct vimc_ent_device *ved = vent->ved; + struct vimc_deb_device *vdeb = container_of(ved, + struct vimc_deb_device, ved); vimc_ent_sd_unregister(ved, &vdeb->sd); } -static int vimc_deb_comp_bind(struct device *comp, struct device *master, - void *master_data) +int vimc_deb_add(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct v4l2_device *v4l2_dev = master_data; - struct vimc_platform_data *pdata = comp->platform_data; + struct v4l2_device *v4l2_dev = &vimc->v4l2_dev; struct vimc_deb_device *vdeb; int ret; @@ -524,7 +517,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev, - pdata->entity_name, + vent->name, MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, (const unsigned long[2]) {MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE}, @@ -535,8 +528,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, } vdeb->ved.process_frame = vimc_deb_process_frame; - dev_set_drvdata(comp, &vdeb->ved); - vdeb->dev = comp; + vdeb->dev = &vimc->pdev.dev; /* Initialize the frame format */ vdeb->sink_fmt = sink_fmt_default; @@ -549,46 +541,6 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, */ vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24; + vent->ved = &vdeb->ved; return 0; } - -static const struct component_ops vimc_deb_comp_ops = { - .bind = vimc_deb_comp_bind, - .unbind = vimc_deb_comp_unbind, -}; - -static int vimc_deb_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &vimc_deb_comp_ops); -} - -static int vimc_deb_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &vimc_deb_comp_ops); - - return 0; -} - -static const struct platform_device_id vimc_deb_driver_ids[] = { - { - .name = VIMC_DEB_DRV_NAME, - }, - { } -}; - -static struct platform_driver vimc_deb_pdrv = { - .probe = vimc_deb_probe, - .remove = vimc_deb_remove, - .id_table = vimc_deb_driver_ids, - .driver = { - .name = VIMC_DEB_DRV_NAME, - }, -}; - -module_platform_driver(vimc_deb_pdrv); - -MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids); - -MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Debayer"); -MODULE_AUTHOR("Helen Mae Koike Fornazier "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index fe99b9102ada..7cd478fee3ae 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -5,10 +5,7 @@ * Copyright (C) 2015-2017 Helen Koike */ -#include #include -#include -#include #include #include #include @@ -16,8 +13,6 @@ #include "vimc.h" #include "vimc-common.h" -#define VIMC_SCA_DRV_NAME "vimc-scaler" - static unsigned int sca_mult = 3; module_param(sca_mult, uint, 0000); MODULE_PARM_DESC(sca_mult, " the image size multiplier"); @@ -331,22 +326,21 @@ static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = { .release = vimc_sca_release, }; -static void vimc_sca_comp_unbind(struct device *comp, struct device *master, - void *master_data) +void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct vimc_ent_device *ved = dev_get_drvdata(comp); - struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device, + struct vimc_ent_device *ved = vent->ved; + struct vimc_sca_device *vsca = container_of(ved, + struct vimc_sca_device, ved); + vimc_ent_sd_unregister(ved, &vsca->sd); } -static int vimc_sca_comp_bind(struct device *comp, struct device *master, - void *master_data) +int vimc_sca_add(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct v4l2_device *v4l2_dev = master_data; - struct vimc_platform_data *pdata = comp->platform_data; + struct v4l2_device *v4l2_dev = &vimc->v4l2_dev; struct vimc_sca_device *vsca; int ret; @@ -357,7 +351,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev, - pdata->entity_name, + vent->name, MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, (const unsigned long[2]) {MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE}, @@ -368,52 +362,12 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master, } vsca->ved.process_frame = vimc_sca_process_frame; - dev_set_drvdata(comp, &vsca->ved); - vsca->dev = comp; + vsca->dev = &vimc->pdev.dev; + + vent->ved = &vsca->ved; /* Initialize the frame format */ vsca->sink_fmt = sink_fmt_default; return 0; } - -static const struct component_ops vimc_sca_comp_ops = { - .bind = vimc_sca_comp_bind, - .unbind = vimc_sca_comp_unbind, -}; - -static int vimc_sca_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &vimc_sca_comp_ops); -} - -static int vimc_sca_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &vimc_sca_comp_ops); - - return 0; -} - -static const struct platform_device_id vimc_sca_driver_ids[] = { - { - .name = VIMC_SCA_DRV_NAME, - }, - { } -}; - -static struct platform_driver vimc_sca_pdrv = { - .probe = vimc_sca_probe, - .remove = vimc_sca_remove, - .id_table = vimc_sca_driver_ids, - .driver = { - .name = VIMC_SCA_DRV_NAME, - }, -}; - -module_platform_driver(vimc_sca_pdrv); - -MODULE_DEVICE_TABLE(platform, vimc_sca_driver_ids); - -MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Scaler"); -MODULE_AUTHOR("Helen Mae Koike Fornazier "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 6c57b1e262f9..bd237e030a1b 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -5,10 +5,6 @@ * Copyright (C) 2015-2017 Helen Koike */ -#include -#include -#include -#include #include #include #include @@ -19,8 +15,6 @@ #include "vimc.h" #include "vimc-common.h" -#define VIMC_SEN_DRV_NAME "vimc-sensor" - static const struct v4l2_mbus_framefmt fmt_default = { .width = 640, .height = 480, @@ -268,12 +262,12 @@ static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = { .release = vimc_sen_release, }; -static void vimc_sen_comp_unbind(struct device *comp, struct device *master, - void *master_data) +void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct vimc_ent_device *ved = dev_get_drvdata(comp); - struct vimc_sen_device *vsen = - container_of(ved, struct vimc_sen_device, ved); + struct vimc_ent_device *ved = vent->ved; + struct vimc_sen_device *vsen = container_of(ved, + struct vimc_sen_device, + ved); vimc_ent_sd_unregister(ved, &vsen->sd); } @@ -295,11 +289,9 @@ static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = { .qmenu = tpg_pattern_strings, }; -static int vimc_sen_comp_bind(struct device *comp, struct device *master, - void *master_data) +int vimc_sen_add(struct vimc_device *vimc, struct vimc_ent_config *vent) { - struct v4l2_device *v4l2_dev = master_data; - struct vimc_platform_data *pdata = comp->platform_data; + struct v4l2_device *v4l2_dev = &vimc->v4l2_dev; struct vimc_sen_device *vsen; int ret; @@ -332,7 +324,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, - pdata->entity_name, + vent->name, MEDIA_ENT_F_CAM_SENSOR, 1, (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, &vimc_sen_int_ops, &vimc_sen_ops); @@ -340,8 +332,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, goto err_free_hdl; vsen->ved.process_frame = vimc_sen_process_frame; - dev_set_drvdata(comp, &vsen->ved); - vsen->dev = comp; + vsen->dev = &vimc->pdev.dev; /* Initialize the frame format */ vsen->mbus_format = fmt_default; @@ -353,6 +344,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, if (ret) goto err_unregister_ent_sd; + vent->ved = &vsen->ved; return 0; err_unregister_ent_sd: @@ -364,44 +356,3 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, return ret; } - -static const struct component_ops vimc_sen_comp_ops = { - .bind = vimc_sen_comp_bind, - .unbind = vimc_sen_comp_unbind, -}; - -static int vimc_sen_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &vimc_sen_comp_ops); -} - -static int vimc_sen_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &vimc_sen_comp_ops); - - return 0; -} - -static const struct platform_device_id vimc_sen_driver_ids[] = { - { - .name = VIMC_SEN_DRV_NAME, - }, - { } -}; - -static struct platform_driver vimc_sen_pdrv = { - .probe = vimc_sen_probe, - .remove = vimc_sen_remove, - .id_table = vimc_sen_driver_ids, - .driver = { - .name = VIMC_SEN_DRV_NAME, - }, -}; - -module_platform_driver(vimc_sen_pdrv); - -MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids); - -MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor"); -MODULE_AUTHOR("Helen Mae Koike Fornazier "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/vimc/vimc.h b/drivers/media/platform/vimc/vimc.h index a5adebdda941..cd527c6fe6fc 100644 --- a/drivers/media/platform/vimc/vimc.h +++ b/drivers/media/platform/vimc/vimc.h @@ -92,11 +92,30 @@ struct vimc_device { /* The Associated media_device parent */ struct media_device mdev; - /* Internal v4l2 parent device*/ + /* Internal v4l2 parent device */ struct v4l2_device v4l2_dev; +}; - /* Subdevices */ - struct platform_device **subdevs; +/* Structure which describes individual configuration for each entity */ +struct vimc_ent_config { + const char *name; + const char *drv; + struct vimc_ent_device *ved; + int (*add)(struct vimc_device *vimc, struct vimc_ent_config *vent); + void (*rm)(struct vimc_device *vimc, struct vimc_ent_config *vent); }; +/* prototypes for vimc_ent_config add and rm hooks */ +int vimc_cap_add(struct vimc_device *vimc, struct vimc_ent_config *vent); +void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_config *vent); + +int vimc_deb_add(struct vimc_device *vimc, struct vimc_ent_config *vent); +void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_config *vent); + +int vimc_sca_add(struct vimc_device *vimc, struct vimc_ent_config *vent); +void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_config *vent); + +int vimc_sen_add(struct vimc_device *vimc, struct vimc_ent_config *vent); +void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_config *vent); + #endif From patchwork Fri Aug 9 21:45:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shuah Khan X-Patchwork-Id: 11087727 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C6F414D5 for ; Fri, 9 Aug 2019 21:46:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B159204BF for ; Fri, 9 Aug 2019 21:46:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2CAC42228E; Fri, 9 Aug 2019 21:46:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A95D72237D for ; Fri, 9 Aug 2019 21:46:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728596AbfHIVp6 (ORCPT ); Fri, 9 Aug 2019 17:45:58 -0400 Received: from mail-ot1-f66.google.com ([209.85.210.66]:39861 "EHLO mail-ot1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728188AbfHIVpy (ORCPT ); Fri, 9 Aug 2019 17:45:54 -0400 Received: by mail-ot1-f66.google.com with SMTP id r21so132180629otq.6 for ; Fri, 09 Aug 2019 14:45:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Q8bv0VJFvcUca4dNFjkReaJ6w8K5woMhiQ/onkgnpeg=; b=coaW+EFbAMuceCGUBT8pJ/YDD+TnpNU0zyfWayKUPOymm32egeIGxjcQDzd/Tcs/zn lY/ewx0Sqd/l2YR0gIlQh5Kjfzf5EpyKc78HGQ+YXYWW+uKzVk06cTisXHX0JoAEG4kZ ukQJbmoVvy4sfaOcfM0OU0LGSpjOD6+JPp3Oo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Q8bv0VJFvcUca4dNFjkReaJ6w8K5woMhiQ/onkgnpeg=; b=nVU6S9VsvFs8Fhm6QVtcxhrVbFLEne/bO1HKeajKCEa3V0lZCv65HPPYdKxI3V88Ec 1DlHs34HrKUJ6BwbQw12ZQJZN2GH5f2QWT/X9nMpCzzsbOuAs9Y53y33mvQPxUxK7fb6 WI/yIk0liclGrZtuSbVZqD9l3ic3Uyn7uG2SYw2lNZ6znmGaKM6SYLdOR0VvaBz0ZbfA LIHBuLs188Lkt05ljSsetk0j9A2ezXkmyx/OSrTaVvw3c1FlhWvxxyVQ/syYyuLOOEdc W2vzmKF/CjaeF5RO7ird/C7dZOUqlLvglHYiRK28mCr0l1TG6gXho5mjVadLNfAIc4hz HJ3w== X-Gm-Message-State: APjAAAXIuyiYH+ClokZHebmbqz+ZcHQQdrjprnnBCsQ6O0WOYOoLSxj9 No+AMNWXVgqTPWIXrgvi1YKRDg== X-Google-Smtp-Source: APXvYqxaftLcNmxLkz2YDb7ubn2cO8ZuF5CD6gIUlXfbvU4C91kVGJRxpuMwXPDTJDhWtthGZuh4Uw== X-Received: by 2002:a05:6602:8e:: with SMTP id h14mr9560463iob.305.1565387153481; Fri, 09 Aug 2019 14:45:53 -0700 (PDT) Received: from shuah-t480s.internal (c-24-9-64-241.hsd1.co.comcast.net. [24.9.64.241]) by smtp.gmail.com with ESMTPSA id n17sm75861623iog.63.2019.08.09.14.45.52 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 09 Aug 2019 14:45:53 -0700 (PDT) From: Shuah Khan To: mchehab@kernel.org, helen.koike@collabora.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com Cc: Shuah Khan , linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH 3/3] media: vimc: Fix gpf in rmmod path when stream is active Date: Fri, 9 Aug 2019 15:45:43 -0600 Message-Id: <1ec378f927ed2462258d0657c6355bf916618a0e.1565386364.git.skhan@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If vimc module is removed while streaming is in progress, sensor subdev unregister runs into general protection fault when it tries to unregister media entities. vimc_ent_sd_unregister() is fixed to call vimc_pads_cleanup() to release media pads after v4l2_device_unregister_subdev() is done unregistering the subdev and stop accessing media objects. kernel: [ 4136.715839] general protection fault: 0000 [#1] SMP PTI kernel: [ 4136.715847] CPU: 2 PID: 1972 Comm: bash Not tainted 5.3.0-rc2+ #4 kernel: [ 4136.715850] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013 kernel: [ 4136.715858] RIP: 0010:media_gobj_destroy.part.16+0x1f/0x60 kernel: [ 4136.715863] Code: ff 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 fe 48 89 e5 53 48 89 fb 48 c7 c7 00 7f cf b0 e8 24 fa ff ff 48 8b 03 <48> 83 80 a0 00 00 00 01 48 8b 43 18 48 8b 53 10 48 89 42 08 48 89 kernel: [ 4136.715866] RSP: 0018:ffff9b2248fe3cb0 EFLAGS: 00010246 kernel: [ 4136.715870] RAX: bcf2bfbfa0d63c2f RBX: ffff88c3eb37e9c0 RCX: 00000000802a0018 kernel: [ 4136.715873] RDX: ffff88c3e4f6a078 RSI: ffff88c3eb37e9c0 RDI: ffffffffb0cf7f00 kernel: [ 4136.715876] RBP: ffff9b2248fe3cb8 R08: 0000000001000002 R09: ffffffffb0492b00 kernel: [ 4136.715879] R10: ffff9b2248fe3c28 R11: 0000000000000001 R12: 0000000000000038 kernel: [ 4136.715881] R13: ffffffffc09a1628 R14: ffff88c3e4f6a028 R15: fffffffffffffff2 kernel: [ 4136.715885] FS: 00007f8389647740(0000) GS:ffff88c465500000(0000) knlGS:0000000000000000 kernel: [ 4136.715888] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 kernel: [ 4136.715891] CR2: 000055d008f80fd8 CR3: 00000001996ec005 CR4: 00000000000606e0 kernel: [ 4136.715894] Call Trace: kernel: [ 4136.715903] media_gobj_destroy+0x14/0x20 kernel: [ 4136.715908] __media_device_unregister_entity+0xb3/0xe0 kernel: [ 4136.715915] media_device_unregister_entity+0x30/0x40 kernel: [ 4136.715920] v4l2_device_unregister_subdev+0xa8/0xe0 kernel: [ 4136.715928] vimc_ent_sd_unregister+0x1e/0x30 [vimc] kernel: [ 4136.715933] vimc_sen_rm+0x16/0x20 [vimc] kernel: [ 4136.715938] vimc_remove+0x3e/0xa0 [vimc] kernel: [ 4136.715945] platform_drv_remove+0x25/0x50 kernel: [ 4136.715951] device_release_driver_internal+0xe0/0x1b0 kernel: [ 4136.715956] device_driver_detach+0x14/0x20 kernel: [ 4136.715960] unbind_store+0xd1/0x130 kernel: [ 4136.715965] drv_attr_store+0x27/0x40 kernel: [ 4136.715971] sysfs_kf_write+0x48/0x60 kernel: [ 4136.715976] kernfs_fop_write+0x128/0x1b0 kernel: [ 4136.715982] __vfs_write+0x1b/0x40 kernel: [ 4136.715987] vfs_write+0xc3/0x1d0 kernel: [ 4136.715993] ksys_write+0xaa/0xe0 kernel: [ 4136.715999] __x64_sys_write+0x1a/0x20 kernel: [ 4136.716005] do_syscall_64+0x5a/0x130 kernel: [ 4136.716010] entry_SYSCALL_64_after_hwframe+0x4 Signed-off-by: Shuah Khan --- drivers/media/platform/vimc/vimc-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 03016f204d05..abace5e0b4d3 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -373,7 +373,7 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register); void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd) { media_entity_cleanup(ved->ent); - vimc_pads_cleanup(ved->pads); v4l2_device_unregister_subdev(sd); + vimc_pads_cleanup(ved->pads); } EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);