From patchwork Sat Jan 31 23:21:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 5755941 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 48708BF440 for ; Sat, 31 Jan 2015 23:21:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 739A62021B for ; Sat, 31 Jan 2015 23:21:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7D92A2020F for ; Sat, 31 Jan 2015 23:21:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753367AbbAaXVo (ORCPT ); Sat, 31 Jan 2015 18:21:44 -0500 Received: from mout.gmx.net ([212.227.17.20]:63363 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753052AbbAaXVn (ORCPT ); Sat, 31 Jan 2015 18:21:43 -0500 Received: from axis700.grange ([78.35.88.112]) by mail.gmx.com (mrgmx101) with ESMTPSA (Nemesis) id 0MY3Ho-1YDDH73a88-00Uq82; Sun, 01 Feb 2015 00:21:38 +0100 Received: by axis700.grange (Postfix, from userid 1000) id B7B2C40BDB; Sun, 1 Feb 2015 00:21:36 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by axis700.grange (Postfix) with ESMTP id B4FFE40BD9; Sun, 1 Feb 2015 00:21:36 +0100 (CET) Date: Sun, 1 Feb 2015 00:21:36 +0100 (CET) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: Linux Media Mailing List cc: Josh Wu , Laurent Pinchart Subject: [PATCH v3 2/2] V4L: add CCF support to the v4l2_clk API In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Provags-ID: V03:K0:VnQRob4MSqsP7v+UinMc8XKdXSEW8E2viACTvlIhYnwz8N+KPKA 1ccfg5dLgptR4uqC4L+3l8VV5jLgrvKDFlL82hilednVN9zaui4spSC8XPnercahKg5DM8V ezmlWzK20Q34B1QZPU4u9wgnraMfR2oaQ0alXOPLpoHi3HaUX9jljcZF2v/Ht5u3rn1wwfz YEizC5XLP1fyZX/btkrwQ== X-UI-Out-Filterresults: notjunk:1; Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,FREEMAIL_FROM, MALFORMED_FREEMAIL, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP V4L2 clocks, e.g. used by camera sensors for their master clock, do not have to be supplied by a different V4L2 driver, they can also be supplied by an independent source. In this case the standart kernel clock API should be used to handle such clocks. This patch adds support for such cases. Signed-off-by: Guennadi Liakhovetski Acked-by: Laurent Pinchart --- v3: 1. return -EPROBE_DEFER if it's returned by clk_get() 2. handle the case of disabled CCF in kernel configuration 3. use clk_prepare_enable() and clk_unprepare_disable() drivers/media/v4l2-core/v4l2-clk.c | 48 +++++++++++++++++++++++++++++++++++--- include/media/v4l2-clk.h | 2 ++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index 3ff0b00..9f8cb20 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -37,6 +38,21 @@ static struct v4l2_clk *v4l2_clk_find(const char *dev_id) struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) { struct v4l2_clk *clk; + struct clk *ccf_clk = clk_get(dev, id); + + if (PTR_ERR(ccf_clk) == -EPROBE_DEFER) + return ERR_PTR(-EPROBE_DEFER); + + if (!IS_ERR_OR_NULL(ccf_clk)) { + clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL); + if (!clk) { + clk_put(ccf_clk); + return ERR_PTR(-ENOMEM); + } + clk->clk = ccf_clk; + + return clk; + } mutex_lock(&clk_lock); clk = v4l2_clk_find(dev_name(dev)); @@ -56,6 +72,12 @@ void v4l2_clk_put(struct v4l2_clk *clk) if (IS_ERR(clk)) return; + if (clk->clk) { + clk_put(clk->clk); + kfree(clk); + return; + } + mutex_lock(&clk_lock); list_for_each_entry(tmp, &clk_list, list) @@ -93,8 +115,12 @@ static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) int v4l2_clk_enable(struct v4l2_clk *clk) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + if (clk->clk) + return clk_prepare_enable(clk->clk); + + ret = v4l2_clk_lock_driver(clk); if (ret < 0) return ret; @@ -120,6 +146,9 @@ void v4l2_clk_disable(struct v4l2_clk *clk) { int enable; + if (clk->clk) + return clk_disable_unprepare(clk->clk); + mutex_lock(&clk->lock); enable = --clk->enable; @@ -137,8 +166,12 @@ EXPORT_SYMBOL(v4l2_clk_disable); unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + + if (clk->clk) + return clk_get_rate(clk->clk); + ret = v4l2_clk_lock_driver(clk); if (ret < 0) return ret; @@ -157,7 +190,16 @@ EXPORT_SYMBOL(v4l2_clk_get_rate); int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + + if (clk->clk) { + long r = clk_round_rate(clk->clk, rate); + if (r < 0) + return r; + return clk_set_rate(clk->clk, r); + } + + ret = v4l2_clk_lock_driver(clk); if (ret < 0) return ret; diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 928045f..3ef6e3d 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -22,6 +22,7 @@ struct module; struct device; +struct clk; struct v4l2_clk { struct list_head list; const struct v4l2_clk_ops *ops; @@ -29,6 +30,7 @@ struct v4l2_clk { int enable; struct mutex lock; /* Protect the enable count */ atomic_t use_count; + struct clk *clk; void *priv; };