From patchwork Tue May 20 12:52:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 30426 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f198.google.com (mail-vc0-f198.google.com [209.85.220.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2688620C03 for ; Tue, 20 May 2014 12:53:08 +0000 (UTC) Received: by mail-vc0-f198.google.com with SMTP id ij19sf1226580vcb.5 for ; Tue, 20 May 2014 05:53:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=aVTUbpsXx6PUAAC7WEAvXxc/dj/LuDrXAQRTCZBbJfg=; b=Ydw6YKr3Zj9ycWm4BzcGvQGXHfmcL2B5NdGAMeC3WUDmd7Mws6InQKEy377agzEsw1 au7Xne79D1FeTgnfImXI0GKU52WIbMjTnCIHuda0pDU4hobphlWo/W5vK8bvUpPRqH7N FXByFZEwmNPHQuwc7X+muZQVgwfQo7M2A2EZoLCzTeZQmHtV/nCTwW3JsY/yO9BB6LyL fDA2WnnYPVjnG5PIH/ZthqijmALzfLaRB/oudtZlRWPbLsWNkgAGwmejR0C4pWoE5Bjf /XIx31tEXE8YscYIgWpS+YuJv6cyDgdePG3bVKPHdBuR9IeYBXE52KJG/7rZFFccCiNL a7MQ== X-Gm-Message-State: ALoCoQmIoc1gcy/U2eq0sNtw7rg950aNl+8XcR5q9yqvop39Yi/I5Dg52FpmREJltcgwGB8/836p X-Received: by 10.236.55.69 with SMTP id j45mr7376577yhc.49.1400590387891; Tue, 20 May 2014 05:53:07 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.107.247 with SMTP id h110ls245921qgf.44.gmail; Tue, 20 May 2014 05:53:07 -0700 (PDT) X-Received: by 10.221.20.199 with SMTP id qp7mr3475743vcb.24.1400590387745; Tue, 20 May 2014 05:53:07 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id gu9si4917024vdc.160.2014.05.20.05.53.07 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 20 May 2014 05:53:07 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id il7so518767vcb.32 for ; Tue, 20 May 2014 05:53:07 -0700 (PDT) X-Received: by 10.221.64.80 with SMTP id xh16mr3468706vcb.35.1400590387660; Tue, 20 May 2014 05:53:07 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp28030vcb; Tue, 20 May 2014 05:53:07 -0700 (PDT) X-Received: by 10.68.139.36 with SMTP id qv4mr50412928pbb.82.1400590386643; Tue, 20 May 2014 05:53:06 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id qz7si1672727pbb.24.2014.05.20.05.53.06; Tue, 20 May 2014 05:53:06 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753267AbaETMwt (ORCPT + 27 others); Tue, 20 May 2014 08:52:49 -0400 Received: from mail-ie0-f176.google.com ([209.85.223.176]:61542 "EHLO mail-ie0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753055AbaETMwn (ORCPT ); Tue, 20 May 2014 08:52:43 -0400 Received: by mail-ie0-f176.google.com with SMTP id rl12so371588iec.35 for ; Tue, 20 May 2014 05:52:43 -0700 (PDT) X-Received: by 10.50.66.169 with SMTP id g9mr4433183igt.49.1400590363219; Tue, 20 May 2014 05:52:43 -0700 (PDT) Received: from localhost.localdomain (c-71-195-31-37.hsd1.mn.comcast.net. [71.195.31.37]) by mx.google.com with ESMTPSA id kw1sm28775309igb.4.2014.05.20.05.52.42 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 20 May 2014 05:52:42 -0700 (PDT) From: Alex Elder To: mturquette@linaro.org, mporter@linaro.org, bcm@fixthebug.org, devicetree@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/5] clk: bcm281xx: implement prerequisite clocks Date: Tue, 20 May 2014 07:52:39 -0500 Message-Id: <1400590362-11177-3-git-send-email-elder@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1400590362-11177-1-git-send-email-elder@linaro.org> References: <1400590362-11177-1-git-send-email-elder@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: elder@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Allow a clock to specify a "prerequisite" clock. The prerequisite clock must be initialized before the clock that depends on it. A prerequisite clock is defined initially by its name; as that clock gets initialized the name gets replaced with a pointer to its clock structure pointer. In order to allow getting a reference to a clock by its name we call clkdev_add() for each clock as it gets set up. A new clk_lookup structure is added to the kona_clk type for this purpose. Rework the KONA_CLK() macro, and define a new KONA_CLK_PREREQ() variant that allows a prerequisite clock to be specified. There exist clocks that could specify more than one prequisite, but almost all clocks only ever use one. We can add support for more than one if we find we need it at some point. Signed-off-by: Alex Elder --- drivers/clk/bcm/clk-kona-setup.c | 16 ++++++++++---- drivers/clk/bcm/clk-kona.c | 45 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/bcm/clk-kona.h | 20 +++++++++++++++--- 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index e5aeded..fcce22c 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c @@ -686,6 +686,9 @@ peri_clk_setup(struct peri_clk_data *data, struct clk_init_data *init_data) static void bcm_clk_teardown(struct kona_clk *bcm_clk) { + /* There is no function defined for this (yet) */ + /* clkdev_remove(&bcm_clk->cl); */ + switch (bcm_clk->type) { case bcm_clk_peri: peri_clk_teardown(bcm_clk->u.data, &bcm_clk->init_data); @@ -719,6 +722,7 @@ static void kona_clk_teardown(struct clk *clk) struct clk *kona_clk_setup(struct kona_clk *bcm_clk) { struct clk_init_data *init_data = &bcm_clk->init_data; + const char *name = init_data->name; struct clk *clk = NULL; switch (bcm_clk->type) { @@ -728,14 +732,13 @@ struct clk *kona_clk_setup(struct kona_clk *bcm_clk) break; default: pr_err("%s: clock type %d invalid for %s\n", __func__, - (int)bcm_clk->type, init_data->name); + (int)bcm_clk->type, name); return NULL; } /* Make sure everything makes sense before we set it up */ if (!kona_clk_valid(bcm_clk)) { - pr_err("%s: clock data invalid for %s\n", __func__, - init_data->name); + pr_err("%s: clock data invalid for %s\n", __func__, name); goto out_teardown; } @@ -743,11 +746,16 @@ struct clk *kona_clk_setup(struct kona_clk *bcm_clk) clk = clk_register(NULL, &bcm_clk->hw); if (IS_ERR(clk)) { pr_err("%s: error registering clock %s (%ld)\n", __func__, - init_data->name, PTR_ERR(clk)); + name, PTR_ERR(clk)); goto out_teardown; } BUG_ON(!clk); + /* Make it so we can look the clock up using clk_find() */ + bcm_clk->cl.con_id = name; + bcm_clk->cl.clk = clk; + clkdev_add(&bcm_clk->cl); + return clk; out_teardown: bcm_clk_teardown(bcm_clk); diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index d8a7f38..fd070d6 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c @@ -1195,6 +1195,48 @@ static bool __peri_clk_init(struct kona_clk *bcm_clk) return true; } +static bool __kona_clk_init(struct kona_clk *bcm_clk); +static bool __kona_prereq_init(struct kona_clk *bcm_clk) +{ + struct clk *clk; + struct clk_hw *hw; + struct kona_clk *prereq; + + BUG_ON(clk_is_initialized(bcm_clk)); + + if (!bcm_clk->p.prereq) + return true; + + clk = clk_get(NULL, bcm_clk->p.prereq); + if (IS_ERR(clk)) { + pr_err("%s: unable to get prereq clock %s for %s\n", + __func__, bcm_clk->p.prereq, bcm_clk->init_data.name); + return false; + } + hw = __clk_get_hw(clk); + if (!hw) { + pr_err("%s: null hw pointer for clock %s\n", __func__, + bcm_clk->init_data.name); + return false; + } + prereq = to_kona_clk(hw); + if (prereq->ccu != bcm_clk->ccu) { + pr_err("%s: prereq clock %s CCU different for clock %s\n", + __func__, bcm_clk->p.prereq, bcm_clk->init_data.name); + return false; + } + + /* Initialize the prerequisite clock first */ + if (!__kona_clk_init(prereq)) { + pr_err("%s: failed to init prereq %s for clock %s\n", + __func__, bcm_clk->p.prereq, bcm_clk->init_data.name); + return false; + } + bcm_clk->p.prereq_clk = clk; + + return true; +} + static bool __kona_clk_init(struct kona_clk *bcm_clk) { bool ret; @@ -1202,6 +1244,9 @@ static bool __kona_clk_init(struct kona_clk *bcm_clk) if (clk_is_initialized(bcm_clk)) return true; + if (!__kona_prereq_init(bcm_clk)) + return false; + switch (bcm_clk->type) { case bcm_clk_peri: ret = __peri_clk_init(bcm_clk); diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index 10e238d..a5b61e0 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define BILLION 1000000000 @@ -407,6 +409,11 @@ struct kona_clk { struct ccu_data *ccu; /* ccu this clock is associated with */ enum bcm_clk_type type; u32 flags; /* BCM_CLK_KONA_FLAGS_* below */ + struct clk_lookup cl; + union { + const char *prereq; + struct clk *prereq_clk; + } p; union { void *data; struct peri_clk_data *peri; @@ -422,15 +429,22 @@ struct kona_clk { #define BCM_CLK_KONA_FLAGS_INITIALIZED ((u32)1 << 0) /* Clock initialized */ /* Initialization macro for an entry in a CCU's kona_clks[] array. */ -#define KONA_CLK(_ccu_name, _clk_name, _type) \ - { \ +#define ___KONA_CLK_COMMON(_ccu_name, _clk_name, _type) \ .init_data = { \ .name = #_clk_name, \ .ops = &kona_ ## _type ## _clk_ops, \ }, \ .ccu = &_ccu_name ## _ccu_data, \ .type = bcm_clk_ ## _type, \ - .u.data = &_clk_name ## _data, \ + .u.data = &_clk_name ## _data +#define KONA_CLK_PREREQ(_ccu_name, _clk_name, _type, _prereq) \ + { \ + .p.prereq = #_prereq, \ + ___KONA_CLK_COMMON(_ccu_name, _clk_name, _type), \ + } +#define KONA_CLK(_ccu_name, _clk_name, _type) \ + { \ + ___KONA_CLK_COMMON(_ccu_name, _clk_name, _type), \ } #define LAST_KONA_CLK { .type = bcm_clk_none }