From patchwork Mon Jun 17 16:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701060 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 926A2C27C79 for ; Mon, 17 Jun 2024 16:46:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ZfbBcvTWg9v7Bbg+JkZfv+jRFiGBg9MQxpTsL00jJxg=; b=vqG0SfPjJcJHs9xz66obDqi9Fy NX5VsRKG7rM3bch+l0yD56r/2JllLVoRnlfyCdoFZ7/MH3lozTuqT9sYh97wHDAvqcxZnqAji6nza esJifU7rlr0Xf8FLK7ZxTyt9yIXXlsVt8H2yYZ2faFg2ZmAiimOEh8GsVfPQ2KqF6TpipzIG8MRvZ al/Vj+1X1KL2fYY1SdFSa7sgXiJxLDu/M2VIp6UMxp/+7wUJH/OqkLXWIP6okB9/QQs+Q/wItRO7Q DBOz8qTNPB6yOJm6AMrQ6W3TuG6pyRmbbX3R24x0CIlsuaI8cHvPmQ2pKcQHSHmMt7/+h9XIsrCty sceUoZVw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFUr-0000000BngL-1963; Mon, 17 Jun 2024 16:46:21 +0000 Received: from mail-ej1-x636.google.com ([2a00:1450:4864:20::636]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTm-0000000Bn17-1iDX for linux-arm-kernel@lists.infradead.org; Mon, 17 Jun 2024 16:45:20 +0000 Received: by mail-ej1-x636.google.com with SMTP id a640c23a62f3a-a63359aaacaso692924066b.1 for ; Mon, 17 Jun 2024 09:45:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642713; x=1719247513; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ZfbBcvTWg9v7Bbg+JkZfv+jRFiGBg9MQxpTsL00jJxg=; b=u5kYIOG1gQz8yF5gxcrfVmcpTCyf1iiYODzRpmcag+dEMcPGMc7uirXkdV2ziNGLoP /mz4dWbGTHci6FHzBuJuz2YiHsT6qA8WV/XUgHCo6PsddgKSwzDDxGdaPQEEJKhy7lor xgrINYUyTdb9+QXfhorKG3EusYhts99500dHIDHlWJyW2/t/ZRxT3HNcZFboo3WLqD/w S8Npb57WguPBmvojGqa921zHuflPAunM9CwGxFJFL3Twe7d2Vpig6zYOgUEfn6Z5ByrM PyMcoQwJIFogiS8lRbDTF465n1vU5BKSMERp2Dot/W0hSPFulkc6KxOk8ckIgMRJerna y2pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642713; x=1719247513; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZfbBcvTWg9v7Bbg+JkZfv+jRFiGBg9MQxpTsL00jJxg=; b=M7vaHSDSf0ZUpqeJwELyQG/fkt3R1jsjYehJNRtvj2CToXAP9CwJuqtoYroc727tV4 21aAG3MBEpxLMI8mEk5BNKLG/q2PAFULE1lOHE2ZGT7a4hFkMW0001jk7NRBGDtGBtij 3z/ukZvamUyWqZIP+G+mAy5RQHWJoNX75oLOsHo6i0lJX0wQ7zx69LM/j8Nr6VP05p0o ngn2Ov4XqVTNcmC5W4cJQ6xnXA0dvtt6FUblIdTSfUDEvpIcRnoNCKExOtI0KclV3R8a CnS87ERmjDTa264E2thVzEizCHQlTYlJJ2hx+E2KOMn0AfZSYPEsgPCr/ychFyvBHkx0 bZ5w== X-Forwarded-Encrypted: i=1; AJvYcCX4QUDZnxoiYQs/qzQ94Kv07s2cZBr5EAoqZbasilx1WfTc0HzdwnittCgkXLMLnNqsnjsrgVO3DH+aAEDycDAb4svi9mlsUa93z1kM0vG2M+MqsTs= X-Gm-Message-State: AOJu0Yx7RbBpd4dZ/wa73BNeE0ApcZPsYw0Y+5nDIuGdF3o0bTk1RVBu bEls+gNwz9YVf74dzORZmwpDYm9hmNydUo0cvP5UG3WduYSo+thvdv+hKd2AsNY= X-Google-Smtp-Source: AGHT+IFwqHuL/AFdrKJ5yS1y9SrBtKhrGrSio/O9IDSp5AUqAYl4zRsXzu5G8/8K7KBD2vk6PlyL9A== X-Received: by 2002:a17:906:d18f:b0:a6f:7c8:4fd6 with SMTP id a640c23a62f3a-a6f60bcbaadmr750030066b.0.1718642712613; Mon, 17 Jun 2024 09:45:12 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:12 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:44 +0100 Subject: [PATCH v3 3/6] phy: exynos5-usbdrd: convert core clocks to clk_bulk MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-3-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094514_646870_75CA71A7 X-CRM114-Status: GOOD ( 24.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler. No need to check any flags whether or not certain clocks exist or not. Further, we can drop the various handles to the individual clocks in the driver data and instead simply treat them all as one thing. So far, this driver assumes that all platforms have a clock "ref". It also assumes that the clocks "phy_pipe", "phy_utmi", and "itp" exist if the platform data "has_common_clk_gate" is set to true. It then goes and individually tries to acquire and enable and disable all the individual clocks one by one. Rather than relying on these implicit clocks and open-coding the clock handling, we can just explicitly spell out the clock names in the different device data and use that information to populate clk_bulk_data, allowing us to use the clk_bulk APIs for managing the clocks. As a side-effect, this change highlighted the fact that exynos5_usbdrd_phy_power_on() forgot to check the result of the clock enable calls. Using the clk_bulk APIs, the compiler now warns when return values are not checked - therefore add the necessary check instead of silently ignoring failures and continuing as if all is OK when it isn't. For consistency, also change a related dev_err() to dev_err_probe() in exynos5_usbdrd_phy_clk_handle() to get consistent error message formatting. Finally, exynos5_usbdrd_phy_clk_handle() prints an error message in all cases as necessary (except for -ENOMEM). There is no need to print another message in its caller (the probe() function), and printing errors during OOM conditions is usually discouraged. Drop the duplicated message in exynos5_usbdrd_phy_probe(). Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 129 +++++++++++++++---------------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index b7e2526f4c06..35b307dad2ee 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -185,10 +185,11 @@ struct exynos5_usbdrd_phy_config { struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; const struct phy_ops *phy_ops; + const char * const *core_clk_names; + int n_core_clks; u32 pmu_offset_usbdrd0_phy; u32 pmu_offset_usbdrd0_phy_ss; u32 pmu_offset_usbdrd1_phy; - bool has_common_clk_gate; }; /** @@ -196,16 +197,12 @@ struct exynos5_usbdrd_phy_drvdata { * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base * @clk: phy clock for register access - * @pipeclk: clock for pipe3 phy - * @utmiclk: clock for utmi+ phy - * @itpclk: clock for ITP generation + * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required) * @drv_data: pointer to SoC level driver data structure * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY * instances each with its 'phy' and 'phy_cfg'. * @extrefclk: frequency select settings when using 'separate * reference clocks' for SS and HS operations - * @ref_clk: reference clock to PHY block from which PHY's - * operational clocks are derived * @vbus: VBUS regulator for phy * @vbus_boost: Boost regulator for VBUS present on few Exynos boards */ @@ -213,9 +210,7 @@ struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; struct clk *clk; - struct clk *pipeclk; - struct clk *utmiclk; - struct clk *itpclk; + struct clk_bulk_data *core_clks; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct phy_usb_instance { struct phy *phy; @@ -225,7 +220,6 @@ struct exynos5_usbdrd_phy { const struct exynos5_usbdrd_phy_config *phy_cfg; } phys[EXYNOS5_DRDPHYS_NUM]; u32 extrefclk; - struct clk *ref_clk; struct regulator *vbus; struct regulator *vbus_boost; }; @@ -505,12 +499,10 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); - clk_prepare_enable(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_prepare_enable(phy_drd->pipeclk); - clk_prepare_enable(phy_drd->utmiclk); - clk_prepare_enable(phy_drd->itpclk); - } + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + if (ret) + return ret; /* Enable VBUS supply */ if (phy_drd->vbus_boost) { @@ -540,12 +532,8 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) regulator_disable(phy_drd->vbus_boost); fail_vbus: - clk_disable_unprepare(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_disable_unprepare(phy_drd->itpclk); - clk_disable_unprepare(phy_drd->utmiclk); - clk_disable_unprepare(phy_drd->pipeclk); - } + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); return ret; } @@ -566,12 +554,8 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) if (phy_drd->vbus_boost) regulator_disable(phy_drd->vbus_boost); - clk_disable_unprepare(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_disable_unprepare(phy_drd->itpclk); - clk_disable_unprepare(phy_drd->pipeclk); - clk_disable_unprepare(phy_drd->utmiclk); - } + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); return 0; } @@ -885,8 +869,9 @@ static const struct phy_ops exynos850_usbdrd_phy_ops = { static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) { - unsigned long ref_rate; int ret; + struct clk *ref_clk; + unsigned long ref_rate; phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); if (IS_ERR(phy_drd->clk)) { @@ -894,42 +879,39 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) return PTR_ERR(phy_drd->clk); } - phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); - if (IS_ERR(phy_drd->ref_clk)) { - dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); - return PTR_ERR(phy_drd->ref_clk); - } - ref_rate = clk_get_rate(phy_drd->ref_clk); - - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); - if (ret) { - dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", - ref_rate); - return ret; - } + phy_drd->core_clks = devm_kcalloc(phy_drd->dev, + phy_drd->drv_data->n_core_clks, + sizeof(*phy_drd->core_clks), + GFP_KERNEL); + if (!phy_drd->core_clks) + return -ENOMEM; - if (!phy_drd->drv_data->has_common_clk_gate) { - phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); - if (IS_ERR(phy_drd->pipeclk)) { - dev_info(phy_drd->dev, - "PIPE3 phy operational clock not specified\n"); - phy_drd->pipeclk = NULL; - } + for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) + phy_drd->core_clks[i].id = phy_drd->drv_data->core_clk_names[i]; - phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); - if (IS_ERR(phy_drd->utmiclk)) { - dev_info(phy_drd->dev, - "UTMI phy operational clock not specified\n"); - phy_drd->utmiclk = NULL; - } + ret = devm_clk_bulk_get(phy_drd->dev, phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + if (ret) + return dev_err_probe(phy_drd->dev, ret, + "failed to get phy core clock(s)\n"); - phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); - if (IS_ERR(phy_drd->itpclk)) { - dev_info(phy_drd->dev, - "ITP clock from main OSC not specified\n"); - phy_drd->itpclk = NULL; + ref_clk = NULL; + for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) { + if (!strcmp(phy_drd->core_clks[i].id, "ref")) { + ref_clk = phy_drd->core_clks[i].clk; + break; } } + if (!ref_clk) + return dev_err_probe(phy_drd->dev, -ENODEV, + "failed to find phy reference clock\n"); + + ref_rate = clk_get_rate(ref_clk); + ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + if (ret) + return dev_err_probe(phy_drd->dev, ret, + "clock rate (%ld) not supported\n", + ref_rate); return 0; } @@ -957,19 +939,29 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { }, }; +static const char * const exynos5_core_clk_names[] = { + "ref", +}; + +static const char * const exynos5433_core_clk_names[] = { + "ref", "phy_pipe", "phy_utmi", "itp", +}; + static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { @@ -977,21 +969,24 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL, - .has_common_clk_gate = false, + .core_clk_names = exynos5433_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = false, + .core_clk_names = exynos5433_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .phy_cfg = phy_cfg_exynos850, .phy_ops = &exynos850_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { @@ -1045,10 +1040,8 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) phy_drd->drv_data = drv_data; ret = exynos5_usbdrd_phy_clk_handle(phy_drd); - if (ret) { - dev_err(dev, "Failed to initialize clocks\n"); + if (ret) return ret; - } reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,pmu-syscon");