From patchwork Thu Nov 7 15:07:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffen Trumtrar X-Patchwork-Id: 3153141 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C14F6BEEB2 for ; Thu, 7 Nov 2013 15:10:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 073A22047C for ; Thu, 7 Nov 2013 15:10:24 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2A8A9204AE for ; Thu, 7 Nov 2013 15:10:18 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VeRCK-0001rK-5b; Thu, 07 Nov 2013 15:08:40 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VeRC3-0001Ug-Fw; Thu, 07 Nov 2013 15:08:23 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VeRBl-0001R5-TY for linux-arm-kernel@lists.infradead.org; Thu, 07 Nov 2013 15:08:07 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1VeRB1-0002fv-6Y; Thu, 07 Nov 2013 16:07:19 +0100 Received: from str by dude.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1VeRB0-0004TN-A8; Thu, 07 Nov 2013 16:07:18 +0100 From: Steffen Trumtrar To: Dinh Nguyen Subject: [PATCH 4/4] ARM: socfpga: clk: add clk_divider to periph Date: Thu, 7 Nov 2013 16:07:08 +0100 Message-Id: <1383836828-24886-5-git-send-email-s.trumtrar@pengutronix.de> X-Mailer: git-send-email 1.8.4.rc3 In-Reply-To: <1383836828-24886-1-git-send-email-s.trumtrar@pengutronix.de> References: <1383836828-24886-1-git-send-email-s.trumtrar@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: str@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131107_100806_509789_0F58B6D0 X-CRM114-Status: GOOD ( 19.53 ) X-Spam-Score: -1.9 (-) Cc: Steffen Trumtrar , Mike Turquette , kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, 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 socfpga-perip-clks all have a variable clk_divider in their path. Add it to the tree and also use clk_register_fixed_factor for the fixed-dividers instead of a custom implementation. Signed-off-by: Steffen Trumtrar --- drivers/clk/socfpga/clk-periph.c | 78 ++++++++++++++++++---------------------- drivers/clk/socfpga/clk.h | 6 ++-- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c index 7ff8f80..28f2c2d 100644 --- a/drivers/clk/socfpga/clk-periph.c +++ b/drivers/clk/socfpga/clk-periph.c @@ -1,6 +1,7 @@ /* * Copyright 2011-2012 Calxeda, Inc. * Copyright (C) 2012-2013 Altera Corporation + * Copyright (C) 2013 Steffen Trumtrar * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,37 +26,17 @@ #include "clk.h" -#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw) - -static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk, - unsigned long parent_rate) -{ - struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk); - u32 div; - - if (socfpgaclk->fixed_div) - div = socfpgaclk->fixed_div; - else - div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1); - - return parent_rate / div; -} - -static const struct clk_ops periclk_ops = { - .recalc_rate = clk_periclk_recalc_rate, -}; - -static __init void __socfpga_periph_init(struct device_node *node, - const struct clk_ops *ops) +static __init void __socfpga_periph_init(struct device_node *node) { u32 reg; - struct clk *clk; struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; const char *parent_name; - struct clk_init_data init; - int rc; + const char *div_name; u32 fixed_div; + int ret; + int i; + unsigned int clk_idx = 0; of_property_read_u32(node, "reg", ®); @@ -63,35 +44,44 @@ static __init void __socfpga_periph_init(struct device_node *node, if (WARN_ON(!periph_clk)) return; - periph_clk->hw.reg = clk_mgr_base_addr + reg; - - rc = of_property_read_u32(node, "fixed-divider", &fixed_div); - if (rc) - periph_clk->fixed_div = 0; - else - periph_clk->fixed_div = fixed_div; + periph_clk->reg = clk_mgr_base_addr + reg; of_property_read_string(node, "clock-output-names", &clk_name); - init.name = clk_name; - init.ops = ops; - init.flags = 0; parent_name = of_clk_get_parent_name(node, 0); - init.parent_names = &parent_name; - init.num_parents = 1; - periph_clk->hw.hw.init = &init; + spin_lock_init(&periph_clk->lock); - clk = clk_register(NULL, &periph_clk->hw.hw); - if (WARN_ON(IS_ERR(clk))) { - kfree(periph_clk); - return; + ret = of_property_read_u32(node, "fixed-divider", &fixed_div); + if (!ret) { + div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name); + periph_clk->clks[clk_idx++] = clk_register_fixed_factor(NULL, + div_name, parent_name, + 0, 1, fixed_div); + } else { + div_name = kasprintf(GFP_KERNEL, "%s", parent_name); } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); + + periph_clk->clks[clk_idx++] = clk_register_divider(NULL, clk_name, + div_name, 0, periph_clk->reg, 0, 9, + CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, + &periph_clk->lock); + + for (i = 0; i < ARRAY_SIZE(periph_clk->clks); i++) + if (IS_ERR(periph_clk->clks[i])) + pr_err("%s: clk %d: register failed with %ld\n", + node->name, i, PTR_ERR(periph_clk->clks[i])); + + kfree(div_name); + + periph_clk->clk_data.clks = periph_clk->clks; + periph_clk->clk_data.clk_num = clk_idx; + of_clk_add_provider(node, of_clk_src_simple_get, &periph_clk->clk_data); } static void __init socfpga_periph_init(struct device_node *node) { - __socfpga_periph_init(node, &periclk_ops); + __socfpga_periph_init(node); } CLK_OF_DECLARE(socfpga_periph, "altr,socfpga-perip-clk", socfpga_periph_init); diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h index d272048..8b60c6b 100644 --- a/drivers/clk/socfpga/clk.h +++ b/drivers/clk/socfpga/clk.h @@ -46,9 +46,11 @@ struct socfpga_gate_clk { }; struct socfpga_periph_clk { - struct clk_gate hw; + void __iomem *reg; + struct clk_onecell_data clk_data; + struct clk *clks[2]; char *parent_name; - u32 fixed_div; + spinlock_t lock; }; #endif /* SOCFPGA_CLK_H */