From patchwork Tue Jan 7 12:59:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 3448021 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7E5C19F1C4 for ; Tue, 7 Jan 2014 13:03:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4D451200F4 for ; Tue, 7 Jan 2014 13:03:22 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 45DF9200E9 for ; Tue, 7 Jan 2014 13:03:19 +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 1W0WI6-000070-4L; Tue, 07 Jan 2014 13:01:55 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W0WHl-0006KK-JR; Tue, 07 Jan 2014 13:01:33 +0000 Received: from mailout1.samsung.com ([203.254.224.24]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W0WH1-0006Bi-WE for linux-arm-kernel@lists.infradead.org; Tue, 07 Jan 2014 13:00:54 +0000 Received: from epcpsbgr3.samsung.com (u143.gpu120.samsung.co.kr [203.254.230.143]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MZ1006ND84QIC00@mailout1.samsung.com> for linux-arm-kernel@lists.infradead.org; Tue, 07 Jan 2014 22:00:26 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.122]) by epcpsbgr3.samsung.com (EPCPMTA) with SMTP id FF.E7.10092.A6AFBC25; Tue, 07 Jan 2014 22:00:26 +0900 (KST) X-AuditID: cbfee68f-b7f156d00000276c-41-52cbfa6aae27 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 75.59.28157.A6AFBC25; Tue, 07 Jan 2014 22:00:26 +0900 (KST) Received: from localhost.localdomain ([107.108.83.245]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MZ10091R83QNV20@mmp2.samsung.com>; Tue, 07 Jan 2014 22:00:26 +0900 (KST) From: Rahul Sharma To: linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH V2 04/10] clk/samsung: add support for multiple clock providers Date: Tue, 07 Jan 2014 18:29:02 +0530 Message-id: <1389099548-14649-5-git-send-email-rahul.sharma@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1389099548-14649-1-git-send-email-rahul.sharma@samsung.com> References: <1389099548-14649-1-git-send-email-rahul.sharma@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpikeLIzCtJLcpLzFFi42JZI2JSpZv163SQQeNuDYv5R86xWnzf9YXd onfBVTaLTY+vsVrMOL+PyeLphItsFgtfxFtMWXSY1aJjGaPFql1/GB24PHbOusvucefaHjaP zUvqPfq2rGL0+LxJLoA1issmJTUnsyy1SN8ugSvj3Z0jTAVnfzBWbHi8jq2Bcfolxi5GTg4J AROJ7w8a2CBsMYkL99YD2VwcQgJLGSVmP70D5HCAFc2+qwcRn84o8ejkR1YIp51J4tTNWawg 3WwCuhKzDz5jBGkQEciU2LglFyTMLLCZUeLbZjUQW1jAX+Lz9pPsIDaLgKrEhFtvmUBsXgEP iZdr/7JA7FKQmDPJBiTMKeApcXBGM1i5EFDJ0yeXmUHWSghsY5eY9O4SG8QcAYlvkw9B9cpK bDrADPGLpMTBFTdYJjAKL2BkWMUomlqQXFCclF5krFecmFtcmpeul5yfu4kRGP6n/z3r38F4 94D1IcZkoHETmaVEk/OB8ZNXEm9obGZkYWpiamxkbmlGmrCSOO/9h0lBQgLpiSWp2ampBalF 8UWlOanFhxiZODilGhhzlZjYQg9GhGh8iHrvLnN/z1yezq2tHDlZaQxZLCK/s99EOlrtrt33 5cEW/2t1dWpOUwq0tu6NOn405rZGLsM2wW9rM66H9U6zYK9v9vArP5pg9oQ79vzTS8+nLvVS O/6noLlvD2dLSpOL30++JwXPjKfY3H7zaMaRcEnJnXs2/mqa8+tn6DYlluKMREMt5qLiRAAO jwyblQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrPIsWRmVeSWpSXmKPExsVy+t9jQd2sX6eDDBq+SVnMP3KO1eL7ri/s Fr0LrrJZbHp8jdVixvl9TBZPJ1xks1j4It5iyqLDrBYdyxgtVu36w+jA5bFz1l12jzvX9rB5 bF5S79G3ZRWjx+dNcgGsUQ2MNhmpiSmpRQqpecn5KZl56bZK3sHxzvGmZgaGuoaWFuZKCnmJ uam2Si4+AbpumTlANykplCXmlAKFAhKLi5X07TBNCA1x07WAaYzQ9Q0JgusxMkADCWsYM97d OcJUcPYHY8WGx+vYGhinX2LsYuTgkBAwkZh9V6+LkRPIFJO4cG89WxcjF4eQwHRGiUcnP7JC OO1MEqduzmIFqWIT0JWYffAZWLOIQKbExi25IGFmgc2MEt82q4HYwgL+Ep+3n2QHsVkEVCUm 3HrLBGLzCnhIvFz7lwVir4LEnEk2IGFOAU+JgzOawcqFgEqePrnMPIGRdwEjwypG0dSC5ILi pPRcI73ixNzi0rx0veT83E2M4Oh6Jr2DcVWDxSFGAQ5GJR7eF3tPBQmxJpYVV+YeYpTgYFYS 4WW+cTpIiDclsbIqtSg/vqg0J7X4EGMy0FETmaVEk/OBkZ9XEm9obGJuamxqaWJhYmZJmrCS OO/BVutAIYH0xJLU7NTUgtQimC1MHJxSDYzNsbp+L9Zrl/qGOC+8N/GNxGEtQ/OzFst2z+K3 27bX7VQ2b8iNe9dXb27TFmo6bc1ntb3/6pEzovGLnM5H3eP9dtn1kpKsZDHz1baQNhWZnqQn V4+cu9DlZno099Cqkz9Ppvtr+2a2ajLt6LmrV/a66Id51c39Wb5nk2Sb4/qdbDj+P11fdk+J pTgj0VCLuag4EQBznsIk8gIAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140107_080048_517287_7EABD936 X-CRM114-Status: GOOD ( 12.73 ) X-Spam-Score: -6.9 (------) Cc: kgene.kim@samsung.com, mturquette@linaro.org, joshi@samsung.com, tomasz.figa@gmail.com, thomas.ab@samsung.com, r.sh.open@gmail.com, Rahul Sharma 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 Samsung CCF helper functions do not provide support to register multiple Clock Providers for a given SoC. Due to this limitation SoC platforms are not able to use these helpers for registering multiple clock providers and are forced to bypass this layer. This layer is modified accordingly to enable the support. Clock file for exynos4, exynos5250, exynos5420, exynos5440 and S3c64xx are also modified as per changed helper functions. Signed-off-by: Rahul Sharma --- drivers/clk/samsung/clk-exynos4.c | 47 +++++++------- drivers/clk/samsung/clk-exynos5250.c | 26 +++++--- drivers/clk/samsung/clk-exynos5410.c | 14 +++-- drivers/clk/samsung/clk-exynos5420.c | 24 ++++--- drivers/clk/samsung/clk-exynos5440.c | 18 +++--- drivers/clk/samsung/clk-pll.c | 14 +++-- drivers/clk/samsung/clk-s3c64xx.c | 44 +++++++------ drivers/clk/samsung/clk.c | 115 +++++++++++++++++++--------------- drivers/clk/samsung/clk.h | 72 ++++++++++++++------- 9 files changed, 220 insertions(+), 154 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 50f6e00..5e47abf 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1094,7 +1094,7 @@ static unsigned long exynos4_get_xom(void) return xom; } -static void __init exynos4_clk_register_finpll(void) +static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx) { struct samsung_fixed_rate_clock fclk; struct clk *clk; @@ -1117,7 +1117,7 @@ static void __init exynos4_clk_register_finpll(void) fclk.parent_name = NULL; fclk.flags = CLK_IS_ROOT; fclk.fixed_rate = finpll_f; - samsung_clk_register_fixed_rate(&fclk, 1); + samsung_clk_register_fixed_rate(ctx, &fclk, 1); } @@ -1227,22 +1227,25 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = { static void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc soc) { + struct samsung_clk_provider *ctx; exynos4_soc = soc; reg_base = of_iomap(np, 0); if (!reg_base) panic("%s: failed to map registers\n", __func__); - samsung_clk_init(np, reg_base, nr_clks); + ctx = samsung_clk_init(np, reg_base, nr_clks); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); - samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, + samsung_clk_of_register_fixed_ext(ctx, exynos4_fixed_rate_ext_clks, ARRAY_SIZE(exynos4_fixed_rate_ext_clks), ext_clk_match); - exynos4_clk_register_finpll(); + exynos4_clk_register_finpll(ctx); if (exynos4_soc == EXYNOS4210) { - samsung_clk_register_mux(exynos4210_mux_early, + samsung_clk_register_mux(ctx, exynos4210_mux_early, ARRAY_SIZE(exynos4210_mux_early)); if (_get_rate("fin_pll") == 24000000) { @@ -1256,7 +1259,7 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4210_plls[vpll].rate_table = exynos4210_vpll_rates; - samsung_clk_register_pll(exynos4210_plls, + samsung_clk_register_pll(ctx, exynos4210_plls, ARRAY_SIZE(exynos4210_plls), reg_base); } else { if (_get_rate("fin_pll") == 24000000) { @@ -1268,42 +1271,42 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4x12_vpll_rates; } - samsung_clk_register_pll(exynos4x12_plls, + samsung_clk_register_pll(ctx, exynos4x12_plls, ARRAY_SIZE(exynos4x12_plls), reg_base); } - samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos4_fixed_rate_clks, ARRAY_SIZE(exynos4_fixed_rate_clks)); - samsung_clk_register_mux(exynos4_mux_clks, + samsung_clk_register_mux(ctx, exynos4_mux_clks, ARRAY_SIZE(exynos4_mux_clks)); - samsung_clk_register_div(exynos4_div_clks, + samsung_clk_register_div(ctx, exynos4_div_clks, ARRAY_SIZE(exynos4_div_clks)); - samsung_clk_register_gate(exynos4_gate_clks, + samsung_clk_register_gate(ctx, exynos4_gate_clks, ARRAY_SIZE(exynos4_gate_clks)); if (exynos4_soc == EXYNOS4210) { - samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos4210_fixed_rate_clks, ARRAY_SIZE(exynos4210_fixed_rate_clks)); - samsung_clk_register_mux(exynos4210_mux_clks, + samsung_clk_register_mux(ctx, exynos4210_mux_clks, ARRAY_SIZE(exynos4210_mux_clks)); - samsung_clk_register_div(exynos4210_div_clks, + samsung_clk_register_div(ctx, exynos4210_div_clks, ARRAY_SIZE(exynos4210_div_clks)); - samsung_clk_register_gate(exynos4210_gate_clks, + samsung_clk_register_gate(ctx, exynos4210_gate_clks, ARRAY_SIZE(exynos4210_gate_clks)); - samsung_clk_register_alias(exynos4210_aliases, + samsung_clk_register_alias(ctx, exynos4210_aliases, ARRAY_SIZE(exynos4210_aliases)); } else { - samsung_clk_register_mux(exynos4x12_mux_clks, + samsung_clk_register_mux(ctx, exynos4x12_mux_clks, ARRAY_SIZE(exynos4x12_mux_clks)); - samsung_clk_register_div(exynos4x12_div_clks, + samsung_clk_register_div(ctx, exynos4x12_div_clks, ARRAY_SIZE(exynos4x12_div_clks)); - samsung_clk_register_gate(exynos4x12_gate_clks, + samsung_clk_register_gate(ctx, exynos4x12_gate_clks, ARRAY_SIZE(exynos4x12_gate_clks)); - samsung_clk_register_alias(exynos4x12_aliases, + samsung_clk_register_alias(ctx, exynos4x12_aliases, ARRAY_SIZE(exynos4x12_aliases)); } - samsung_clk_register_alias(exynos4_aliases, + samsung_clk_register_alias(ctx, exynos4_aliases, ARRAY_SIZE(exynos4_aliases)); exynos4_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 82f14e1..af4f7fd 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -583,6 +583,8 @@ static struct of_device_id ext_clk_match[] __initdata = { /* register exynox5250 clocks */ static void __init exynos5250_clk_init(struct device_node *np) { + struct samsung_clk_provider *ctx; + if (np) { reg_base = of_iomap(np, 0); if (!reg_base) @@ -591,11 +593,14 @@ static void __init exynos5250_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, nr_clks); - samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, nr_clks); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_of_register_fixed_ext(ctx, exynos5250_fixed_rate_ext_clks, ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), ext_clk_match); - samsung_clk_register_mux(exynos5250_pll_pmux_clks, + samsung_clk_register_mux(ctx, exynos5250_pll_pmux_clks, ARRAY_SIZE(exynos5250_pll_pmux_clks)); if (_get_rate("fin_pll") == 24 * MHZ) @@ -604,17 +609,18 @@ static void __init exynos5250_clk_init(struct device_node *np) if (_get_rate("mout_vpllsrc") == 24 * MHZ) exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; - samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls), - reg_base); - samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks, + samsung_clk_register_pll(ctx, exynos5250_plls, + ARRAY_SIZE(exynos5250_plls), + reg_base); + samsung_clk_register_fixed_rate(ctx, exynos5250_fixed_rate_clks, ARRAY_SIZE(exynos5250_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5250_fixed_factor_clks, ARRAY_SIZE(exynos5250_fixed_factor_clks)); - samsung_clk_register_mux(exynos5250_mux_clks, + samsung_clk_register_mux(ctx, exynos5250_mux_clks, ARRAY_SIZE(exynos5250_mux_clks)); - samsung_clk_register_div(exynos5250_div_clks, + samsung_clk_register_div(ctx, exynos5250_div_clks, ARRAY_SIZE(exynos5250_div_clks)); - samsung_clk_register_gate(exynos5250_gate_clks, + samsung_clk_register_gate(ctx, exynos5250_gate_clks, ARRAY_SIZE(exynos5250_gate_clks)); exynos5250_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c index f94c493..c761e9d 100644 --- a/drivers/clk/samsung/clk-exynos5410.c +++ b/drivers/clk/samsung/clk-exynos5410.c @@ -255,20 +255,24 @@ static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { /* register exynos5410 clocks */ static void __init exynos5410_clk_init(struct device_node *np) { + struct samsung_clk_provider *ctx; + reg_base = of_iomap(np, 0); if (!reg_base) panic("%s: failed to map registers\n", __func__); - samsung_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); - samsung_clk_register_pll(exynos5410_plls, ARRAY_SIZE(exynos5410_plls), + samsung_clk_register_pll(ctx, exynos5410_plls, ARRAY_SIZE(exynos5410_plls), reg_base); - samsung_clk_register_mux(exynos5410_mux_clks, + samsung_clk_register_mux(ctx, exynos5410_mux_clks, ARRAY_SIZE(exynos5410_mux_clks)); - samsung_clk_register_div(exynos5410_div_clks, + samsung_clk_register_div(ctx, exynos5410_div_clks, ARRAY_SIZE(exynos5410_div_clks)); - samsung_clk_register_gate(exynos5410_gate_clks, + samsung_clk_register_gate(ctx, exynos5410_gate_clks, ARRAY_SIZE(exynos5410_gate_clks)); exynos5410_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9de5bfd..e5493cf 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -808,6 +808,8 @@ static struct of_device_id ext_clk_match[] __initdata = { /* register exynos5420 clocks */ static void __init exynos5420_clk_init(struct device_node *np) { + struct samsung_clk_provider *ctx; + if (np) { reg_base = of_iomap(np, 0); if (!reg_base) @@ -816,21 +818,25 @@ static void __init exynos5420_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, nr_clks); - samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, nr_clks); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_of_register_fixed_ext(ctx, exynos5420_fixed_rate_ext_clks, ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), ext_clk_match); - samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls), - reg_base); - samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks, + samsung_clk_register_pll(ctx, exynos5420_plls, + ARRAY_SIZE(exynos5420_plls), + reg_base); + samsung_clk_register_fixed_rate(ctx, exynos5420_fixed_rate_clks, ARRAY_SIZE(exynos5420_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5420_fixed_factor_clks, ARRAY_SIZE(exynos5420_fixed_factor_clks)); - samsung_clk_register_mux(exynos5420_mux_clks, + samsung_clk_register_mux(ctx, exynos5420_mux_clks, ARRAY_SIZE(exynos5420_mux_clks)); - samsung_clk_register_div(exynos5420_div_clks, + samsung_clk_register_div(ctx, exynos5420_div_clks, ARRAY_SIZE(exynos5420_div_clks)); - samsung_clk_register_gate(exynos5420_gate_clks, + samsung_clk_register_gate(ctx, exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks)); exynos5420_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index e3e460a..c2f5d3c 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -106,6 +106,7 @@ static struct of_device_id ext_clk_match[] __initdata = { static void __init exynos5440_clk_init(struct device_node *np) { void __iomem *reg_base; + struct samsung_clk_provider *ctx; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -114,22 +115,25 @@ static void __init exynos5440_clk_init(struct device_node *np) return; } - samsung_clk_init(np, reg_base, nr_clks); - samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, nr_clks); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks, ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); samsung_clk_register_pll2550x("cplla", "xtal", reg_base + 0x1c, 0x10); samsung_clk_register_pll2550x("cpllb", "xtal", reg_base + 0x20, 0x10); - samsung_clk_register_fixed_rate(exynos5440_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos5440_fixed_rate_clks, ARRAY_SIZE(exynos5440_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5440_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5440_fixed_factor_clks, ARRAY_SIZE(exynos5440_fixed_factor_clks)); - samsung_clk_register_mux(exynos5440_mux_clks, + samsung_clk_register_mux(ctx, exynos5440_mux_clks, ARRAY_SIZE(exynos5440_mux_clks)); - samsung_clk_register_div(exynos5440_div_clks, + samsung_clk_register_div(ctx, exynos5440_div_clks, ARRAY_SIZE(exynos5440_div_clks)); - samsung_clk_register_gate(exynos5440_gate_clks, + samsung_clk_register_gate(ctx, exynos5440_gate_clks, ARRAY_SIZE(exynos5440_gate_clks)); pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 529e11d..e8e8953 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -710,8 +710,9 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name, return clk; } -static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, - void __iomem *base) +static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_clk, + void __iomem *base) { struct samsung_clk_pll *pll; struct clk *clk; @@ -804,7 +805,7 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, return; } - samsung_clk_add_lookup(clk, pll_clk->id); + samsung_clk_add_lookup(ctx, clk, pll_clk->id); if (!pll_clk->alias) return; @@ -815,11 +816,12 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, __func__, pll_clk->name, ret); } -void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, - unsigned int nr_pll, void __iomem *base) +void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_list, + unsigned int nr_pll, void __iomem *base) { int cnt; for (cnt = 0; cnt < nr_pll; cnt++) - _samsung_clk_register_pll(&pll_list[cnt], base); + _samsung_clk_register_pll(ctx, &pll_list[cnt], base); } diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index a43cbde..b7d06ae 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -442,12 +442,14 @@ static struct samsung_clock_alias s3c6410_clock_aliases[] = { ALIAS(MEM0_SROM, NULL, "srom"), }; -static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f, - unsigned long xusbxti_f) +static void __init s3c64xx_clk_register_fixed_ext( + struct samsung_clk_provider *ctx, + unsigned long fin_pll_f, + unsigned long xusbxti_f) { s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f; s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f; - samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks, + samsung_clk_register_fixed_rate(ctx, s3c64xx_fixed_rate_ext_clks, ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks)); } @@ -456,6 +458,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, unsigned long xusbxti_f, bool s3c6400, void __iomem *base) { + struct samsung_clk_provider *ctx; + reg_base = base; is_s3c6400 = s3c6400; @@ -465,48 +469,50 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS); + ctx = samsung_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); /* Register external clocks. */ if (!np) - s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f); + s3c64xx_clk_register_fixed_ext(ctx, xtal_f, xusbxti_f); /* Register PLLs. */ - samsung_clk_register_pll(s3c64xx_pll_clks, + samsung_clk_register_pll(ctx, s3c64xx_pll_clks, ARRAY_SIZE(s3c64xx_pll_clks), reg_base); /* Register common internal clocks. */ - samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, s3c64xx_fixed_rate_clks, ARRAY_SIZE(s3c64xx_fixed_rate_clks)); - samsung_clk_register_mux(s3c64xx_mux_clks, + samsung_clk_register_mux(ctx, s3c64xx_mux_clks, ARRAY_SIZE(s3c64xx_mux_clks)); - samsung_clk_register_div(s3c64xx_div_clks, + samsung_clk_register_div(ctx, s3c64xx_div_clks, ARRAY_SIZE(s3c64xx_div_clks)); - samsung_clk_register_gate(s3c64xx_gate_clks, + samsung_clk_register_gate(ctx, s3c64xx_gate_clks, ARRAY_SIZE(s3c64xx_gate_clks)); /* Register SoC-specific clocks. */ if (is_s3c6400) { - samsung_clk_register_mux(s3c6400_mux_clks, + samsung_clk_register_mux(ctx, s3c6400_mux_clks, ARRAY_SIZE(s3c6400_mux_clks)); - samsung_clk_register_div(s3c6400_div_clks, + samsung_clk_register_div(ctx, s3c6400_div_clks, ARRAY_SIZE(s3c6400_div_clks)); - samsung_clk_register_gate(s3c6400_gate_clks, + samsung_clk_register_gate(ctx, s3c6400_gate_clks, ARRAY_SIZE(s3c6400_gate_clks)); - samsung_clk_register_alias(s3c6400_clock_aliases, + samsung_clk_register_alias(ctx, s3c6400_clock_aliases, ARRAY_SIZE(s3c6400_clock_aliases)); } else { - samsung_clk_register_mux(s3c6410_mux_clks, + samsung_clk_register_mux(ctx, s3c6410_mux_clks, ARRAY_SIZE(s3c6410_mux_clks)); - samsung_clk_register_div(s3c6410_div_clks, + samsung_clk_register_div(ctx, s3c6410_div_clks, ARRAY_SIZE(s3c6410_div_clks)); - samsung_clk_register_gate(s3c6410_gate_clks, + samsung_clk_register_gate(ctx, s3c6410_gate_clks, ARRAY_SIZE(s3c6410_gate_clks)); - samsung_clk_register_alias(s3c6410_clock_aliases, + samsung_clk_register_alias(ctx, s3c6410_clock_aliases, ARRAY_SIZE(s3c6410_clock_aliases)); } - samsung_clk_register_alias(s3c64xx_clock_aliases, + samsung_clk_register_alias(ctx, s3c64xx_clock_aliases, ARRAY_SIZE(s3c64xx_clock_aliases)); s3c64xx_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 91bec3e..c75eb11 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -14,13 +14,6 @@ #include #include "clk.h" -static DEFINE_SPINLOCK(lock); -static struct clk **clk_table; -static void __iomem *reg_base; -#ifdef CONFIG_OF -static struct clk_onecell_data clk_data; -#endif - void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -55,40 +48,54 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( } /* setup the essentials required to support clock lookup using ccf */ -void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks) +struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks) { - reg_base = base; + struct samsung_clk_provider *ctx; + struct clk **clk_table; + int ret; + + ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); + if (!ctx) + panic("could not allocate clock provider context.\n"); clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); if (!clk_table) panic("could not allocate clock lookup table\n"); + ctx->reg_base = base; + ctx->clk_data.clks = clk_table; + ctx->clk_data.clk_num = nr_clks; + ctx->lock = __SPIN_LOCK_UNLOCKED(lock); + if (!np) - return; + return ctx; -#ifdef CONFIG_OF - clk_data.clks = clk_table; - clk_data.clk_num = nr_clks; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -#endif + ret = of_clk_add_provider(np, of_clk_src_onecell_get, + &ctx->clk_data); + if (ret) + panic("could not register clock provide\n"); + + return ctx; } /* add a clock instance to the clock lookup table used for dt based lookup */ -void samsung_clk_add_lookup(struct clk *clk, unsigned int id) +void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk, + unsigned int id) { - if (clk_table && id) - clk_table[id] = clk; + if (ctx->clk_data.clks && id) + ctx->clk_data.clks[id] = clk; } /* register a list of aliases */ -void __init samsung_clk_register_alias(struct samsung_clock_alias *list, - unsigned int nr_clk) +void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, + struct samsung_clock_alias *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; - if (!clk_table) { + if (!ctx->clk_data.clks) { pr_err("%s: clock table missing\n", __func__); return; } @@ -100,7 +107,7 @@ void __init samsung_clk_register_alias(struct samsung_clock_alias *list, continue; } - clk = clk_table[list->id]; + clk = ctx->clk_data.clks[list->id]; if (!clk) { pr_err("%s: failed to find clock %d\n", __func__, list->id); @@ -115,7 +122,7 @@ void __init samsung_clk_register_alias(struct samsung_clock_alias *list, } /* register a list of fixed clocks */ -void __init samsung_clk_register_fixed_rate( +void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *list, unsigned int nr_clk) { struct clk *clk; @@ -130,7 +137,7 @@ void __init samsung_clk_register_fixed_rate( continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* * Unconditionally add a clock lookup for the fixed rate clocks. @@ -144,7 +151,7 @@ void __init samsung_clk_register_fixed_rate( } /* register a list of fixed factor clocks */ -void __init samsung_clk_register_fixed_factor( +void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, struct samsung_fixed_factor_clock *list, unsigned int nr_clk) { struct clk *clk; @@ -159,28 +166,30 @@ void __init samsung_clk_register_fixed_factor( continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); } } /* register a list of mux clocks */ -void __init samsung_clk_register_mux(struct samsung_mux_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, + struct samsung_mux_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { clk = clk_register_mux(NULL, list->name, list->parent_names, - list->num_parents, list->flags, reg_base + list->offset, - list->shift, list->width, list->mux_flags, &lock); + list->num_parents, list->flags, + ctx->reg_base + list->offset, + list->shift, list->width, list->mux_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { @@ -194,8 +203,9 @@ void __init samsung_clk_register_mux(struct samsung_mux_clock *list, } /* register a list of div clocks */ -void __init samsung_clk_register_div(struct samsung_div_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, + struct samsung_div_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; @@ -203,22 +213,22 @@ void __init samsung_clk_register_div(struct samsung_div_clock *list, for (idx = 0; idx < nr_clk; idx++, list++) { if (list->table) clk = clk_register_divider_table(NULL, list->name, - list->parent_name, list->flags, - reg_base + list->offset, list->shift, - list->width, list->div_flags, - list->table, &lock); + list->parent_name, list->flags, + ctx->reg_base + list->offset, + list->shift, list->width, list->div_flags, + list->table, &ctx->lock); else clk = clk_register_divider(NULL, list->name, - list->parent_name, list->flags, - reg_base + list->offset, list->shift, - list->width, list->div_flags, &lock); + list->parent_name, list->flags, + ctx->reg_base + list->offset, list->shift, + list->width, list->div_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { @@ -232,16 +242,17 @@ void __init samsung_clk_register_div(struct samsung_div_clock *list, } /* register a list of gate clocks */ -void __init samsung_clk_register_gate(struct samsung_gate_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, + struct samsung_gate_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { clk = clk_register_gate(NULL, list->name, list->parent_name, - list->flags, reg_base + list->offset, - list->bit_idx, list->gate_flags, &lock); + list->flags, ctx->reg_base + list->offset, + list->bit_idx, list->gate_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); @@ -257,7 +268,7 @@ void __init samsung_clk_register_gate(struct samsung_gate_clock *list, __func__, list->alias); } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); } } @@ -266,21 +277,21 @@ void __init samsung_clk_register_gate(struct samsung_gate_clock *list, * tree and register it */ #ifdef CONFIG_OF -void __init samsung_clk_of_register_fixed_ext( +void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, struct of_device_id *clk_matches) { const struct of_device_id *match; - struct device_node *np; + struct device_node *clk_np; u32 freq; - for_each_matching_node_and_match(np, clk_matches, &match) { - if (of_property_read_u32(np, "clock-frequency", &freq)) + for_each_matching_node_and_match(clk_np, clk_matches, &match) { + if (of_property_read_u32(clk_np, "clock-frequency", &freq)) continue; fixed_rate_clk[(u32)match->data].fixed_rate = freq; } - samsung_clk_register_fixed_rate(fixed_rate_clk, nr_fixed_rate_clk); + samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); } #endif diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index c7141ba..9693b80 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -22,6 +22,18 @@ #include "clk-pll.h" /** + * struct samsung_clk_provider: information about clock provider + * @reg_base: virtual address for the register base. + * @clk_data: holds clock related data like clk* and number of clocks. + * @lock: maintains exclusion bwtween callbacks for a given clock-provider. + */ +struct samsung_clk_provider { + void __iomem *reg_base; + struct clk_onecell_data clk_data; + spinlock_t lock; +}; + +/** * struct samsung_clock_alias: information about mux clock * @id: platform specific id of the clock. * @dev_name: name of the device to which this clock belongs. @@ -312,40 +324,52 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) -extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks); +extern struct samsung_clk_provider *__init samsung_clk_init( + struct device_node *np, void __iomem *base, + unsigned long nr_clks); extern void __init samsung_clk_of_register_fixed_ext( - struct samsung_fixed_rate_clock *fixed_rate_clk, - unsigned int nr_fixed_rate_clk, - struct of_device_id *clk_matches); + struct samsung_clk_provider *ctx, + struct samsung_fixed_rate_clock *fixed_rate_clk, + unsigned int nr_fixed_rate_clk, + struct of_device_id *clk_matches); -extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id); +extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, + struct clk *clk, unsigned int id); -extern void samsung_clk_register_alias(struct samsung_clock_alias *list, - unsigned int nr_clk); +extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx, + struct samsung_clock_alias *list, + unsigned int nr_clk); extern void __init samsung_clk_register_fixed_rate( - struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); + struct samsung_clk_provider *ctx, + struct samsung_fixed_rate_clock *clk_list, + unsigned int nr_clk); extern void __init samsung_clk_register_fixed_factor( - struct samsung_fixed_factor_clock *list, unsigned int nr_clk); -extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list, - unsigned int nr_clk); -extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list, - unsigned int nr_clk); -extern void __init samsung_clk_register_gate( - struct samsung_gate_clock *clk_list, unsigned int nr_clk); -extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, - unsigned int nr_clk, void __iomem *base); + struct samsung_clk_provider *ctx, + struct samsung_fixed_factor_clock *list, + unsigned int nr_clk); +extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, + struct samsung_mux_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, + struct samsung_div_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, + struct samsung_gate_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_list, + unsigned int nr_clk, void __iomem *base); extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base, - struct samsung_clk_reg_dump *rd, - unsigned int num_regs); + struct samsung_clk_reg_dump *rd, + unsigned int num_regs); extern void samsung_clk_restore(void __iomem *base, - const struct samsung_clk_reg_dump *rd, - unsigned int num_regs); + const struct samsung_clk_reg_dump *rd, + unsigned int num_regs); extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( - const unsigned long *rdump, - unsigned long nr_rdump); + const unsigned long *rdump, + unsigned long nr_rdump); #endif /* __SAMSUNG_CLK_H */