From patchwork Mon Aug 17 22:08:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lubomir Rintel X-Patchwork-Id: 256125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0BF4AC433E8 for ; Mon, 17 Aug 2020 22:27:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E658E2072D for ; Mon, 17 Aug 2020 22:27:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728692AbgHQW04 (ORCPT ); Mon, 17 Aug 2020 18:26:56 -0400 Received: from mail.v3.sk ([167.172.186.51]:54082 "EHLO shell.v3.sk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726315AbgHQW0y (ORCPT ); Mon, 17 Aug 2020 18:26:54 -0400 X-Greylist: delayed 1078 seconds by postgrey-1.27 at vger.kernel.org; Mon, 17 Aug 2020 18:26:52 EDT Received: from localhost (localhost.localdomain [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 04D41DF92E; Mon, 17 Aug 2020 22:08:03 +0000 (UTC) Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id UuIVB_sZDDOv; Mon, 17 Aug 2020 22:08:01 +0000 (UTC) Received: from localhost (localhost.localdomain [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 9005ADFA54; Mon, 17 Aug 2020 22:08:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at zimbra.v3.sk Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id b8tZ_xavN7PF; Mon, 17 Aug 2020 22:08:01 +0000 (UTC) Received: from localhost (unknown [109.183.109.54]) by zimbra.v3.sk (Postfix) with ESMTPSA id 5892ADF880; Mon, 17 Aug 2020 22:08:01 +0000 (UTC) From: Lubomir Rintel To: Mauro Carvalho Chehab Cc: Sakari Ailus , Jonathan Corbet , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Lubomir Rintel Subject: [PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list Date: Tue, 18 Aug 2020 00:08:48 +0200 Message-Id: <20200817220850.401287-3-lkundrak@v3.sk> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817220850.401287-1-lkundrak@v3.sk> References: <20200817220850.401287-1-lkundrak@v3.sk> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The solemn reason for this was so that it would be possible to get a mmp_camera from a platform_device in suspend/resume/remove hooks, because drvdata used to be used by the v4l core. Since commit 95db3a60e065 ("[media] v4l: Add a media_device pointer to the v4l2_device structure") it is no longer case and thus we can make things a great deal simpler. Signed-off-by: Lubomir Rintel --- Changes since v1: - Added this patch .../media/platform/marvell-ccic/mmp-driver.c | 78 ++----------------- 1 file changed, 8 insertions(+), 70 deletions(-) diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 92b92255dac66..f04c01bced2f0 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -46,49 +46,6 @@ static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam) return container_of(mcam, struct mmp_camera, mcam); } -/* - * A silly little infrastructure so we can keep track of our devices. - * Chances are that we will never have more than one of them, but - * the Armada 610 *does* have two controllers... - */ - -static LIST_HEAD(mmpcam_devices); -static struct mutex mmpcam_devices_lock; - -static void mmpcam_add_device(struct mmp_camera *cam) -{ - mutex_lock(&mmpcam_devices_lock); - list_add(&cam->devlist, &mmpcam_devices); - mutex_unlock(&mmpcam_devices_lock); -} - -static void mmpcam_remove_device(struct mmp_camera *cam) -{ - mutex_lock(&mmpcam_devices_lock); - list_del(&cam->devlist); - mutex_unlock(&mmpcam_devices_lock); -} - -/* - * Platform dev remove passes us a platform_device, and there's - * no handy unused drvdata to stash a backpointer in. So just - * dig it out of our list. - */ -static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev) -{ - struct mmp_camera *cam; - - mutex_lock(&mmpcam_devices_lock); - list_for_each_entry(cam, &mmpcam_devices, devlist) { - if (cam->pdev == pdev) { - mutex_unlock(&mmpcam_devices_lock); - return cam; - } - } - mutex_unlock(&mmpcam_devices_lock); - return NULL; -} - /* * calc the dphy register values * There are three dphy registers being used. @@ -227,6 +184,7 @@ static int mmpcam_probe(struct platform_device *pdev) cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL); if (cam == NULL) return -ENOMEM; + platform_set_drvdata(pdev, cam); cam->pdev = pdev; INIT_LIST_HEAD(&cam->devlist); @@ -313,11 +271,10 @@ static int mmpcam_probe(struct platform_device *pdev) cam->irq = res->start; ret = devm_request_irq(&pdev->dev, cam->irq, mmpcam_irq, IRQF_SHARED, "mmp-camera", mcam); - if (ret == 0) { - mmpcam_add_device(cam); - return 0; - } + if (ret) + goto out; + return 0; out: fwnode_handle_put(mcam->asd.match.fwnode); mccic_shutdown(mcam); @@ -330,14 +287,13 @@ static int mmpcam_remove(struct mmp_camera *cam) { struct mcam_camera *mcam = &cam->mcam; - mmpcam_remove_device(cam); mccic_shutdown(mcam); return 0; } static int mmpcam_platform_remove(struct platform_device *pdev) { - struct mmp_camera *cam = mmpcam_find_device(pdev); + struct mmp_camera *cam = platform_get_drvdata(pdev); if (cam == NULL) return -ENODEV; @@ -351,7 +307,7 @@ static int mmpcam_platform_remove(struct platform_device *pdev) static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state) { - struct mmp_camera *cam = mmpcam_find_device(pdev); + struct mmp_camera *cam = platform_get_drvdata(pdev); if (state.event != PM_EVENT_SUSPEND) return 0; @@ -361,7 +317,7 @@ static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state) static int mmpcam_resume(struct platform_device *pdev) { - struct mmp_camera *cam = mmpcam_find_device(pdev); + struct mmp_camera *cam = platform_get_drvdata(pdev); return mccic_resume(&cam->mcam); } @@ -387,22 +343,4 @@ static struct platform_driver mmpcam_driver = { } }; - -static int __init mmpcam_init_module(void) -{ - mutex_init(&mmpcam_devices_lock); - return platform_driver_register(&mmpcam_driver); -} - -static void __exit mmpcam_exit_module(void) -{ - platform_driver_unregister(&mmpcam_driver); - /* - * platform_driver_unregister() should have emptied the list - */ - if (!list_empty(&mmpcam_devices)) - printk(KERN_ERR "mmp_camera leaving devices behind\n"); -} - -module_init(mmpcam_init_module); -module_exit(mmpcam_exit_module); +module_platform_driver(mmpcam_driver); From patchwork Mon Aug 17 22:08:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lubomir Rintel X-Patchwork-Id: 256126 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D446C433E8 for ; Mon, 17 Aug 2020 22:27:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 48C1A20738 for ; Mon, 17 Aug 2020 22:27:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729010AbgHQW05 (ORCPT ); Mon, 17 Aug 2020 18:26:57 -0400 Received: from mail.v3.sk ([167.172.186.51]:54088 "EHLO shell.v3.sk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726778AbgHQW0y (ORCPT ); Mon, 17 Aug 2020 18:26:54 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 7A9CFDFA7A; Mon, 17 Aug 2020 22:08:04 +0000 (UTC) Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id W7eiLtROr_7X; Mon, 17 Aug 2020 22:08:03 +0000 (UTC) Received: from localhost (localhost.localdomain [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 29FF7DFA54; Mon, 17 Aug 2020 22:08:03 +0000 (UTC) X-Virus-Scanned: amavisd-new at zimbra.v3.sk Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id BbzJIudQYf77; Mon, 17 Aug 2020 22:08:02 +0000 (UTC) Received: from localhost (unknown [109.183.109.54]) by zimbra.v3.sk (Postfix) with ESMTPSA id 5D62CDFA73; Mon, 17 Aug 2020 22:08:02 +0000 (UTC) From: Lubomir Rintel To: Mauro Carvalho Chehab Cc: Sakari Ailus , Jonathan Corbet , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Lubomir Rintel Subject: [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM Date: Tue, 18 Aug 2020 00:08:50 +0200 Message-Id: <20200817220850.401287-5-lkundrak@v3.sk> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817220850.401287-1-lkundrak@v3.sk> References: <20200817220850.401287-1-lkundrak@v3.sk> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On MMP3, the camera block lives on na separate power island. We want to turn it off if the CCIC is not in use to conserve power. Signed-off-by: Lubomir Rintel --- Changes since v1: (all at suggestions from Sakari Ailus) - s/on na separate/on a separate/ in commit message - Move clock management into PM callbacks .../media/platform/marvell-ccic/mcam-core.c | 31 ++----------- .../media/platform/marvell-ccic/mmp-driver.c | 43 +++++++++++++++++-- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 3d4242b8182ba..a967f010341fa 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -893,30 +894,6 @@ static void mcam_ctlr_power_down(struct mcam_camera *cam) spin_unlock_irqrestore(&cam->dev_lock, flags); } -/* ---------------------------------------------------------------------- */ -/* - * Controller clocks. - */ -static void mcam_clk_enable(struct mcam_camera *mcam) -{ - unsigned int i; - - for (i = 0; i < NR_MCAM_CLK; i++) { - if (!IS_ERR(mcam->clk[i])) - clk_prepare_enable(mcam->clk[i]); - } -} - -static void mcam_clk_disable(struct mcam_camera *mcam) -{ - int i; - - for (i = NR_MCAM_CLK - 1; i >= 0; i--) { - if (!IS_ERR(mcam->clk[i])) - clk_disable_unprepare(mcam->clk[i]); - } -} - /* ---------------------------------------------------------------------- */ /* * Master sensor clock. @@ -1633,7 +1610,7 @@ static int mcam_v4l_open(struct file *filp) ret = sensor_call(cam, core, s_power, 1); if (ret) goto out; - mcam_clk_enable(cam); + pm_runtime_get_sync(cam->dev); __mcam_cam_reset(cam); mcam_set_config_needed(cam, 1); } @@ -1656,7 +1633,7 @@ static int mcam_v4l_release(struct file *filp) if (last_open) { mcam_disable_mipi(cam); sensor_call(cam, core, s_power, 0); - mcam_clk_disable(cam); + pm_runtime_put(cam->dev); if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) mcam_free_dma_bufs(cam); } @@ -1977,7 +1954,6 @@ void mccic_suspend(struct mcam_camera *cam) mcam_ctlr_stop_dma(cam); sensor_call(cam, core, s_power, 0); - mcam_clk_disable(cam); cam->state = cstate; } mutex_unlock(&cam->s_mutex); @@ -1990,7 +1966,6 @@ int mccic_resume(struct mcam_camera *cam) mutex_lock(&cam->s_mutex); if (!list_empty(&cam->vdev.fh_list)) { - mcam_clk_enable(cam); ret = sensor_call(cam, core, s_power, 1); if (ret) { mutex_unlock(&cam->s_mutex); diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 78263e746cad2..c4b28a00a3a24 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -274,6 +275,7 @@ static int mmpcam_probe(struct platform_device *pdev) if (ret) goto out; + pm_runtime_enable(&pdev->dev); return 0; out: fwnode_handle_put(mcam->asd.match.fwnode); @@ -288,6 +290,7 @@ static int mmpcam_remove(struct mmp_camera *cam) struct mcam_camera *mcam = &cam->mcam; mccic_shutdown(mcam); + pm_runtime_force_suspend(mcam->dev); return 0; } @@ -304,11 +307,40 @@ static int mmpcam_platform_remove(struct platform_device *pdev) * Suspend/resume support. */ +static int mmpcam_runtime_resume(struct device *dev) +{ + struct mmp_camera *cam = dev_get_drvdata(dev); + struct mcam_camera *mcam = &cam->mcam; + unsigned int i; + + for (i = 0; i < NR_MCAM_CLK; i++) { + if (!IS_ERR(mcam->clk[i])) + clk_prepare_enable(mcam->clk[i]); + } + + return 0; +} + +static int mmpcam_runtime_suspend(struct device *dev) +{ + struct mmp_camera *cam = dev_get_drvdata(dev); + struct mcam_camera *mcam = &cam->mcam; + int i; + + for (i = NR_MCAM_CLK - 1; i >= 0; i--) { + if (!IS_ERR(mcam->clk[i])) + clk_disable_unprepare(mcam->clk[i]); + } + + return 0; +} + static int mmpcam_suspend(struct device *dev) { struct mmp_camera *cam = dev_get_drvdata(dev); - mccic_suspend(&cam->mcam); + if (!pm_runtime_suspended(dev)) + mccic_suspend(&cam->mcam); return 0; } @@ -316,10 +348,15 @@ static int mmpcam_resume(struct device *dev) { struct mmp_camera *cam = dev_get_drvdata(dev); - return mccic_resume(&cam->mcam); + if (!pm_runtime_suspended(dev)) + return mccic_resume(&cam->mcam); + return 0; } -static SIMPLE_DEV_PM_OPS(mmpcam_pm_ops, mmpcam_suspend, mmpcam_resume); +static const struct dev_pm_ops mmpcam_pm_ops = { + SET_RUNTIME_PM_OPS(mmpcam_runtime_suspend, mmpcam_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(mmpcam_suspend, mmpcam_resume) +}; static const struct of_device_id mmpcam_of_match[] = { { .compatible = "marvell,mmp2-ccic", },