From patchwork Tue Sep 2 15:35:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naveen Krishna Chatradhi X-Patchwork-Id: 4826711 Return-Path: X-Original-To: patchwork-linux-samsung-soc@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 B74D8C0338 for ; Tue, 2 Sep 2014 15:42:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2DB55201C0 for ; Tue, 2 Sep 2014 15:42:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1D66A2017E for ; Tue, 2 Sep 2014 15:42:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751764AbaIBPmE (ORCPT ); Tue, 2 Sep 2014 11:42:04 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:15459 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751735AbaIBPmB (ORCPT ); Tue, 2 Sep 2014 11:42:01 -0400 Received: from epcpsbgr3.samsung.com (u143.gpu120.samsung.co.kr [203.254.230.143]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NBA00E9T69ZAVC0@mailout3.samsung.com>; Wed, 03 Sep 2014 00:41:59 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.126]) by epcpsbgr3.samsung.com (EPCPMTA) with SMTP id 8C.3B.04467.745E5045; Wed, 03 Sep 2014 00:41:59 +0900 (KST) X-AuditID: cbfee68f-f797f6d000001173-37-5405e547d899 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 51.EA.04943.745E5045; Wed, 03 Sep 2014 00:41:59 +0900 (KST) Received: from chnaveen-ubuntu.sisodomain.com ([107.108.83.161]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NBA002I96728OC0@mmp1.samsung.com>; Wed, 03 Sep 2014 00:41:59 +0900 (KST) From: Naveen Krishna Chatradhi To: linux-arm-kernel@lists.infradead.org Cc: naveenkrishna.ch@gmail.com, linux-samsung-soc@vger.kernel.org, catalin.marinas@arm.com, robh@kernel.org, devicetree@vger.kernel.org, t.figa@samsung.com, kgene.kim@samsung.com, Mike Turquette Subject: [PATCH v2 2/7] clk: samsung: Factor out the common code to clk.c Date: Tue, 02 Sep 2014 21:05:38 +0530 Message-id: <1409672143-8574-3-git-send-email-ch.naveen@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1409672143-8574-1-git-send-email-ch.naveen@samsung.com> References: <1409672143-8574-1-git-send-email-ch.naveen@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJLMWRmVeSWpSXmKPExsWyRsSkTtf9KWuIQctHfYv3y3oYLeYfOcdq 0bvgKpvFpsfXWC1mnN/HZPF0wkU2i0Xb/jNb/N+zg91i/YzXLA6cHmvmrWH02DnrLrvHplWd bB53ru1h89i8pN6jb8sqRo/Pm+QC2KO4bFJSczLLUov07RK4Mvb82cBc0DWZseLK6poGxifV XYycHBICJhLnjk5hhLDFJC7cW8/WxcjFISSwlFHi6bc7rF2MHGBFT+8bQ8QXMUrs6vzEDtIg JNDPJNFzxAnEZhMwkzi4aDVYXERAQ2JK12N2kAZmgQeMEo3HrrCADBIW8JR4dLAKxGQRUJXY 2JgFYvIKuEg8uhkEsUlBYs4kG5AhnAKuEksebGMDCQsBVZw4ZQ4yT0JgG7vEjt6ZLCA1LAIC Et8mH2KBaJWV2HSAGeIRSYmDK26wTGAUXsDIsIpRNLUguaA4Kb3IWK84Mbe4NC9dLzk/dxMj MAZO/3vWv4Px7gHrQ4wCHIxKPLwSP1hChFgTy4orcw8xmgJtmMgsJZqcD4y0vJJ4Q2MzIwtT E1NjI3NLMyVx3oVSP4OFBNITS1KzU1MLUovii0pzUosPMTJxcEo1MAqz9+Z0rvhlFSfE+V9G Vj8lpsT9yHYr4cPPdzbxKF1eUxoz9fz1Dc81pBQf+ATVFuWvcJ2VJmfXIl09v+aHWr3805QF /K3V871lJ1+dlfthcxT7Qf9VM85KyeqtXS66pbsqemOGIfOPux7Hebbqte2Q1Lu/rVlwGsfW Dyn77fcnTt/yrnXWMSWW4oxEQy3mouJEAPqr4jR8AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrMIsWRmVeSWpSXmKPExsVy+t9jAV33p6whBse3aFi8X9bDaDH/yDlW i94FV9ksNj2+xmox4/w+JounEy6yWSza9p/Z4v+eHewW62e8ZnHg9Fgzbw2jx85Zd9k9Nq3q ZPO4c20Pm8fmJfUefVtWMXp83iQXwB7VwGiTkZqYklqkkJqXnJ+SmZduq+QdHO8cb2pmYKhr aGlhrqSQl5ibaqvk4hOg65aZA3SakkJZYk4pUCggsbhYSd8O04TQEDddC5jGCF3fkCC4HiMD NJCwhjFjz58NzAVdkxkrrqyuaWB8Ut3FyMEhIWAi8fS+cRcjJ5ApJnHh3nq2LkYuDiGBRYwS uzo/sYMkhAT6mSR6jjiB2GwCZhIHF60Gi4sIaEhM6XrMDtLALPCAUaLx2BUWkKHCAp4Sjw5W gZgsAqoSGxuzQExeAReJRzeDILYqSMyZZAMyhFPAVWLJg21sIGEhoIoTp8wnMPIuYGRYxSia WpBcUJyUnmuoV5yYW1yal66XnJ+7iREcYc+kdjCubLA4xCjAwajEwyv5gyVEiDWxrLgy9xCj BAezkghvwSPWECHelMTKqtSi/Pii0pzU4kOMpkAXTWSWEk3OB0Z/Xkm8obGJuamxqaWJhYmZ pZI474FW60AhgfTEktTs1NSC1CKYPiYOTqkGxvlfBHeIP+wQ7pr44nyVauOPBobtN2UKM2fs q1vU8WWTkdhJTT9m/lDd1YGrbt1WPfikoTz0jNMKk/0PLux+eeK92orUt6m8lzI2GFav+ThL oN/3ikhpQVbOTeOAgi7PbY8X7pdMWFH33etuU56q3a46s69Tovinm37sMauva2Kx7N4ttIgr T4mlOCPRUIu5qDgRAOZQpcHGAgAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 While adding clock support for Exynos5260, the infrastructure to register multiple clock controllers was introduced. Factor out the support for registering multiple clock controller from Exynos5260 clock code to common samsung clock code so that it can be used by other Exynos SoC which have multiple clock controllers. Signed-off-by: Naveen Krishna Chatradhi Cc: Tomasz Figa Cc: Mike Turquette --- drivers/clk/samsung/clk-exynos5260.c | 183 +++++----------------------------- drivers/clk/samsung/clk.c | 95 ++++++++++++++++++ drivers/clk/samsung/clk.h | 34 +++++++ 3 files changed, 155 insertions(+), 157 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index ce3de97..d72c982 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -11,10 +11,8 @@ #include #include -#include #include #include -#include #include "clk-exynos5260.h" #include "clk.h" @@ -22,39 +20,6 @@ #include -static LIST_HEAD(clock_reg_cache_list); - -struct exynos5260_clock_reg_cache { - struct list_head node; - void __iomem *reg_base; - struct samsung_clk_reg_dump *rdump; - unsigned int rd_num; -}; - -struct exynos5260_cmu_info { - /* list of pll clocks and respective count */ - struct samsung_pll_clock *pll_clks; - unsigned int nr_pll_clks; - /* list of mux clocks and respective count */ - struct samsung_mux_clock *mux_clks; - unsigned int nr_mux_clks; - /* list of div clocks and respective count */ - struct samsung_div_clock *div_clks; - unsigned int nr_div_clks; - /* list of gate clocks and respective count */ - struct samsung_gate_clock *gate_clks; - unsigned int nr_gate_clks; - /* list of fixed clocks and respective count */ - struct samsung_fixed_rate_clock *fixed_clks; - unsigned int nr_fixed_clks; - /* total number of clocks with IDs assigned*/ - unsigned int nr_clk_ids; - - /* list and number of clocks registers */ - unsigned long *clk_regs; - unsigned int nr_clk_regs; -}; - /* * Applicable for all 2550 Type PLLS for Exynos5260, listed below * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. @@ -115,102 +80,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { #ifdef CONFIG_PM_SLEEP -static int exynos5260_clk_suspend(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_save(cache->reg_base, cache->rdump, - cache->rd_num); - - return 0; -} - -static void exynos5260_clk_resume(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_restore(cache->reg_base, cache->rdump, - cache->rd_num); -} - -static struct syscore_ops exynos5260_clk_syscore_ops = { - .suspend = exynos5260_clk_suspend, - .resume = exynos5260_clk_resume, -}; - -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump) -{ - struct exynos5260_clock_reg_cache *reg_cache; - - reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), - GFP_KERNEL); - if (!reg_cache) - panic("could not allocate register cache.\n"); - - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); - - if (!reg_cache->rdump) - panic("could not allocate register dump storage.\n"); - - if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&exynos5260_clk_syscore_ops); - - reg_cache->rd_num = nr_rdump; - reg_cache->reg_base = reg_base; - list_add_tail(®_cache->node, &clock_reg_cache_list); -} - -#else -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump){} -#endif - -/* - * Common function which registers plls, muxes, dividers and gates - * for each CMU. It also add CMU register list to register cache. - */ - -void __init exynos5260_cmu_register_one(struct device_node *np, - struct exynos5260_cmu_info *cmu) -{ - void __iomem *reg_base; - struct samsung_clk_provider *ctx; - - reg_base = of_iomap(np, 0); - if (!reg_base) - panic("%s: failed to map registers\n", __func__); - - ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) - panic("%s: unable to alllocate ctx\n", __func__); - - if (cmu->pll_clks) - samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, - reg_base); - if (cmu->mux_clks) - samsung_clk_register_mux(ctx, cmu->mux_clks, - cmu->nr_mux_clks); - if (cmu->div_clks) - samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); - if (cmu->gate_clks) - samsung_clk_register_gate(ctx, cmu->gate_clks, - cmu->nr_gate_clks); - if (cmu->fixed_clks) - samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, - cmu->nr_fixed_clks); - if (cmu->clk_regs) - exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, - cmu->nr_clk_regs); - - samsung_clk_of_add_provider(np, ctx); -} - - /* CMU_AUD */ static unsigned long aud_clk_regs[] __initdata = { @@ -268,7 +137,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = { static void __init exynos5260_clk_aud_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = aud_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); @@ -280,7 +149,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np) cmu.clk_regs = aud_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", @@ -458,7 +327,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = { static void __init exynos5260_clk_disp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = disp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); @@ -470,7 +339,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np) cmu.clk_regs = disp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", @@ -522,7 +391,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = { static void __init exynos5260_clk_egl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = egl_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); @@ -534,7 +403,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np) cmu.clk_regs = egl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", @@ -624,7 +493,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = { static void __init exynos5260_clk_fsys_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = fsys_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); @@ -634,7 +503,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np) cmu.clk_regs = fsys_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", @@ -713,7 +582,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = { static void __init exynos5260_clk_g2d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = g2d_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); @@ -725,7 +594,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np) cmu.clk_regs = g2d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", @@ -774,7 +643,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = { static void __init exynos5260_clk_g3d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = g3d_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); @@ -788,7 +657,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np) cmu.clk_regs = g3d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", @@ -909,7 +778,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = { static void __init exynos5260_clk_gscl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = gscl_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); @@ -921,7 +790,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np) cmu.clk_regs = gscl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", @@ -1028,7 +897,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = { static void __init exynos5260_clk_isp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = isp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); @@ -1040,7 +909,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np) cmu.clk_regs = isp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", @@ -1092,7 +961,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = { static void __init exynos5260_clk_kfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = kfc_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); @@ -1104,7 +973,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np) cmu.clk_regs = kfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", @@ -1148,7 +1017,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = { static void __init exynos5260_clk_mfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = mfc_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); @@ -1160,7 +1029,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np) cmu.clk_regs = mfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", @@ -1295,7 +1164,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { static void __init exynos5260_clk_mif_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = mif_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); @@ -1309,7 +1178,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np) cmu.clk_regs = mif_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", @@ -1503,7 +1372,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = { static void __init exynos5260_clk_peri_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.mux_clks = peri_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); @@ -1515,7 +1384,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np) cmu.clk_regs = peri_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", @@ -1959,7 +1828,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = { static void __init exynos5260_clk_top_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct exynos_cmu_info cmu = {0}; cmu.pll_clks = top_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); @@ -1975,7 +1844,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np) cmu.clk_regs = top_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + exynos_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index deab84d..a043654 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -14,6 +14,8 @@ #include #include "clk.h" +static LIST_HEAD(clock_reg_cache_list); + void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -313,3 +315,96 @@ unsigned long _get_rate(const char *clk_name) return clk_get_rate(clk); } + +#ifdef CONFIG_PM_SLEEP +static int exynos_clk_suspend(void) +{ + struct exynos_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); + return 0; +} + +static void exynos_clk_resume(void) +{ + struct exynos_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); +} + +static struct syscore_ops exynos_clk_syscore_ops = { + .suspend = exynos_clk_suspend, + .resume = exynos_clk_resume, +}; + +static void exynos_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) +{ + struct exynos_clock_reg_cache *reg_cache; + + reg_cache = kzalloc(sizeof(struct exynos_clock_reg_cache), + GFP_KERNEL); + if (!reg_cache) + panic("could not allocate register reg_cache.\n"); + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); + + if (!reg_cache->rdump) + panic("could not allocate register dump storage.\n"); + + if (list_empty(&clock_reg_cache_list)) + register_syscore_ops(&exynos_clk_syscore_ops); + + reg_cache->reg_base = reg_base; + reg_cache->rd_num = nr_rdump; + list_add_tail(®_cache->node, &clock_reg_cache_list); +} + +#else +static void exynos_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) {} +#endif + +/* + * Common function which registers plls, muxes, dividers and gates + * for each CMU. It also add CMU register list to register cache. + */ +void __init exynos_cmu_register_one(struct device_node *np, + struct exynos_cmu_info *cmu) +{ + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); + if (!ctx) + panic("%s: unable to alllocate ctx\n", __func__); + + if (cmu->pll_clks) + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, + reg_base); + if (cmu->mux_clks) + samsung_clk_register_mux(ctx, cmu->mux_clks, + cmu->nr_mux_clks); + if (cmu->div_clks) + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); + if (cmu->gate_clks) + samsung_clk_register_gate(ctx, cmu->gate_clks, + cmu->nr_gate_clks); + if (cmu->fixed_clks) + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, + cmu->nr_fixed_clks); + if (cmu->clk_regs) + exynos_clk_sleep_init(reg_base, cmu->clk_regs, + cmu->nr_clk_regs); + + samsung_clk_of_add_provider(np, ctx); +} diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 66ab36b..552d155 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -324,6 +324,37 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) +struct exynos_clock_reg_cache { + struct list_head node; + void __iomem *reg_base; + struct samsung_clk_reg_dump *rdump; + unsigned int rd_num; +}; + +struct exynos_cmu_info { + /* list of pll clocks and respective count */ + struct samsung_pll_clock *pll_clks; + unsigned int nr_pll_clks; + /* list of mux clocks and respective count */ + struct samsung_mux_clock *mux_clks; + unsigned int nr_mux_clks; + /* list of div clocks and respective count */ + struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + /* list of gate clocks and respective count */ + struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + /* list of fixed clocks and respective count */ + struct samsung_fixed_rate_clock *fixed_clks; + unsigned int nr_fixed_clks; + /* total number of clocks with IDs assigned*/ + unsigned int nr_clk_ids; + + /* list and number of clocks registers */ + unsigned long *clk_regs; + unsigned int nr_clk_regs; +}; + extern struct samsung_clk_provider *__init samsung_clk_init( struct device_node *np, void __iomem *base, unsigned long nr_clks); @@ -362,6 +393,9 @@ 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 void __init exynos_cmu_register_one(struct device_node *, + struct exynos_cmu_info *); + extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base,