From patchwork Thu Jan 12 18:37:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamie Iles X-Patchwork-Id: 135670 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C5F19B723A for ; Fri, 13 Jan 2012 05:40:24 +1100 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1RlPWr-0007RG-Lr; Thu, 12 Jan 2012 18:37:37 +0000 Received: from mail-we0-f177.google.com ([74.125.82.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1RlPWn-0007R2-LG for linux-arm-kernel@lists.infradead.org; Thu, 12 Jan 2012 18:37:34 +0000 Received: by wera10 with SMTP id a10so2297989wer.36 for ; Thu, 12 Jan 2012 10:37:29 -0800 (PST) Received: by 10.216.135.69 with SMTP id t47mr590936wei.42.1326393449448; Thu, 12 Jan 2012 10:37:29 -0800 (PST) Received: from localhost (cpc1-chap8-2-0-cust194.aztw.cable.virginmedia.com. [94.169.120.195]) by mx.google.com with ESMTPS id a6sm1144471wiy.6.2012.01.12.10.37.28 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 12 Jan 2012 10:37:28 -0800 (PST) Date: Thu, 12 Jan 2012 18:37:28 +0000 From: Jamie Iles To: Matt Sealey Subject: Re: Clock API and "maximum rate" Message-ID: <20120112183728.GA13991@page> References: <20120111165844.GL3226@page> <20120112141128.GK1068@n2100.arm.linux.org.uk> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.177 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Russell King - ARM Linux , kernel@pengutronix.de, Linux ARM Kernel ML X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org On Thu, Jan 12, 2012 at 08:48:11AM -0600, Matt Sealey wrote: > On Thu, Jan 12, 2012 at 8:11 AM, Russell King - ARM Linux > wrote: > > On Thu, Jan 12, 2012 at 07:49:35AM -0600, Matt Sealey wrote: > >> On Wed, Jan 11, 2012 at 10:58 AM, Jamie Iles wrote: > >> > Hi Matt, > >> > > >> > On Wed, Jan 11, 2012 at 10:30:15AM -0600, Matt Sealey wrote: > >> >> Just a curious question, is there any safe way in the current API or > >> >> even by peeking a little behind the scenes to find out what the > >> >> maximum clock rate would be for a given named clock or struct clk? > >> > > >> > How about: > >> > > >> >        long max = clk_round_rate(clk, ~0LU); > >> > > >> > clk_round_rate() is one of the optional API calls though. > >> > >> Luckily implemented in this case :) Seems to do the trick, thanks. > > > > If it's not implemented, but there is an implemented clk_set_rate(), feel > > free to complain at whoever created the implementation. > > > > If there's a clk_set_rate() implementation, then there's _already_ an > > implementation of clk_round_rate() internally doing the rounding for the > > set_rate function, so there's really no excuse not to expose that via > > clk_round_rate(). > > > > clk_round_rate() is supposed to tell you what you end up with if you > > ask clk_set_rate() to set the exact same value you passed in - but > > clk_round_rate() won't modify the hardware. > > > > So, clk_round_rate/clk_set_rate really should be thought of being > > implemented as this: > > > > long clk_round_rate(struct clk *clk, unsigned long rate) > > { > >        return __clk_round_rate(clk, rate); > > } > > > > int clk_set_rate(struct clk *clk, unsigned long rate) > > { > >        long rate = __clk_round_rate(clk, rate); > > > >        if (rate < 0) > >                return rate; > > > >        return __clk_set_rate(clk, rate); > > } > > Right. On i.MX it seems not to round first, but to assume you passed a > rounded rate? I assume the upper level clk API does the above, so the > low level doesn't have to? Well each platform implements the whole clock API itself at the moment so I guess the higher layer is in plat-mxc? If so then something like the (untested) patch below may do the trick. clk_round_rate() for this platform returns 0 when it fails though and that's not right from the API: /** * clk_round_rate - adjust a rate to the exact rate a clock can provide * @clk: clock source * @rate: desired clock rate in Hz * * Returns rounded clock rate in Hz, or negative errno. */ Jamie 8<--- diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 2ed3ab1..64f679b 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -134,7 +134,7 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { if (clk == NULL || IS_ERR(clk) || !clk->round_rate) - return 0; + return -EOPNOTSUPP; return clk->round_rate(clk, rate); } @@ -146,12 +146,17 @@ EXPORT_SYMBOL(clk_round_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { int ret = -EINVAL; + long rounded_rate; if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0) return ret; + rounded_rate = clock_round_rate(clk, rate); + if (rounded_rate < 0) + return rounded_rate; + mutex_lock(&clocks_mutex); - ret = clk->set_rate(clk, rate); + ret = clk->set_rate(clk, rounded_rate); mutex_unlock(&clocks_mutex); return ret;