From patchwork Wed Mar 30 17:47:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Francois Moine X-Patchwork-Id: 8701991 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 708839F3D1 for ; Wed, 30 Mar 2016 18:17:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9E2392038D for ; Wed, 30 Mar 2016 18:17:16 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 80B1520379 for ; Wed, 30 Mar 2016 18:17:15 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1alKeR-0008DX-Mj; Wed, 30 Mar 2016 18:15:31 +0000 Received: from smtp5-g21.free.fr ([212.27.42.5]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1alKeO-00084f-ED for linux-arm-kernel@lists.infradead.org; Wed, 30 Mar 2016 18:15:29 +0000 Received: from localhost (unknown [IPv6:2a01:e35:2f5c:9de0:6b55:87da:4920:b782]) by smtp5-g21.free.fr (Postfix) with ESMTP id 49290D48094; Wed, 30 Mar 2016 20:10:13 +0200 (CEST) X-Mailbox-Line: From 1073caa832e647a650a2733d998e668a59c5e324 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 30 Mar 2016 19:47:40 +0200 Subject: [PATCH v2] clk: sunxi: Accept a greater rate when setting a parent clock To: Emilio Lopez , Maxime Ripard , Chen-Yu Tsai X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160330_111528_661771_B92F210D X-CRM114-Status: GOOD ( 10.84 ) X-Spam-Score: -2.1 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Message-ID: Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_MED, 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 The best rate of a clock may be a bit greater than the requested one. In such a case, the rate setting from a child clock was rejected. This patch fixes the problem searching a 'best rate' instead of a 'fastest rate <= rate'. Signed-off-by: Jean-Francois Moine --- drivers/clk/sunxi/clk-factors.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index ddefe96..c8e2f29 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -95,9 +95,10 @@ static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_factors *factors = to_clk_factors(hw); struct clk_hw *parent, *best_parent = NULL; int i, num_parents; - unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; + unsigned long parent_rate, best = 0, child_rate, best_child_rate; + unsigned long d_rate, best_d_rate = ~0ul; - /* find the parent that can help provide the fastest rate <= rate */ + /* find the parent that can help provide the best rate */ num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { struct factors_request factors_req = { @@ -116,10 +117,18 @@ static int clk_factors_determine_rate(struct clk_hw *hw, factors->get_factors(&factors_req); child_rate = factors_req.rate; - if (child_rate <= req->rate && child_rate > best_child_rate) { + if (child_rate >= req->rate) + d_rate = child_rate - req->rate; + else + d_rate = req->rate - child_rate; + + if (d_rate < best_d_rate) { best_parent = parent; best = parent_rate; best_child_rate = child_rate; + if (d_rate == 0) + break; + best_d_rate = d_rate; } }