From patchwork Tue Sep 24 18:06:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Bresticker X-Patchwork-Id: 2934971 Return-Path: X-Original-To: patchwork-linux-samsung-soc@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 5C7049F524 for ; Tue, 24 Sep 2013 18:08:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9E375202F8 for ; Tue, 24 Sep 2013 18:08:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 50F84203E5 for ; Tue, 24 Sep 2013 18:08:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754493Ab3IXSHF (ORCPT ); Tue, 24 Sep 2013 14:07:05 -0400 Received: from mail-vc0-f201.google.com ([209.85.220.201]:44732 "EHLO mail-vc0-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754264Ab3IXSHA (ORCPT ); Tue, 24 Sep 2013 14:07:00 -0400 Received: by mail-vc0-f201.google.com with SMTP id lf11so558835vcb.2 for ; Tue, 24 Sep 2013 11:06:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/BtaFCjig0dpGY2lsvzgsB9fUihqIwGk6bVegxy/mIs=; b=fPIj+B8WIuhktFsz6kn/N1I4vbeMPHO9ZPcR37zZYo6mj60vdU8zlY4sorAtKNCtPw RPR8jvVlVKFEnS7r2mSeaoPHg00Vioz7Bk0b+ic1EVGXg5pYeptE/YfzSjby0COKDAWi Jb7paYgu4XUJ0gIUsOj49A/6LC1gN85W5jy5AI84UUVHuBHlZ4RDatMLnNXCbz7kgzPN 6BMY80V/5vTzUZXoh7u//P6E+xk5faueVdd0tzGDLp6/fiWbjobALVBpm5ZIibzf2I+u vQDsGb2ThEIMnAf5NItlD4rNI6s2D6TxSdMgiIUQ6xyXdcCj/4ua12tesXAyaL6qf4Bn 3M6Q== X-Gm-Message-State: ALoCoQn2vzDZj2AQzs2OgPQO3/3dNl385rthbwGLX9tER5fACeus4e/NN6EvdK/M4LNjSwbJTjD4s59u+VILrFQ0/j2toumbdifWiWeMfQF3DVn2JixosKWzvZ3/LP1qwJXgWUHfM7pB4gJ96mMm1h/MoofFrdxi4rdWKY84Dh8KYFybdVVWsiGLVhdxApf9N6e7rnuPtMCRP5xc4PbpiqYHwDi0d9y8Cw== X-Received: by 10.236.186.101 with SMTP id v65mr9129692yhm.12.1380046019763; Tue, 24 Sep 2013 11:06:59 -0700 (PDT) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id s21si4564328yhc.1.1969.12.31.16.00.00 (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Tue, 24 Sep 2013 11:06:59 -0700 (PDT) Received: from abrestic.mtv.corp.google.com (abrestic.mtv.corp.google.com [172.22.72.111]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 7A86B5A4214; Tue, 24 Sep 2013 11:06:59 -0700 (PDT) Received: by abrestic.mtv.corp.google.com (Postfix, from userid 137652) id 22E11220A39; Tue, 24 Sep 2013 11:06:58 -0700 (PDT) From: Andrew Bresticker To: linux-samsung-soc@vger.kernel.org, Tomasz Figa , Sylwester Nawrocki Cc: Rob Herring , Pawel Moll , Mark Rutland , Stephen Warren , Ian Campbell , Rob Landley , Kukjin Kim , Russell King , Mike Turquette , Grant Likely , Sachin Kamat , Jiri Kosina , Rahul Sharma , Leela Krishna Amudala , Stephen Boyd , Tushar Behera , Doug Anderson , Padmavathi Venna , devicetree@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Andrew Bresticker Subject: [PATCH V3 1/6] clk: exynos-audss: convert to platform device Date: Tue, 24 Sep 2013 11:06:51 -0700 Message-Id: <1380046016-5811-1-git-send-email-abrestic@chromium.org> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379982078-23381-1-git-send-email-abrestic@chromium.org> References: <1379982078-23381-1-git-send-email-abrestic@chromium.org> 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=-5.8 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, 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 The Exynos AudioSS clock controller will later be modified to allow input clocks to be specified via device-tree in order to support multiple Exynos SoCs. This will introduce a dependency on the core SoC clock controller being initialized first so that the AudioSS driver can look up its input clocks, but the order in which clock providers are probed in of_clk_init() is not guaranteed. Since deferred probing is not supported in of_clk_init() and the AudioSS block is not the core controller, we can initialize it later as a platform device. Signed-off-by: Andrew Bresticker Acked-by: Tomasz Figa Reviewed-by: Sylwester Nawrocki --- Changes since v2: - add error handling to probe callback - fixed ordering of of_clk_{add,del}_provider - fixed nits from Tomasz and Sylwester Changes since v1: - add clk_unregister() calls to remove callback - fixed minor nits from Tomasz --- drivers/clk/samsung/clk-exynos-audss.c | 109 +++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 19 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 39b40aa..319c6e4 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include @@ -62,24 +64,23 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = { #endif /* CONFIG_PM_SLEEP */ /* register exynos_audss clocks */ -static void __init exynos_audss_clk_init(struct device_node *np) +static int exynos_audss_clk_probe(struct platform_device *pdev) { - reg_base = of_iomap(np, 0); - if (!reg_base) { - pr_err("%s: failed to map audss registers\n", __func__); - return; + int i, ret = 0; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reg_base)) { + dev_err(&pdev->dev, "failed to map audss registers\n"); + return PTR_ERR(reg_base); } - clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, + clk_table = devm_kzalloc(&pdev->dev, + sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, GFP_KERNEL); - if (!clk_table) { - pr_err("%s: could not allocate clk lookup table\n", __func__); - return; - } - - clk_data.clks = clk_table; - clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + if (!clk_table) + return -ENOMEM; clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), @@ -123,13 +124,83 @@ static void __init exynos_audss_clk_init(struct device_node *np) "div_pcm0", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 5, 0, &lock); + for (i = 0; i < EXYNOS_AUDSS_MAX_CLKS; i++) { + if (IS_ERR(clk_table[i])) { + dev_err(&pdev->dev, "failed to regsiter clock %d\n", i); + ret = PTR_ERR(clk_table[i]); + goto unregister; + } + } + + clk_data.clks = clk_table; + clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS; + ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, + &clk_data); + if (ret) { + dev_err(&pdev->dev, "failed to add clock provider\n"); + goto unregister; + } + #ifdef CONFIG_PM_SLEEP register_syscore_ops(&exynos_audss_clk_syscore_ops); #endif - pr_info("Exynos: Audss: clock setup completed\n"); + dev_info(&pdev->dev, "setup completed\n"); + + return 0; + +unregister: + for (i = 0; i < EXYNOS_AUDSS_MAX_CLKS; i++) { + if (!IS_ERR_OR_NULL(clk_table[i])) + clk_unregister(clk_table[i]); + } + + return ret; } -CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock", - exynos_audss_clk_init); -CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock", - exynos_audss_clk_init); + +static int exynos_audss_clk_remove(struct platform_device *pdev) +{ + int i; + + of_clk_del_provider(pdev->dev.of_node); + + for (i = 0; i < EXYNOS_AUDSS_MAX_CLKS; i++) { + if (!IS_ERR_OR_NULL(clk_table[i])) + clk_unregister(clk_table[i]); + } + + return 0; +} + +static const struct of_device_id exynos_audss_clk_of_match[] = { + { .compatible = "samsung,exynos4210-audss-clock", }, + { .compatible = "samsung,exynos5250-audss-clock", }, + {}, +}; + +static struct platform_driver exynos_audss_clk_driver = { + .driver = { + .name = "exynos-audss-clk", + .owner = THIS_MODULE, + .of_match_table = exynos_audss_clk_of_match, + }, + .probe = exynos_audss_clk_probe, + .remove = exynos_audss_clk_remove, +}; + +static int __init exynos_audss_clk_init(void) +{ + return platform_driver_register(&exynos_audss_clk_driver); +} +core_initcall(exynos_audss_clk_init); + +static void __init exynos_audss_clk_exit(void) +{ + platform_driver_unregister(&exynos_audss_clk_driver); +} +module_exit(exynos_audss_clk_exit); + +MODULE_AUTHOR("Padmavathi Venna "); +MODULE_DESCRIPTION("Exynos Audio Subsystem Clock Controller"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:exynos-audss-clk");