From patchwork Fri Mar 22 15:43:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hogan X-Patchwork-Id: 2321471 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id C56FCDFE82 for ; Fri, 22 Mar 2013 15:48:52 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UJ4AU-0007ZM-JI; Fri, 22 Mar 2013 15:46:10 +0000 Received: from multi.imgtec.com ([194.200.65.239]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UJ49L-0007GQ-NI for linux-arm-kernel@lists.infradead.org; Fri, 22 Mar 2013 15:45:00 +0000 From: James Hogan To: Mike Turquette , , Subject: [RFC PATCH v1 3/3] clk: clk-mux: implement remuxing Date: Fri, 22 Mar 2013 15:43:51 +0000 Message-ID: <1363967031-22781-4-git-send-email-james.hogan@imgtec.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1363967031-22781-1-git-send-email-james.hogan@imgtec.com> References: <1363967031-22781-1-git-send-email-james.hogan@imgtec.com> MIME-Version: 1.0 X-SEF-Processed: 7_3_0_01181__2013_03_22_15_44_55 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130322_114500_055533_FA66765B X-CRM114-Status: GOOD ( 11.21 ) X-Spam-Score: -4.4 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: James Hogan , Sascha Hauer , Chao Xie X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Implement clk-mux remuxing if the CLK_SET_RATE_REMUX flag is set. This implements round_rate for clk-mux to propagate the round_rate to each parent and to choose the best one. Signed-off-by: James Hogan --- drivers/clk/clk-mux.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 508c032..20b3f0b 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -82,9 +82,56 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) return 0; } +/* Return index of parent that provides best clock rate */ +static int clk_mux_bestparent(struct clk *clk, unsigned long rate, + unsigned long *best_parent_rate) +{ + int i, num_parents, bestparent = -1; + unsigned long parent_rate, best = 0; + struct clk *parent; + + num_parents = __clk_get_num_parents(clk); + for (i = 0; i < num_parents; i++) { + parent = __clk_get_parent_by_index(clk, i); + if (!parent) + continue; + parent_rate = __clk_round_rate(parent, rate); + if (parent_rate <= rate && parent_rate > best) { + bestparent = i; + best = parent_rate; + *best_parent_rate = parent_rate; + } + } + + return bestparent; +} + +static long clk_mux_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate, u8 *best_parent) +{ + struct clk *clk = hw->clk; + unsigned long flags = __clk_get_flags(clk); + int parent; + + /* never remux unless the flag is set */ + if (!(flags & CLK_SET_RATE_REMUX)) { + if (flags & CLK_SET_RATE_PARENT) + return __clk_round_rate(__clk_get_parent(clk), rate); + else + return __clk_get_rate(clk); + } + + parent = clk_mux_bestparent(clk, rate, prate); + if (best_parent && parent >= 0) + *best_parent = parent; + + return *prate; +} + const struct clk_ops clk_mux_ops = { .get_parent = clk_mux_get_parent, .set_parent = clk_mux_set_parent, + .round_rate = clk_mux_round_rate, }; EXPORT_SYMBOL_GPL(clk_mux_ops);