From patchwork Mon Apr 10 11:07:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangfl X-Patchwork-Id: 81475 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1830592vqo; Mon, 10 Apr 2023 04:34:37 -0700 (PDT) X-Google-Smtp-Source: AKy350aBBwyvtLsKYviikkud3cAdgxFNKYIB+78su/NTRI/BWlmGL0kG99wFKukbE30VCAh842pY X-Received: by 2002:a05:6a20:4c97:b0:d8:997f:b21c with SMTP id fq23-20020a056a204c9700b000d8997fb21cmr6847417pzb.27.1681126477460; Mon, 10 Apr 2023 04:34:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681126477; cv=none; d=google.com; s=arc-20160816; b=E6YWKVWdpMHWA/EMK5wTCizZLIXhOyXcDfBXk2+KbmNkePfm7L4eZc0d/AbK8Canfv 4UlIta8FBdzzaUlaV1jGAJmTZoFxEyRYJ9HZe2Q4AaEd75NEqLy5Hk6Zwsh4cfjvS3/o mquM3tmFVroRPG2uyHNNNvBYCP1a8dWSmNvL3K+lrfEwGxypslXh81Vh0zHsmKez2LWx a3OC1ruKA0N0MwBhlX70MNT4z3qhNnwC8O/HqyI/bCIi3qrrnPxcl6Zn3d1xMiDInH52 UFcwGqpQ8yiT7RqpC6+ob0FoGTNswxE61nNc+pzAHvMgbB76eO0w7UBBaKVmPOywDaZB WLoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=zGYltMygM2Avg7sOhC73hhQt4KoPWEHqx0AmFedwBwI=; b=gZn3EhxloW6QuwkkV40rHkJn1AUD7Nt/a23Pxdx4WXm6CLJiUnnYwO5K/j/9ocERpe uSi/qeAPF9MvZUU4/hWDUv9oF65pRYlax+x9lwo6dphgVaQThZDIHuVa3iAPgOvyndZj ZFNny0vw/rlaFynWHDNE4mq95dw1LGUPzYo3hTZhF8W4sEvrL8CQcYes+RJdbxl2QMZg YMin97tfP2t6AA32rGow3JsTtjY11bsfHp8KJZMbu2K/5M/CIJJ9O5J5gTVDlGyEBUoe LO1G2qJxGeNCwG5myy4BJdijuhLWsaOSfJff9KRgb5OPp6f3Vi1Cdn0O3shl6oQ7wyZj uSRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="kjqgIfK/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t18-20020a635352000000b004a4eae7c943si7857079pgl.535.2023.04.10.04.34.24; Mon, 10 Apr 2023 04:34:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="kjqgIfK/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229557AbjDJLIF (ORCPT + 99 others); Mon, 10 Apr 2023 07:08:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229739AbjDJLID (ORCPT ); Mon, 10 Apr 2023 07:08:03 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67B6E30F0; Mon, 10 Apr 2023 04:08:01 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id ik20so4260981plb.3; Mon, 10 Apr 2023 04:08:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1681124880; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zGYltMygM2Avg7sOhC73hhQt4KoPWEHqx0AmFedwBwI=; b=kjqgIfK/yuNK3wgV3HdeL9NBcPafQXEb61GuA3Lf8BVJ0yHSaiaVZ72WEkAlJnk/L3 SbzxLNt/RCR7F20iBsCwgtsuPT4Muy1wP5aK5C3/lqx8YpANOj4ekTIzaXFCDM5rZ7wA ZmcvFk2m2QdHRfTQJHp8AXbCQQzDxfCPQBaZhyjFZAmN9spoa1hepHvtTUBdY3Efuctk n6zXBd/9dbCymrYL4ReDCAvfdSrB3DzMehPQZHsI8W6+uw1M6wx9/GGM1X8phE95YD2v j1af2GhvtTNdnJ3x5nc2Z7e9Wt8e/SNvJJpzb/0swNfK27Pd3nAKUZZ4LKq1sWdETRt7 NyQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681124880; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zGYltMygM2Avg7sOhC73hhQt4KoPWEHqx0AmFedwBwI=; b=YC/0dXOTKHId7lkk43iS+jktmUtv6B31GVHps1k29k6vtwI3CzsrgDs8kRxzdiCCJh V/tLhrvdf+mC0uddwZkbAQnKT9BcZg8Slv5A5ycvqhc3+Rh+NnmBwxhGFw++3dru/+Y6 AxQKXVOyZth0K/ZRqfuesPRHJc9kx2kuQKLwdClI4tNHHFXe10yy3B9WK4JFO2tCspCC 8v+vITz6m94EHjAoFCgX81vW3PH1sMbvr9rogXEwfhrqIlHChhXS7tTAO9etYmyg8V/9 0LklD8Dq+iXkEhwWaTnAVRsFeZln6yHFN5wVuE/9bceY50vCA5lu9vW9THeS+qU61+xA 1GEg== X-Gm-Message-State: AAQBX9cHkydulAR4K2Yz6qD5PUs/QJlwq0KIO4UDcEFxmjqExZQN/I1s d6ppb+YewhQqdSURCm1vy9wp187eWRsoxxwT91A= X-Received: by 2002:a17:902:f947:b0:1a1:ca37:5257 with SMTP id kx7-20020a170902f94700b001a1ca375257mr8343304plb.7.1681124880512; Mon, 10 Apr 2023 04:08:00 -0700 (PDT) Received: from d.home.yangfl.dn42 ([104.28.213.201]) by smtp.gmail.com with ESMTPSA id r5-20020a170902be0500b001a076568da9sm7464728pls.216.2023.04.10.04.07.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 04:08:00 -0700 (PDT) From: David Yang To: linux-clk@vger.kernel.org Cc: David Yang , Michael Turquette , Stephen Boyd , linux-kernel@vger.kernel.org Subject: [PATCH v3 01/14] clk: hisilicon: Add helper functions for platform driver Date: Mon, 10 Apr 2023 19:07:13 +0800 Message-Id: <20230410110733.192151-2-mmyangfl@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230410110733.192151-1-mmyangfl@gmail.com> References: <20230410110733.192151-1-mmyangfl@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762788877557614933?= X-GMAIL-MSGID: =?utf-8?q?1762788877557614933?= Helper functions extract common operations on platform drivers. During migration to devm APIs, (virtual) fixed clocks were found hard on devm APIs, since they often depended by crucial peripherals, thus require early initialization before device probing, and cannot use devm APIs. One solution to this problem is to add a "fixed-clock" node to device tree, independent to clock device, and make those peripherals depend on that. However, there is also some devices that do use fixed clocks provided by drivers, for example clk-hi3660.c . To simplify codes, we migrate clocks of other types to devm APIs, while keep fixed clocks self-managed, alongside with struct hisi_clock_data, and remove devm-managed hisi_clock_data. `hisi_clk_alloc` will be removed in the following patch. Signed-off-by: David Yang --- drivers/clk/hisilicon/clk.c | 156 ++++++++++++++++++++++++++++++++++ drivers/clk/hisilicon/clk.h | 45 ++++++++++ drivers/clk/hisilicon/crg.h | 5 ++ drivers/clk/hisilicon/reset.c | 43 ++++++++++ 4 files changed, 249 insertions(+) diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 54d9fdc93599..cb4444bba2c0 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -88,6 +88,25 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np, } EXPORT_SYMBOL_GPL(hisi_clk_init); +void hisi_clk_free(struct device_node *np, struct hisi_clock_data *data) +{ + if (data->clks) { + if (data->clks->fixed_rate_clks_num) + hisi_clk_unregister_fixed_rate(data->clks->fixed_rate_clks, + data->clks->fixed_rate_clks_num, + data); + if (data->clks->fixed_factor_clks_num) + hisi_clk_unregister_fixed_factor(data->clks->fixed_factor_clks, + data->clks->fixed_factor_clks_num, + data); + } + + of_clk_del_provider(np); + kfree(data->clk_data.clks); + kfree(data); +} +EXPORT_SYMBOL_GPL(hisi_clk_free); + int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks, int nums, struct hisi_clock_data *data) { @@ -341,3 +360,140 @@ void __init hi6220_clk_register_divider(const struct hi6220_divider_clock *clks, data->clk_data.clks[clks[i].id] = clk; } } + +int hisi_clk_register(struct device *dev, const struct hisi_clocks *clks, + struct hisi_clock_data *data) +{ + int ret; + + if (clks->mux_clks_num) { + ret = hisi_clk_register_mux(clks->mux_clks, + clks->mux_clks_num, data); + if (ret) + return ret; + } + + if (clks->phase_clks_num) { + ret = hisi_clk_register_phase(dev, clks->phase_clks, + clks->phase_clks_num, data); + if (ret) + return ret; + } + + if (clks->divider_clks_num) { + ret = hisi_clk_register_divider(clks->divider_clks, + clks->divider_clks_num, data); + if (ret) + return ret; + } + + if (clks->gate_clks_num) { + ret = hisi_clk_register_gate(clks->gate_clks, + clks->gate_clks_num, data); + if (ret) + return ret; + } + + if (clks->gate_sep_clks_num) { + hisi_clk_register_gate_sep(clks->gate_sep_clks, + clks->gate_sep_clks_num, data); + } + + if (clks->clk_register_customized && clks->customized_clks_num) { + ret = clks->clk_register_customized(dev, clks->customized_clks, + clks->customized_clks_num, data); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(hisi_clk_register); + +static size_t hisi_clocks_get_nr(const struct hisi_clocks *clks) +{ + return clks->fixed_rate_clks_num + clks->fixed_factor_clks_num + + clks->mux_clks_num + clks->phase_clks_num + + clks->divider_clks_num + clks->gate_clks_num + + clks->gate_sep_clks_num + clks->customized_clks_num; +} + +int hisi_clk_early_init(struct device_node *np, const struct hisi_clocks *clks) +{ + struct hisi_clock_data *data; + int ret; + + data = hisi_clk_init(np, hisi_clocks_get_nr(clks)); + if (!data) + return -ENOMEM; + data->clks = clks; + + ret = hisi_clk_register_fixed_rate(clks->fixed_rate_clks, + clks->fixed_rate_clks_num, data); + if (ret) + goto err; + + ret = hisi_clk_register_fixed_factor(clks->fixed_factor_clks, + clks->fixed_factor_clks_num, data); + if (ret) + goto err; + + np->data = data; + return 0; + +err: + hisi_clk_free(np, data); + return ret; +} +EXPORT_SYMBOL_GPL(hisi_clk_early_init); + +int hisi_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct hisi_clocks *clks; + struct hisi_clock_data *data; + int ret; + + clks = of_device_get_match_data(dev); + if (!clks) + return -ENOENT; + + if (!np->data) { + ret = hisi_clk_early_init(np, clks); + if (ret) + return ret; + } + + data = np->data; + np->data = NULL; + + if (clks->prologue) { + ret = clks->prologue(dev, data); + if (ret) + goto err; + } + + ret = hisi_clk_register(dev, clks, data); + if (ret) + goto err; + + platform_set_drvdata(pdev, data); + return 0; + +err: + hisi_clk_free(np, data); + return ret; +} +EXPORT_SYMBOL_GPL(hisi_clk_probe); + +int hisi_clk_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct hisi_clock_data *data = platform_get_drvdata(pdev); + + hisi_clk_free(np, data); + return 0; +} +EXPORT_SYMBOL_GPL(hisi_clk_remove); diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h index 7a9b42e1b027..c373d7c14ed5 100644 --- a/drivers/clk/hisilicon/clk.h +++ b/drivers/clk/hisilicon/clk.h @@ -17,10 +17,12 @@ #include struct platform_device; +struct hisi_clocks; struct hisi_clock_data { struct clk_onecell_data clk_data; void __iomem *base; + const struct hisi_clocks *clks; }; struct hisi_fixed_rate_clock { @@ -103,6 +105,39 @@ struct hisi_gate_clock { const char *alias; }; +struct hisi_clocks { + /* if 0, sum all *_num */ + size_t nr; + + int (*prologue)(struct device *dev, struct hisi_clock_data *data); + + const struct hisi_fixed_rate_clock *fixed_rate_clks; + size_t fixed_rate_clks_num; + + const struct hisi_fixed_factor_clock *fixed_factor_clks; + size_t fixed_factor_clks_num; + + const struct hisi_mux_clock *mux_clks; + size_t mux_clks_num; + + const struct hisi_phase_clock *phase_clks; + size_t phase_clks_num; + + const struct hisi_divider_clock *divider_clks; + size_t divider_clks_num; + + const struct hisi_gate_clock *gate_clks; + size_t gate_clks_num; + + const struct hisi_gate_clock *gate_sep_clks; + size_t gate_sep_clks_num; + + const void *customized_clks; + size_t customized_clks_num; + int (*clk_register_customized)(struct device *dev, const void *clks, + size_t num, struct hisi_clock_data *data); +}; + struct clk *hisi_register_clkgate_sep(struct device *, const char *, const char *, unsigned long, void __iomem *, u8, @@ -113,6 +148,7 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int); struct hisi_clock_data *hisi_clk_init(struct device_node *, int); +void hisi_clk_free(struct device_node *np, struct hisi_clock_data *data); int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *, int, struct hisi_clock_data *); int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, @@ -134,6 +170,15 @@ void hisi_clk_register_gate_sep(const struct hisi_gate_clock *, void hi6220_clk_register_divider(const struct hi6220_divider_clock *, int, struct hisi_clock_data *); +int hisi_clk_register(struct device *dev, const struct hisi_clocks *clks, + struct hisi_clock_data *data); + +/* helper functions for platform driver */ + +int hisi_clk_early_init(struct device_node *np, const struct hisi_clocks *clks); +int hisi_clk_probe(struct platform_device *pdev); +int hisi_clk_remove(struct platform_device *pdev); + #define hisi_clk_unregister(type) \ static inline \ void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \ diff --git a/drivers/clk/hisilicon/crg.h b/drivers/clk/hisilicon/crg.h index 803f6ba6d7a2..d9544f1f2625 100644 --- a/drivers/clk/hisilicon/crg.h +++ b/drivers/clk/hisilicon/crg.h @@ -22,4 +22,9 @@ struct hisi_crg_dev { const struct hisi_crg_funcs *funcs; }; +/* helper functions for platform driver */ + +int hisi_crg_probe(struct platform_device *pdev); +int hisi_crg_remove(struct platform_device *pdev); + #endif /* __HISI_CRG_H */ diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c index 93cee17db8b1..19918cd717fd 100644 --- a/drivers/clk/hisilicon/reset.c +++ b/drivers/clk/hisilicon/reset.c @@ -6,11 +6,15 @@ */ #include +#include #include #include #include #include #include + +#include "clk.h" +#include "crg.h" #include "reset.h" #define HISI_RESET_BIT_MASK 0x1f @@ -116,3 +120,42 @@ void hisi_reset_exit(struct hisi_reset_controller *rstc) reset_controller_unregister(&rstc->rcdev); } EXPORT_SYMBOL_GPL(hisi_reset_exit); + +int hisi_crg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hisi_crg_dev *crg; + int ret; + + crg = devm_kmalloc(dev, sizeof(*crg), GFP_KERNEL); + if (!crg) + return -ENOMEM; + + ret = hisi_clk_probe(pdev); + if (ret) + return ret; + + crg->rstc = hisi_reset_init(pdev); + if (!crg->rstc) { + ret = -ENOMEM; + goto err; + } + + platform_set_drvdata(pdev, crg); + return 0; + +err: + hisi_clk_remove(pdev); + return ret; +} +EXPORT_SYMBOL_GPL(hisi_crg_probe); + +int hisi_crg_remove(struct platform_device *pdev) +{ + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); + + hisi_reset_exit(crg->rstc); + hisi_clk_remove(pdev); + return 0; +} +EXPORT_SYMBOL_GPL(hisi_crg_remove);