From patchwork Thu Jan 9 14:00:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 23016 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f72.google.com (mail-oa0-f72.google.com [209.85.219.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 95DE0216DD for ; Thu, 9 Jan 2014 14:02:07 +0000 (UTC) Received: by mail-oa0-f72.google.com with SMTP id o6sf11678956oag.11 for ; Thu, 09 Jan 2014 06:02:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=N7alq5CndiMStB0BeKyOgaqFAXFz+naEnbWjPnrcEZo=; b=jv+jzOAuJUd9Eo+H83/IMkocQizC+Ox1/WBvue3IqnoahKr9Y1+GjY2HcCmYidEwoR em3Mya0MLlW47MShV+DzdD5O53yum8vnKDRPE2nkRzGtDORW/Rhoqs6nH6NPH525RYtk T+POJWHM9KvWWhBU+GilFBFlMxe7pWjNnd3/EHm6cJmuXfr79qoK8gYpWMPu0204c+AU 8e1WJ3gS7WwGxRfbK8SdbFKLJwHVGZB8fClvH9GiDHvm5tX9N2OEkyYpDjuYr8aErM1z ygb4+ig7+k6+DDoqdrkec2RqCprtGBAJk/lFsL0iwX7FCX1Jst+nPSWKNOGhcgO702UY mAag== X-Gm-Message-State: ALoCoQle2fzub6AQvJUG5DcSk8yVqpCCZvnxYoTviFpiPC9wCN1JJDtk1uY16+dCSN8NhJ2fpiAi X-Received: by 10.182.104.70 with SMTP id gc6mr1145717obb.35.1389276126767; Thu, 09 Jan 2014 06:02:06 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.24.174 with SMTP id v14ls969529qef.74.gmail; Thu, 09 Jan 2014 06:02:06 -0800 (PST) X-Received: by 10.58.77.161 with SMTP id t1mr2002934vew.37.1389276126687; Thu, 09 Jan 2014 06:02:06 -0800 (PST) Received: from mail-vb0-f51.google.com (mail-vb0-f51.google.com [209.85.212.51]) by mx.google.com with ESMTPS id gx6si2893093vdc.24.2014.01.09.06.02.06 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 Jan 2014 06:02:06 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.51 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.51; Received: by mail-vb0-f51.google.com with SMTP id 10so466586vbe.38 for ; Thu, 09 Jan 2014 06:02:06 -0800 (PST) X-Received: by 10.52.241.103 with SMTP id wh7mr985700vdc.85.1389276126465; Thu, 09 Jan 2014 06:02:06 -0800 (PST) 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.59.13.131 with SMTP id ey3csp14274ved; Thu, 9 Jan 2014 06:02:05 -0800 (PST) X-Received: by 10.66.224.109 with SMTP id rb13mr3839233pac.78.1389276125071; Thu, 09 Jan 2014 06:02:05 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id sw1si4029475pab.112.2014.01.09.06.02.04; Thu, 09 Jan 2014 06:02:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-omap-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754908AbaAIOBw (ORCPT + 5 others); Thu, 9 Jan 2014 09:01:52 -0500 Received: from bear.ext.ti.com ([192.94.94.41]:38592 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754789AbaAIOBm (ORCPT ); Thu, 9 Jan 2014 09:01:42 -0500 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id s09E1CG8016163; Thu, 9 Jan 2014 08:01:12 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s09E1CCn024341; Thu, 9 Jan 2014 08:01:12 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.2.342.3; Thu, 9 Jan 2014 08:01:11 -0600 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s09E12W6030058; Thu, 9 Jan 2014 08:01:09 -0600 From: Tero Kristo To: , , , , , , CC: , Subject: [PATCHv13 02/40] CLK: ti: add init support for clock IP blocks Date: Thu, 9 Jan 2014 16:00:13 +0200 Message-ID: <1389276051-1326-3-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1389276051-1326-1-git-send-email-t-kristo@ti.com> References: <1389276051-1326-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: t-kristo@ti.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.51 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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: , ti_dt_clk_init_provider() can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them. This patch also introduces a helper function for the TI clock drivers to get register info from DT and append the master IP info to this. Signed-off-by: Tero Kristo --- drivers/clk/clk.c | 4 +- drivers/clk/ti/clk.c | 112 ++++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 2 + include/linux/clk/ti.h | 35 +++++++++++++ 4 files changed, 150 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 2cf2ea6..bbbe799 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2104,8 +2104,6 @@ struct of_clk_provider { void *data; }; -extern struct of_device_id __clk_of_table[]; - static const struct of_device_id __clk_of_table_sentinel __used __section(__clk_of_table_end); @@ -2245,7 +2243,7 @@ void __init of_clk_init(const struct of_device_id *matches) struct device_node *np; if (!matches) - matches = __clk_of_table; + matches = &__clk_of_table; for_each_matching_node_and_match(np, matches, &match) { of_clk_init_cb_t clk_init_cb = match->data; diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index ef1a7cd..b1a6f71 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -19,10 +19,15 @@ #include #include #include +#include +#include #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ +static int ti_dt_clk_memmap_index; +struct ti_clk_ll_ops *ti_clk_ll_ops; + /** * ti_dt_clocks_register - register DT alias clocks during boot * @oclks: list of clocks to register @@ -53,3 +58,110 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) } } } + +struct clk_init_item { + struct device_node *node; + struct clk_hw *hw; + ti_of_clk_init_cb_t func; + struct list_head link; +}; + +static LIST_HEAD(retry_list); + +/** + * ti_clk_retry_init - retries a failed clock init at later phase + * @node: device not for the clock + * @hw: partially initialized clk_hw struct for the clock + * @func: init function to be called for the clock + * + * Adds a failed clock init to the retry list. The retry list is parsed + * once all the other clocks have been initialized. + */ +int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, + ti_of_clk_init_cb_t func) +{ + struct clk_init_item *retry; + + pr_debug("%s: adding to retry list...\n", node->name); + retry = kzalloc(sizeof(*retry), GFP_KERNEL); + if (!retry) + return -ENOMEM; + + retry->node = node; + retry->func = func; + retry->hw = hw; + list_add(&retry->link, &retry_list); + + return 0; +} + +/** + * ti_clk_get_reg_addr - get register address for a clock register + * @node: device node for the clock + * @index: register index from the clock node + * + * Builds clock register address from device tree information. This + * is a struct of type clk_omap_reg. + */ +void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index) +{ + struct clk_omap_reg *reg; + u32 val; + u32 tmp; + + reg = (struct clk_omap_reg *)&tmp; + reg->index = ti_dt_clk_memmap_index; + + if (of_property_read_u32_index(node, "reg", index, &val)) { + pr_err("%s must have reg[%d]!\n", node->name, index); + return NULL; + } + + reg->offset = val; + + return (void __iomem *)tmp; +} + +/** + * ti_dt_clk_init_provider - init master clock provider + * @parent: master node + * @index: internal index for clk_reg_ops + * + * Initializes a master clock IP block and its child clock nodes. + * Regmap is provided for accessing the register space for the + * IP block and all the clocks under it. + */ +void ti_dt_clk_init_provider(struct device_node *parent, int index) +{ + const struct of_device_id *match; + struct device_node *np; + struct device_node *clocks; + of_clk_init_cb_t clk_init_cb; + struct clk_init_item *retry; + struct clk_init_item *tmp; + + ti_dt_clk_memmap_index = index; + + /* get clocks for this parent */ + clocks = of_get_child_by_name(parent, "clocks"); + if (!clocks) { + pr_err("%s missing 'clocks' child node.\n", parent->name); + return; + } + + for_each_child_of_node(clocks, np) { + match = of_match_node(&__clk_of_table, np); + if (!match) + continue; + clk_init_cb = (of_clk_init_cb_t)match->data; + pr_debug("%s: initializing: %s\n", __func__, np->name); + clk_init_cb(np); + } + + list_for_each_entry_safe(retry, tmp, &retry_list, link) { + pr_debug("retry-init: %s\n", retry->node->name); + retry->func(retry->hw, retry->node); + list_del(&retry->link); + kfree(retry); + } +} diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7e59253..5760dc8 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -458,6 +458,8 @@ struct clk_onecell_data { unsigned int clk_num; }; +extern struct of_device_id __clk_of_table; + #define CLK_OF_DECLARE(name, compat, fn) \ static const struct of_device_id __clk_of_table_##name \ __used __section(__clk_of_table) \ diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index df94c24..c6eded5 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -36,7 +36,42 @@ struct ti_dt_clk { .node_name = name, \ } +/* Maximum number of clock memmaps */ +#define CLK_MAX_MEMMAPS 4 +typedef void (*ti_of_clk_init_cb_t)(struct clk_hw *, struct device_node *); + +/** + * struct clk_omap_reg - OMAP register declaration + * @offset: offset from the master IP module base address + * @index: index of the master IP module + */ +struct clk_omap_reg { + u16 offset; + u16 index; +}; + +/** + * struct ti_clk_ll_ops - low-level register access ops for a clock + * @clk_readl: pointer to register read function + * @clk_writel: pointer to register write function + * + * Low-level register access ops are generally used by the basic clock types + * (clk-gate, clk-mux, clk-divider etc.) to provide support for various + * low-level hardware interfaces (direct MMIO, regmap etc.), but can also be + * used by other hardware-specific clock drivers if needed. + */ +struct ti_clk_ll_ops { + u32 (*clk_readl)(void __iomem *reg); + void (*clk_writel)(u32 val, void __iomem *reg); +}; + +extern struct ti_clk_ll_ops *ti_clk_ll_ops; + +void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); void ti_dt_clocks_register(struct ti_dt_clk *oclks); +void ti_dt_clk_init_provider(struct device_node *np, int index); +int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, + ti_of_clk_init_cb_t func); #endif