Received: by 2002:ab2:1347:0:b0:1f4:ac9d:b246 with SMTP id g7csp222977lqg; Thu, 11 Apr 2024 00:06:53 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCX0t3p8XK/sZoZIzn3in7kmrx320YnWUEGVscuoyRZIC9fXmRkkHhuZ3VyaCK2w0thVUFkF8RDPyAPZOcD9UBxfK8yC3DNF3FG7s2ljdw== X-Google-Smtp-Source: AGHT+IGhH2lYxHL9gfmfys9dAb72vvW6CIARJiaOHDi6S6CXlxLMXiEkXJwWNylEq2WtO6AzuwQy X-Received: by 2002:a25:a3c4:0:b0:dbd:8f9:a71 with SMTP id e62-20020a25a3c4000000b00dbd08f90a71mr4860997ybi.28.1712819213571; Thu, 11 Apr 2024 00:06:53 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712819213; cv=pass; d=google.com; s=arc-20160816; b=vqeDbr1VB/j/s64BDmdXTNFqXUEx0aYG2km0hTqjSww6zO4y9wAtI4SBd4FYs/hh8S Hja2c5yrTmR17dfgkyXXkvCbRS5+7GYwzgFRvrv2nMv4Qvbj+etGIsyxSx7oyqbuU20b XLsqQ2Faqiu/ygxGUvkwRiTJv8HAQ/rsonipEMJIct9cqwK4NIQllLIJBMCXCyRUoJDA J6gV6S9ycRWaw2Crcy6v0eMYc61dzxkF9Kx2+VyjIMEMJOc6Pnl3RWE2mNBTwx5HWh1o LhHl2L81clq2xa0h2GXPaG6XzeLvnlc93g2StvnnALDILB8R+PS812MQMSTU0NpY3glm QFyg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=n8lUCW6/osKWYcttIWv//iPm23yYuW3M1dv6E9h9iCk=; fh=ISfTbJuiEYcRBJZEtoICAiD8Zh4mtX/mMCqdAHNWdBE=; b=CUNdaq4Xnd0chlyaLuTHq7Q80rfcguh1039TKvkn8py/BnDC+WKJLctuX7nGfBN169 vXayL5gRMn0ffMgtOm7opMM1dcy4op7axSFe6rg6IHqyMZ/pVhhd8b2uMx77qKXUFNLb lnxGQgyNlxo3ds/ygR8X3N1wUU65mCfMGwlvujtT1GvgL2T9ffEPd86uwxzd2oLfBb9F DKDtp1Zjniz/Zm2Lrq/z0EdYxf6NI2VyxWhhgz1OR74LPjV5J5JOfwap0TJwAbmxBpah MU6ednXNsqT64thYcUeQyFT9TOYJmszNc8PMVvrp9wMAJATbMYHi7gwVAggQSxd4y2uN Mo8Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=R0KE177j; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-139917-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-139917-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id e9-20020ac85989000000b004366ca9593csi253130qte.523.2024.04.11.00.06.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Apr 2024 00:06:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-139917-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=R0KE177j; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-139917-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-139917-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 3A9251C217C5 for ; Thu, 11 Apr 2024 07:06:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A62BB13E058; Thu, 11 Apr 2024 07:06:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R0KE177j" Received: from mail-oi1-f170.google.com (mail-oi1-f170.google.com [209.85.167.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A351813E028; Thu, 11 Apr 2024 07:06:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712819179; cv=none; b=Ebkyk/rVUn2yk3D3/KFqImuj3J1ahGV7y3JQQqc0crn7RsR5uzT/39hTc96NtAmaNOzhdwhzurWLIJkCffEZJNp9s46XHvyWm4jPRxhl/4jTMWW+HcvcRSyA0uR2XbNek++r9faWJGBK/mOTjilSLzrN8uU566+zvAfHXJ9fK1Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712819179; c=relaxed/simple; bh=nFRMU6xTbrzOS51FDYFjCaA/OJfcz6/qg6Mj1TgIBms=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R9FG8sb5bhP8Ko8coZXuf5dpVjgUTMXq9YiCoPzJ3SvwN8SKSzMh6dIicaVaJRGdMRtyZPsisMAvMINDOMr3mJLTz9lSlgmvBBj/0un81RehAnrR2JmrjbSxHIv8zcm8vbeM295sZKZnSuj7rSHRzQ5UqySdn0OC7f9AFxSPA3U= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=R0KE177j; arc=none smtp.client-ip=209.85.167.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oi1-f170.google.com with SMTP id 5614622812f47-3c397193878so4053640b6e.3; Thu, 11 Apr 2024 00:06:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712819176; x=1713423976; darn=vger.kernel.org; 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=n8lUCW6/osKWYcttIWv//iPm23yYuW3M1dv6E9h9iCk=; b=R0KE177jIgyOkKBsRG3rrneXZD5urcWtS3iKCgxAUmonJb+LYBrahmfCxN2yygB8h7 mdXGK1UA3nxL0ExEm1jaQopLSkd77roXHAT7fakXFrjT3H1RGqEwQdWmaOvHqgXYqDmt zIkGdvcg+7/IqEHVvhwVGVuKqLGYhn+/o/jMFyOIVBuLslYAu0aqPE85loH2uMijuHaQ qIrmeSw79jnDh2Kil1xF5YZxluM72i4oUdanA+O4QUys7ig7LTlcJ4IfUAVHtmGzO4re QdnanaPjv/W6/8Z+qDzzVZJctp8Jb5OihUQ7UbpiEdE4bdswcvO3DqNTTRw6Gzn0BPOr 34uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712819176; x=1713423976; 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=n8lUCW6/osKWYcttIWv//iPm23yYuW3M1dv6E9h9iCk=; b=HvGB6KDlpX2dCREt7Ni1/dX80xYfyideL6cgwjprfB5yzCYbXKYc2DA1M3EVM8/Xo2 Wrwz/UpO893kL0jVNn8Ej5BTEchloYmrvSZ40SDsWO2sNRikbOZuUPNQusWON7EvGbfG kWlq7LvTN/bXQ9rtWoCnAkYELJDZ91KUyvVWtKLTyX8E6ANZfo1oPfTlHZJ6QE4W/TRf zRqRtTV36j9phsEb4uUBD683jgsXk8ATG4UoXQHspUUIv2C0Qz2zugty5TnlS8cuh7h0 3syYngQNqK3Ze2l/4ovdNy2M7JFDawn76bc20QygtwvsX1Z+9anns7Zhfez+9fCmfqL8 /WUA== X-Forwarded-Encrypted: i=1; AJvYcCXAEMcANPwY0u0xL7yQDdNU9GQ/o3eBwp4uBbMbwjDIgOELh9Ul6+W8n5Lq4VeidUiJf5CnhBcsql4op8WnvZuxNyW3jNX+lkYKcW92 X-Gm-Message-State: AOJu0YwlaLc4hK4wXeaA43yDSriN3NwFVK5b0NpDWZaBNBjLIVAudSrl 3elQeZTrOgDVqEVAjAtIaIwjpNFNP+rGcddUIMD3zbNjBYLnmJR5tc+u9Lhc X-Received: by 2002:a05:6870:a10c:b0:229:8236:ae9 with SMTP id m12-20020a056870a10c00b0022982360ae9mr4565215oae.59.1712819176187; Thu, 11 Apr 2024 00:06:16 -0700 (PDT) Received: from d.wok.cipunited.com ([104.28.213.200]) by smtp.gmail.com with ESMTPSA id g5-20020a056a0023c500b006e6be006637sm647402pfc.135.2024.04.11.00.06.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Apr 2024 00:06:15 -0700 (PDT) From: David Yang To: linux-clk@vger.kernel.org Cc: Michael Turquette , Stephen Boyd , linux-kernel@vger.kernel.org, David Yang Subject: [PATCH v8 01/13] clk: hisilicon: Add helper functions for platform driver Date: Thu, 11 Apr 2024 15:04:46 +0800 Message-ID: <20240411070503.38093-3-mmyangfl@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240411070503.38093-2-mmyangfl@gmail.com> References: <20240411070503.38093-2-mmyangfl@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 09368fd32bef..e50115f8e236 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); -- 2.43.0