From patchwork Sun Jul 23 16:22:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangfl X-Patchwork-Id: 124516 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9010:0:b0:3e4:2afc:c1 with SMTP id l16csp1360085vqg; Sun, 23 Jul 2023 10:30:48 -0700 (PDT) X-Google-Smtp-Source: APBJJlG131pQqRptJ8TfySR3sjkPZEzn2fcuvK8vZqxdlbq0J1gnlCR4WC5ES9lH+6Kftb85GX3u X-Received: by 2002:a17:903:2445:b0:1b8:a7ec:38c5 with SMTP id l5-20020a170903244500b001b8a7ec38c5mr7402287pls.57.1690133448269; Sun, 23 Jul 2023 10:30:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690133448; cv=none; d=google.com; s=arc-20160816; b=DY/EOlb/QIf6KkZBIL1NDRG42MpmS3IZpmBXbHhRWn8qQY4krFM3Y96IRmIlBL83nw 1iw6sbB5w1fIBDxONdP8xpt1P9ZfJ/luU5SN75iMJ571NbDcICJvov1RphEcdAuY6MMW E4MYrxz8uJjbvCWxftVqvMKPbalgFv9bz5n0xChGyTuFSFGuRjAZmgn+XbDA4kDkNpJ4 bUO3eOG6i3FlbSNdaDLI8H1KcWYkY2RTc4tia+zNtrhSICBLKZwAH6p7rSgmCoAirblc wGYq5LVojEarfJXUU6KSy5HWG52nT8/9wIcC7cdVt82IsTiiqSBtuqyGjp64+piMRod0 yuYA== 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=nC80tf2Fqm9NV1HkrgmsaoEnP1GJqadflAYCzRO4B1o=; fh=6op8AbJPoSQyJcsI0L5qUJDM8pym4PtkpWqFZ6dkle0=; b=f9siAOtzHoyZu3wJq+0fq9WuxVl9XEhAp5Yf8lqxnkcIhO2sUnd++ba9j9kuAsjF/J stbpOF2A/pWC5B83kbtmJD77VDR2IDxockIJvFbZDmIA7X1IN9+OgYBwQA38tmaG3RbN o35DkiuZ6kX0gA6G5K5Oacdjdjm8Fwn8IrczLE+sdeIO8qrjN3DtPRhQbs0roqHX2pj4 +stRYm7g795Bhvk4c5Lkbiccjw9v9AG0YV9SFYn8VsiG/qTvph9OgXUsTGOfPja9vbds TGdV4ftqhPJvORwUforbd3c3hj4YQMgCT1JXR76TJlNxkhsv/2sC1DHb8wFjL8r6duSd DXtQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=ocjCaFiK; 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 ij14-20020a170902ab4e00b001bb86cdf12bsi3057469plb.147.2023.07.23.10.30.33; Sun, 23 Jul 2023 10:30:48 -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=20221208 header.b=ocjCaFiK; 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 S229809AbjGWQYR (ORCPT + 99 others); Sun, 23 Jul 2023 12:24:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229537AbjGWQYL (ORCPT ); Sun, 23 Jul 2023 12:24:11 -0400 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FE9CE7F; Sun, 23 Jul 2023 09:23:45 -0700 (PDT) Received: by mail-pg1-x52d.google.com with SMTP id 41be03b00d2f7-53fa455cd94so1848120a12.2; Sun, 23 Jul 2023 09:23:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1690129418; x=1690734218; 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=nC80tf2Fqm9NV1HkrgmsaoEnP1GJqadflAYCzRO4B1o=; b=ocjCaFiKtIzplKvPtoFuX6XwXSSF7vAO3+JLcljBsiqsRF941PjtOQYeAcUw38T3p4 ymth6n3JivTbjphSrZY7Ld/pQLahaiRI0jW2wAlGPW4yAr/AFsnuD+uKSoPCmCrtmYLd HT4kMHJj+TZxvEteuUfdf2rJXJ2VIL+CwdNQYri5KXIHndzS4wwAC/Zvl9xPZwlBD+GW bMqWYYm/yxS7VuB8u2yctHWRizsJM/4QVlhf5DoXngtocWGWNLjVwwgeFO0VAc8RDfku wLkCAmMpvKiHc5eR4KaqJsyDXI/6dgpg8Yl001uOZaUTVhyHwQIOCpt4vXU0LalgyM5j ke9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690129418; x=1690734218; 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=nC80tf2Fqm9NV1HkrgmsaoEnP1GJqadflAYCzRO4B1o=; b=GskJGMh/4se3MBUP0Uwz3BdkNqHM6fbjk0sWS8WolFKnV1LEnFKNntCFryVthi3Uaw NbYiPDp/5OLfhOHX0YWVZf1hs64Z71w6sgJD4VtAzHvg1NuMX71zw2u6vOIq1yKon893 NuEkrKuxfMIaKV/kzuCQjL8+bEt+V8fLDlitjfg01H2L+ZOS+b/Xqcn8KjF4K/PXG4fQ +FcdDspVu0ByN8k9MNGAcgr2W7VIEIIbNvkiW14I0yj72hzFf0wqOv6jE4hGVsqV03Q0 q6LLkViCc9hnzjcXm58pn4vTxHkahNMuMgnsnXcHcDez2J/E3/QHouMGT3UHi0UEnldI fVpQ== X-Gm-Message-State: ABy/qLZ4oeqKwMtDi3/DfZRIfXO0KO6p8iVCIJCJ2tt7siHFr/6RSO6a rnWQYM1c+KdaBQkWFTdNuhPrrhyqQps0eBWg X-Received: by 2002:a17:90a:8a13:b0:263:661e:e0dc with SMTP id w19-20020a17090a8a1300b00263661ee0dcmr5930107pjn.25.1690129418604; Sun, 23 Jul 2023 09:23:38 -0700 (PDT) Received: from d.home.yangfl.dn42 ([104.28.245.199]) by smtp.gmail.com with ESMTPSA id u3-20020a17090aae8300b00265a7145fe5sm6883787pjq.41.2023.07.23.09.23.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Jul 2023 09:23:38 -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 v5 01/13] clk: hisilicon: Add helper functions for platform driver Date: Mon, 24 Jul 2023 00:22:26 +0800 Message-Id: <20230723162245.35033-2-mmyangfl@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230723162245.35033-1-mmyangfl@gmail.com> References: <20230723162245.35033-1-mmyangfl@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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: INBOX X-GMAIL-THRID: 1772233370858562541 X-GMAIL-MSGID: 1772233370858562541 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 | 157 ++++++++++++++++++++++++++++++++++ drivers/clk/hisilicon/clk.h | 46 +++++++++- drivers/clk/hisilicon/crg.h | 5 ++ drivers/clk/hisilicon/reset.c | 42 +++++++++ 4 files changed, 248 insertions(+), 2 deletions(-) diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 54d9fdc93599..aa8908714cd0 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,141 @@ void __init hi6220_clk_register_divider(const struct hi6220_divider_clock *clks, data->clk_data.clks[clks[i].id] = clk; } } + +static size_t hisi_clocks_get_nr(const struct hisi_clocks *clks) +{ + if (clks->nr) + return clks->nr; + + 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); + +static 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; +} + +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); + +void 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); +} +EXPORT_SYMBOL_GPL(hisi_clk_remove); diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h index 7a9b42e1b027..87b17e9b79a3 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; + 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 *, @@ -154,4 +190,10 @@ hisi_clk_unregister(mux) hisi_clk_unregister(divider) hisi_clk_unregister(gate) +/* 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); +void hisi_clk_remove(struct platform_device *pdev); + #endif /* __HISI_CLK_H */ diff --git a/drivers/clk/hisilicon/crg.h b/drivers/clk/hisilicon/crg.h index 803f6ba6d7a2..bd8e76b1f6d7 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); +void 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..c7d4c9ea7183 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,41 @@ 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); + +void 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); +} +EXPORT_SYMBOL_GPL(hisi_crg_remove);