From patchwork Sat Aug 3 10:57:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752339 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0614913633B; Sat, 3 Aug 2024 10:57:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682679; cv=none; b=g+uGzmooX7b/EX+2th58NAAkyjFTbxpKde8KznVi93K11SNl5rF+vG8x7RzIELrHS7gDvprlmhhnc6Zw6Czp4AiMyE4YvgmPhhy631bPNy9fUGanK0nBs/mo581ooLVAMqf7AzK+lxF3Fty3xgDdzJokNNwkfk2wocK756ejbxM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682679; c=relaxed/simple; bh=qeGqzsOq6hvnt2Ssx+xjMH+EgeX1O9a/0x2cswTGQyM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P4lLgs0h7WnPJFFffa5lakbiq5gJYhakNzFcZC9BF2uOgcmFyJD9JDj4/ADghv7ZpPkKfXz2bXP8r0HeM8GJ+RRDOepo0VKFKUHZ1a1Zey65w/jpcMJpFawT8I+c6PgNejwv+zSGspCtn3D3jEr1/WKsqTK+IyICJe0hN/cTXj4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=ixBI5W35; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="ixBI5W35" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682675; x=1722941875; bh=hgmQYgGbKBNIE3jKAVuoNIdAjegNRZ9f/iIDrU2/RLw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=ixBI5W35ybTOngt+f3ZS3wHskUqHRlFNSAwxMUQRlIyf+h2M4bzAHXqMX/frif8cV Ld3+CzJhOyQCdl875fS3nR63vqdPEvvo6DpCR2Eifrtlim6F5ZLYv6pBoKtNlPvjH+ 4jx7liAVq44evMVYku+pOxX2tH/a1Kdq3ly8KeKAa0cgLJtgpXyHzjIZacfzIHnzzM pRJ7l2Y4YpWWXXNtW2z1eRge2lxnJTXsWDUmwKbbVp/KOrAxlVKmbQTVZkO9HEn8GN jWWh88mAkajIsoFxBfSICWZHc6LLv9I1OwlaKU3+CN5aLo/esG6U6UE/i4WSjAM4/5 jhSBf51ZMjj4Q== Date: Sat, 03 Aug 2024 10:57:50 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 1/9] clk: clocking-wizard: simplify probe/remove with devres helpers Message-ID: <20240803105702.9621-2-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 33b6043ca5154c7c9ec3ae9711320c530f26e506 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Remove need to do various operations in remove callback and error paths by utilising device managed versions of clock and notifier APIs. Signed-off-by: Harry Austen Reviewed-by: Stephen Boyd --- v1 -> v2: Add Stephen's R-b tag drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 48 ++++++---------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 19eb3fb7ae319..0ca045849ea3e 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -1001,21 +1001,15 @@ static int clk_wzrd_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), "clk_in1 not found\n"); - clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); if (IS_ERR(clk_wzrd->axi_clk)) return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), "s_axi_aclk not found\n"); - ret = clk_prepare_enable(clk_wzrd->axi_clk); - if (ret) { - dev_err(&pdev->dev, "enabling s_axi_aclk failed\n"); - return ret; - } rate = clk_get_rate(clk_wzrd->axi_clk); if (rate > WZRD_ACLK_MAX_FREQ) { dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate); - ret = -EINVAL; - goto err_disable_clk; + return -EINVAL; } data = device_get_match_data(&pdev->dev); @@ -1023,16 +1017,12 @@ static int clk_wzrd_probe(struct platform_device *pdev) is_versal = data->is_versal; ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); - if (ret || nr_outputs > WZRD_NUM_OUTPUTS) { - ret = -EINVAL; - goto err_disable_clk; - } + if (ret || nr_outputs > WZRD_NUM_OUTPUTS) + return -EINVAL; clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev)); - if (!clkout_name) { - ret = -ENOMEM; - goto err_disable_clk; - } + if (!clkout_name) + return -ENOMEM; if (is_versal) { if (nr_outputs == 1) { @@ -1090,18 +1080,15 @@ static int clk_wzrd_probe(struct platform_device *pdev) div = 1000; } clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); - if (!clk_name) { - ret = -ENOMEM; - goto err_disable_clk; - } + if (!clk_name) + return -ENOMEM; clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor (&pdev->dev, clk_name, __clk_get_name(clk_wzrd->clk_in1), 0, mult, div); if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { dev_err(&pdev->dev, "unable to register fixed-factor clock\n"); - ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); - goto err_disable_clk; + return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); } clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); @@ -1197,13 +1184,14 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (clk_wzrd->speed_grade) { clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; - ret = clk_notifier_register(clk_wzrd->clk_in1, - &clk_wzrd->nb); + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1, + &clk_wzrd->nb); if (ret) dev_warn(&pdev->dev, "unable to register clock notifier\n"); - ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb); + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk, + &clk_wzrd->nb); if (ret) dev_warn(&pdev->dev, "unable to register clock notifier\n"); @@ -1215,9 +1203,6 @@ static int clk_wzrd_probe(struct platform_device *pdev) clk_unregister(clk_wzrd->clks_internal[1]); err_rm_int_clk: clk_unregister(clk_wzrd->clks_internal[0]); -err_disable_clk: - clk_disable_unprepare(clk_wzrd->axi_clk); - return ret; } @@ -1232,13 +1217,6 @@ static void clk_wzrd_remove(struct platform_device *pdev) clk_unregister(clk_wzrd->clkout[i]); for (i = 0; i < wzrd_clk_int_max; i++) clk_unregister(clk_wzrd->clks_internal[i]); - - if (clk_wzrd->speed_grade) { - clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb); - clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb); - } - - clk_disable_unprepare(clk_wzrd->axi_clk); } static const struct of_device_id clk_wzrd_ids[] = { From patchwork Sat Aug 3 10:57:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752341 Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23A1314F138 for ; Sat, 3 Aug 2024 10:58:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682690; cv=none; b=RuXEvoUepr19jOJgK7NbizJ7kXdqVHyUNu9V3I2IfOU0veOlbz4wu15VSx9HJbrmQX4r07VeC8LEWdBLIkLF93MEblu0Ce4iTSl4XS82DXW9pnr3c7dGeeO7oG83pjyxC6mbgtZpd3VszU0XH8vnn0yoh/eRG9ttfpeZoSp38/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682690; c=relaxed/simple; bh=aHpkg3Dt6T/pZASy33bmrQtjWDdXc2myLglEgCQn0W8=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AUCd2D8pAafqS28pUBumVK2MJHcsXXSYFty6i3AvEsBA7GvIsSkCriDY0q45Bo7jHin5heQXSNRyrefsVUYAFpBmhymtsbAZsZZ6RuAV9FnpCA56liHz4t+yKAdxPqu6rPHgPm8ANbsF+n9VPnUTTU8ASMqtBkcXNlNivqV3USM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=cQYODIXK; arc=none smtp.client-ip=185.70.40.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="cQYODIXK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682682; x=1722941882; bh=aFKN+b0Saw1IphsCNqgGUJBEZJNTr/Nxv82GUZruSNw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=cQYODIXK6LMhoawJWffkp2CRRaAM/HM6kgdvhmBY3FzY1cHbK55V083i8ru6Dz8Fp TQOx14BkVYWiw+ZgSGh9niJVQMFde7y6qnPObLFwIX69myfIO9BjFqWCrk2E5m6pBl jzXJz+4zueDwlBqbcslCMXm7mD2yjiUL0Fa6NKsqHqdZI5LYh1KeiyW3Z4PZ4Nbwxw rHpkcR1CcCitPvC8hfUQYhgoV9OhvzTldUDNCDgEP0DFHPfsh/BnxxJm1m8MQFnWGg B3pT5fxs4KFkdqdxCLhqHz4ZXvI65KvWYi5kmgbRqLkeMw/KYfd2glCTODuzgUbNvQ 7Bs8r/hPqCeYA== Date: Sat, 03 Aug 2024 10:57:57 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 2/9] clk: clocking-wizard: use newer clk_hw API Message-ID: <20240803105702.9621-3-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 019e6b55198fc166203181dcb7ae7b5abae111d4 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Utilise clock provider API with struct clk_hw instances instead of the consumer-side struct clk. Signed-off-by: Harry Austen --- v1 -> v2: - Move onecell data to end of struct for single allocation - Just move to clk_hw API. Move devres transition to subsequent patch drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 77 +++++++++++----------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 0ca045849ea3e..ccaf30c2d9481 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -121,26 +122,24 @@ enum clk_wzrd_int_clks { /** * struct clk_wzrd - Clock wizard private data structure * - * @clk_data: Clock data + * @clk_data: Output clock data * @nb: Notifier block * @base: Memory base * @clk_in1: Handle to input clock 'clk_in1' * @axi_clk: Handle to input clock 's_axi_aclk' * @clks_internal: Internal clocks - * @clkout: Output clocks * @speed_grade: Speed grade of the device * @suspended: Flag indicating power state of the device */ struct clk_wzrd { - struct clk_onecell_data clk_data; struct notifier_block nb; void __iomem *base; struct clk *clk_in1; struct clk *axi_clk; - struct clk *clks_internal[wzrd_clk_int_max]; - struct clk *clkout[WZRD_NUM_OUTPUTS]; + struct clk_hw *clks_internal[wzrd_clk_int_max]; unsigned int speed_grade; bool suspended; + struct clk_hw_onecell_data clk_data; }; /** @@ -765,7 +764,7 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = { .recalc_rate = clk_wzrd_recalc_ratef, }; -static struct clk *clk_wzrd_register_divf(struct device *dev, +static struct clk_hw *clk_wzrd_register_divf(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -805,10 +804,10 @@ static struct clk *clk_wzrd_register_divf(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } -static struct clk *clk_wzrd_ver_register_divider(struct device *dev, +static struct clk_hw *clk_wzrd_ver_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -852,10 +851,10 @@ static struct clk *clk_wzrd_ver_register_divider(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } -static struct clk *clk_wzrd_register_divider(struct device *dev, +static struct clk_hw *clk_wzrd_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -898,7 +897,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event, @@ -978,7 +977,12 @@ static int clk_wzrd_probe(struct platform_device *pdev) int nr_outputs; int i, ret; - clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL); + ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); + if (ret || nr_outputs > WZRD_NUM_OUTPUTS) + return -EINVAL; + + clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs), + GFP_KERNEL); if (!clk_wzrd) return -ENOMEM; platform_set_drvdata(pdev, clk_wzrd); @@ -1016,17 +1020,13 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (data) is_versal = data->is_versal; - ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); - if (ret || nr_outputs > WZRD_NUM_OUTPUTS) - return -EINVAL; - clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev)); if (!clkout_name) return -ENOMEM; if (is_versal) { if (nr_outputs == 1) { - clk_wzrd->clkout[0] = clk_wzrd_ver_register_divider + clk_wzrd->clk_data.hws[0] = clk_wzrd_ver_register_divider (&pdev->dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), @@ -1059,7 +1059,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) div = 64; } else { if (nr_outputs == 1) { - clk_wzrd->clkout[0] = clk_wzrd_register_divider + clk_wzrd->clk_data.hws[0] = clk_wzrd_register_divider (&pdev->dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), @@ -1082,7 +1082,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); if (!clk_name) return -ENOMEM; - clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor + clk_wzrd->clks_internal[wzrd_clk_mul] = clk_hw_register_fixed_factor (&pdev->dev, clk_name, __clk_get_name(clk_wzrd->clk_in1), 0, mult, div); @@ -1108,15 +1108,15 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (!div) div = 1; - clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); + clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); clk_wzrd->clks_internal[wzrd_clk_mul_div] = - clk_register_fixed_factor(&pdev->dev, clk_name, - clk_mul_name, 0, 1, div); + clk_hw_register_fixed_factor(&pdev->dev, clk_name, + clk_mul_name, 0, 1, div); } else { ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0); - clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider + clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_hw_register_divider (&pdev->dev, clk_name, - __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), + clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock); } @@ -1136,7 +1136,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) } if (is_versal) { - clk_wzrd->clkout[i] = clk_wzrd_ver_register_divider + clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider (&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base, @@ -1148,7 +1148,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) DIV_O, &clkwzrd_lock); } else { if (!i) - clk_wzrd->clkout[i] = clk_wzrd_register_divf + clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divf (&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1156,7 +1156,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_O, &clkwzrd_lock); else - clk_wzrd->clkout[i] = clk_wzrd_register_divider + clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divider (&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1164,22 +1164,25 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_O, &clkwzrd_lock); } - if (IS_ERR(clk_wzrd->clkout[i])) { + if (IS_ERR(clk_wzrd->clk_data.hws[i])) { int j; for (j = i + 1; j < nr_outputs; j++) - clk_unregister(clk_wzrd->clkout[j]); + clk_hw_unregister(clk_wzrd->clk_data.hws[j]); dev_err(&pdev->dev, "unable to register divider clock\n"); - ret = PTR_ERR(clk_wzrd->clkout[i]); + ret = PTR_ERR(clk_wzrd->clk_data.hws[i]); goto err_rm_int_clks; } } out: - clk_wzrd->clk_data.clks = clk_wzrd->clkout; - clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data); + clk_wzrd->clk_data.num = nr_outputs; + ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, &clk_wzrd->clk_data); + if (ret) { + dev_err(&pdev->dev, "unable to register clock provider\n"); + return ret; + } if (clk_wzrd->speed_grade) { clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; @@ -1200,9 +1203,9 @@ static int clk_wzrd_probe(struct platform_device *pdev) return 0; err_rm_int_clks: - clk_unregister(clk_wzrd->clks_internal[1]); + clk_hw_unregister(clk_wzrd->clks_internal[1]); err_rm_int_clk: - clk_unregister(clk_wzrd->clks_internal[0]); + clk_hw_unregister(clk_wzrd->clks_internal[0]); return ret; } @@ -1214,9 +1217,9 @@ static void clk_wzrd_remove(struct platform_device *pdev) of_clk_del_provider(pdev->dev.of_node); for (i = 0; i < WZRD_NUM_OUTPUTS; i++) - clk_unregister(clk_wzrd->clkout[i]); + clk_hw_unregister(clk_wzrd->clk_data.hws[i]); for (i = 0; i < wzrd_clk_int_max; i++) - clk_unregister(clk_wzrd->clks_internal[i]); + clk_hw_unregister(clk_wzrd->clks_internal[i]); } static const struct of_device_id clk_wzrd_ids[] = { From patchwork Sat Aug 3 10:58:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752342 Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4601B13633B for ; Sat, 3 Aug 2024 10:58:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682693; cv=none; b=ootAzNJHDatzEQGPSqjCi+HaYUHJdVpoBOiEw2LG5tBHwa8PEZ3Nt74mB/umgxKOSoAGwqoU0CG7YqSTF3wf0dJjpJgwvb8vP3i3txdDq/8FRU5FBiMySjvt0O2gQ0moLJ6w8X7+6cgOMSoconljXiBEZtC0PzuqdaZKB4Q5yyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682693; c=relaxed/simple; bh=tJcOjOt7CpDAdvGLNDfCZNuwgqeXDC/aJ8MWg3SS2gY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=o+nGtqumEWvaegg5DtGUxZYVypaAgn77cD2xMrGhuU8Th1D5VMxan+O6CqSqX5J45xCjJtWFOfg9SoUQR2fbm7VHVTNbr9/ORNiCCXcsPt/1kC6kJf4TMAF6Q2lnoj4bmsQ0DXeZwvhxgv/2zgqxyKDYkmewGCwkJyOTkuJ9lqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=k/OPrCeH; arc=none smtp.client-ip=185.70.40.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="k/OPrCeH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682690; x=1722941890; bh=0bJIPx09LELVRNHeZZCMVFYiAtr1yKFdcOKvTL0Vwlk=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=k/OPrCeHGyQdKbNRCpwQ0Fwc/4kSGQjXQOX+HeoVYPp7JmIlp7jKJAPRpBA8kF6T/ Y0f18A7bS4B9xBfRAWHHsThzJjvN8ld7Y7sX5tz8fgaUX5XrK9w5XZvK/9AO3fLYcp jB4d4siEmen/U9TwybnM9bwcxrNlXH2lFn822+LpkBHmF7ggoTDs2+miZEjW6GxV8M d8i/xyjDYyNaXBecIKEkgj09JVfSQqHhgSHlVUAl9szEUj6c88JBskRND63xZgUjRi UPCSQt1y7Mo/U8OSz9FTD/DKPyccs8Q+c7JCwxI5DBB0uqXn1RYoYm8VtFwXg39K70 WflY/jE/DjXZw== Date: Sat, 03 Aug 2024 10:58:04 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 3/9] clk: clocking-wizard: use devres versions of clk_hw API Message-ID: <20240803105702.9621-4-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: bfd10b61e6f5845dd8c2606d6350dd8cd8826350 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use device managed versions of the clk_hw API, entirely removing the need for the driver's remove() callback and greatly simplifying the probe() function's error paths. Signed-off-by: Harry Austen --- v1 -> v2: New drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 52 +++++----------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index ccaf30c2d9481..810d57c46a63c 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -1082,7 +1082,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); if (!clk_name) return -ENOMEM; - clk_wzrd->clks_internal[wzrd_clk_mul] = clk_hw_register_fixed_factor + clk_wzrd->clks_internal[wzrd_clk_mul] = devm_clk_hw_register_fixed_factor (&pdev->dev, clk_name, __clk_get_name(clk_wzrd->clk_in1), 0, mult, div); @@ -1092,10 +1092,8 @@ static int clk_wzrd_probe(struct platform_device *pdev) } clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); - if (!clk_name) { - ret = -ENOMEM; - goto err_rm_int_clk; - } + if (!clk_name) + return -ENOMEM; if (is_versal) { edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) & @@ -1110,11 +1108,11 @@ static int clk_wzrd_probe(struct platform_device *pdev) clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); clk_wzrd->clks_internal[wzrd_clk_mul_div] = - clk_hw_register_fixed_factor(&pdev->dev, clk_name, - clk_mul_name, 0, 1, div); + devm_clk_hw_register_fixed_factor(&pdev->dev, clk_name, + clk_mul_name, 0, 1, div); } else { ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0); - clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_hw_register_divider + clk_wzrd->clks_internal[wzrd_clk_mul_div] = devm_clk_hw_register_divider (&pdev->dev, clk_name, clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED | @@ -1122,18 +1120,15 @@ static int clk_wzrd_probe(struct platform_device *pdev) } if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { dev_err(&pdev->dev, "unable to register divider clock\n"); - ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); - goto err_rm_int_clk; + return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); } /* register div per output */ for (i = nr_outputs - 1; i >= 0 ; i--) { clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out%d", dev_name(&pdev->dev), i); - if (!clkout_name) { - ret = -ENOMEM; - goto err_rm_int_clk; - } + if (!clkout_name) + return -ENOMEM; if (is_versal) { clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider @@ -1165,20 +1160,15 @@ static int clk_wzrd_probe(struct platform_device *pdev) DIV_O, &clkwzrd_lock); } if (IS_ERR(clk_wzrd->clk_data.hws[i])) { - int j; - - for (j = i + 1; j < nr_outputs; j++) - clk_hw_unregister(clk_wzrd->clk_data.hws[j]); dev_err(&pdev->dev, "unable to register divider clock\n"); - ret = PTR_ERR(clk_wzrd->clk_data.hws[i]); - goto err_rm_int_clks; + return PTR_ERR(clk_wzrd->clk_data.hws[i]); } } out: clk_wzrd->clk_data.num = nr_outputs; - ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, &clk_wzrd->clk_data); + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, &clk_wzrd->clk_data); if (ret) { dev_err(&pdev->dev, "unable to register clock provider\n"); return ret; @@ -1201,25 +1191,6 @@ static int clk_wzrd_probe(struct platform_device *pdev) } return 0; - -err_rm_int_clks: - clk_hw_unregister(clk_wzrd->clks_internal[1]); -err_rm_int_clk: - clk_hw_unregister(clk_wzrd->clks_internal[0]); - return ret; -} - -static void clk_wzrd_remove(struct platform_device *pdev) -{ - int i; - struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev); - - of_clk_del_provider(pdev->dev.of_node); - - for (i = 0; i < WZRD_NUM_OUTPUTS; i++) - clk_hw_unregister(clk_wzrd->clk_data.hws[i]); - for (i = 0; i < wzrd_clk_int_max; i++) - clk_hw_unregister(clk_wzrd->clks_internal[i]); } static const struct of_device_id clk_wzrd_ids[] = { @@ -1238,7 +1209,6 @@ static struct platform_driver clk_wzrd_driver = { .pm = &clk_wzrd_dev_pm_ops, }, .probe = clk_wzrd_probe, - .remove_new = clk_wzrd_remove, }; module_platform_driver(clk_wzrd_driver); From patchwork Sat Aug 3 10:58:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752343 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3C39136338; Sat, 3 Aug 2024 10:58:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682698; cv=none; b=bYgVb3mXSDarVyvD38WHE0B5ggW7KfMgrxXpV9att4VmLFGLIyBMmP1csflRF2VduHN5QyBWMpRgbb29+c+CFE6OAzvz7FK2w2v2WVKJ7LoDuUYDMYz1YAvzP5gy1liLEt6RsCAMZeY7cZW6ZQMxpYwAo1XPKq5psCAo4w4t/MY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682698; c=relaxed/simple; bh=Mv6Yg0xeleRP8tOTqAfnrhhtjwbm7/hZHyTLhXCf0C0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ftHPGjIUKe+iyBiGlia7RDxH/b5Z1/lgVhU7AIp2ZBVrmcuEii/57RM10CYWad9YCh4JOUu6/NO6kaNcUwxXjKtQZJFegb5Pee54XW+Lfpt2b+Zq+xs2u3CH7pip01vxnLiQnFnSYT9j005U0XXR9nnxGCxkhWu/tvjSQS1oYRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=UvO7EncE; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="UvO7EncE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682694; x=1722941894; bh=qYtpSyGaJgeWMzyv9a570X5QRmW7J8rKo6A6r07IUj0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=UvO7EncEU7kx7tc1O8G1jnDtw33rDr1dduu0VR4ygxNwqZCxVvn4i35Zl0kyZAakw Er8jS0W7AC0q+eH+FwgJtGTvPK6Zd1ng49G92Bw+ZPJP7PV2Qi2NAAyvLRgLZM9p4R 5HSV+J63G6MOQvQEoQdL6JZ4epUYriZxQerAITwUbF39AkQmykG9cWIrZrsL/8cTXB sP7ec4i2NcCS3fM47lj2JmIm5ruAtnkHpmdkMmC0hUcHIyBr4uNOnGjAbYnoKum/sN 1U3bY6OOD0QAFlK1B3MnhWsxX9fyJDau8UTtWyJbvwust5VoLy4FAoyzsVwiBCjMBP CxKhkOWJez26w== Date: Sat, 03 Aug 2024 10:58:12 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 4/9] clk: clocking-wizard: move clock registration to separate function Message-ID: <20240803105702.9621-5-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 0da5653f228cf98ac8ab02ccf02dab675b980e81 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Provide clear separation of dynamic reconfiguration logic, by moving its setup procedure to its own dedicated function. Signed-off-by: Harry Austen --- v1 -> v2: No functional change drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 143 +++++++++++---------- 1 file changed, 75 insertions(+), 68 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 810d57c46a63c..1f8023d24029f 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -962,72 +962,30 @@ static const struct versal_clk_data versal_data = { .is_versal = true, }; -static int clk_wzrd_probe(struct platform_device *pdev) +static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs) { const char *clkout_name, *clk_name, *clk_mul_name; + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); u32 regl, regh, edge, regld, reghd, edged, div; - struct device_node *np = pdev->dev.of_node; const struct versal_clk_data *data; - struct clk_wzrd *clk_wzrd; unsigned long flags = 0; + bool is_versal = false; void __iomem *ctrl_reg; u32 reg, reg_f, mult; - bool is_versal = false; - unsigned long rate; - int nr_outputs; - int i, ret; - - ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); - if (ret || nr_outputs > WZRD_NUM_OUTPUTS) - return -EINVAL; - - clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs), - GFP_KERNEL); - if (!clk_wzrd) - return -ENOMEM; - platform_set_drvdata(pdev, clk_wzrd); - - clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(clk_wzrd->base)) - return PTR_ERR(clk_wzrd->base); - - ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); - if (!ret) { - if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { - dev_warn(&pdev->dev, "invalid speed grade '%d'\n", - clk_wzrd->speed_grade); - clk_wzrd->speed_grade = 0; - } - } - - clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); - if (IS_ERR(clk_wzrd->clk_in1)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), - "clk_in1 not found\n"); + int i; - clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); - if (IS_ERR(clk_wzrd->axi_clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), - "s_axi_aclk not found\n"); - rate = clk_get_rate(clk_wzrd->axi_clk); - if (rate > WZRD_ACLK_MAX_FREQ) { - dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", - rate); - return -EINVAL; - } - - data = device_get_match_data(&pdev->dev); + data = device_get_match_data(dev); if (data) is_versal = data->is_versal; - clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev)); + clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out0", dev_name(dev)); if (!clkout_name) return -ENOMEM; if (is_versal) { if (nr_outputs == 1) { clk_wzrd->clk_data.hws[0] = clk_wzrd_ver_register_divider - (&pdev->dev, clkout_name, + (dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1035,7 +993,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_ALL, &clkwzrd_lock); - goto out; + return 0; } /* register multiplier */ edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) & @@ -1060,7 +1018,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) } else { if (nr_outputs == 1) { clk_wzrd->clk_data.hws[0] = clk_wzrd_register_divider - (&pdev->dev, clkout_name, + (dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1068,7 +1026,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_ALL, &clkwzrd_lock); - goto out; + return 0; } reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)); reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK; @@ -1079,19 +1037,19 @@ static int clk_wzrd_probe(struct platform_device *pdev) mult = (reg * 1000) + reg_f; div = 1000; } - clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); + clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul", dev_name(dev)); if (!clk_name) return -ENOMEM; clk_wzrd->clks_internal[wzrd_clk_mul] = devm_clk_hw_register_fixed_factor - (&pdev->dev, clk_name, + (dev, clk_name, __clk_get_name(clk_wzrd->clk_in1), 0, mult, div); if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { - dev_err(&pdev->dev, "unable to register fixed-factor clock\n"); + dev_err(dev, "unable to register fixed-factor clock\n"); return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); } - clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); + clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul_div", dev_name(dev)); if (!clk_name) return -ENOMEM; @@ -1108,31 +1066,29 @@ static int clk_wzrd_probe(struct platform_device *pdev) clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); clk_wzrd->clks_internal[wzrd_clk_mul_div] = - devm_clk_hw_register_fixed_factor(&pdev->dev, clk_name, - clk_mul_name, 0, 1, div); + devm_clk_hw_register_fixed_factor(dev, clk_name, clk_mul_name, 0, 1, div); } else { ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0); clk_wzrd->clks_internal[wzrd_clk_mul_div] = devm_clk_hw_register_divider - (&pdev->dev, clk_name, + (dev, clk_name, clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock); } if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { - dev_err(&pdev->dev, "unable to register divider clock\n"); + dev_err(dev, "unable to register divider clock\n"); return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); } /* register div per output */ for (i = nr_outputs - 1; i >= 0 ; i--) { - clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, - "%s_out%d", dev_name(&pdev->dev), i); + clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out%d", dev_name(dev), i); if (!clkout_name) return -ENOMEM; if (is_versal) { clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider - (&pdev->dev, + (dev, clkout_name, clk_name, 0, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 3) + i * 8), @@ -1144,7 +1100,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) } else { if (!i) clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divf - (&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base, + (dev, clkout_name, clk_name, flags, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, WZRD_CLKOUT_DIVIDE_WIDTH, @@ -1152,7 +1108,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) DIV_O, &clkwzrd_lock); else clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divider - (&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base, + (dev, clkout_name, clk_name, 0, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, WZRD_CLKOUT_DIVIDE_WIDTH, @@ -1160,13 +1116,64 @@ static int clk_wzrd_probe(struct platform_device *pdev) DIV_O, &clkwzrd_lock); } if (IS_ERR(clk_wzrd->clk_data.hws[i])) { - dev_err(&pdev->dev, - "unable to register divider clock\n"); + dev_err(dev, "unable to register divider clock\n"); return PTR_ERR(clk_wzrd->clk_data.hws[i]); } } -out: + return 0; +} + +static int clk_wzrd_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk_wzrd *clk_wzrd; + unsigned long rate; + int nr_outputs; + int ret; + + ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); + if (ret || nr_outputs > WZRD_NUM_OUTPUTS) + return -EINVAL; + + clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs), + GFP_KERNEL); + if (!clk_wzrd) + return -ENOMEM; + platform_set_drvdata(pdev, clk_wzrd); + + clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_wzrd->base)) + return PTR_ERR(clk_wzrd->base); + + ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); + if (!ret) { + if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { + dev_warn(&pdev->dev, "invalid speed grade '%d'\n", + clk_wzrd->speed_grade); + clk_wzrd->speed_grade = 0; + } + } + + clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); + if (IS_ERR(clk_wzrd->clk_in1)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), + "clk_in1 not found\n"); + + clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clk_wzrd->axi_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), + "s_axi_aclk not found\n"); + rate = clk_get_rate(clk_wzrd->axi_clk); + if (rate > WZRD_ACLK_MAX_FREQ) { + dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate); + return -EINVAL; + } + + ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); + if (ret) + return ret; + clk_wzrd->clk_data.num = nr_outputs; ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, &clk_wzrd->clk_data); if (ret) { From patchwork Sat Aug 3 10:58:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752344 Received: from mail-40134.protonmail.ch (mail-40134.protonmail.ch [185.70.40.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DE7D14EC40; Sat, 3 Aug 2024 10:58:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682705; cv=none; b=sfQxlXswe9n4I0YGB1gwjNFSEae/MIbJGlZQ7a3WndPzOKu+JhIuw9XHI9HV/Qf+JWCRMK0fqY4hnYDHsByiTZhlBA7Ho7ISnd9xXOThAa2J+fJSoyGpXCNPJlt30JLbbMcZx5IsC8KgYum26oYxNF+bSxVzbhoy5PGAMK+C2L8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682705; c=relaxed/simple; bh=yHdo1T9SuZ+oYQAhZBz8Mjq2CUJJ2pBPOaEJLtJrgzk=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MuZepiulokeYCXhXfi+jb3/V5Qs268uyF71HG18soCnz6ngKjuwJoAKMQIrEvCj4vLbkP+f+I5L3WHCBDlOcNDlv3SzEDSpcMl3/2mzGngzqSTHS3SEOqfZepl1ot9SRKxTQcna58Q7UMOZqjPyBQd/ZhMW1/b/B5FpDCs6AilM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=CLLYDoMV; arc=none smtp.client-ip=185.70.40.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="CLLYDoMV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682702; x=1722941902; bh=8SUDarAKq4d9hQZ9wreu4NLDZENLtufrGVGAJEsJUYQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=CLLYDoMVIiQOnA2BcAvKjreA6fluldSGnx4JcXluGbKVKIYJciM0iRYgEeVh+d+ZR lsldEukuSq5UgFGJqSd0xbR4tKB4KGR4WbqcTdPheUFPP+0pmWymVeVZgAHZ7wad50 r0/ScEcKdcrq4sFcj2v2/9vtwUfvij9MQIfIvhaa+adqCwnGRZ/wtkZoDGXohY21SO 42qbpBAPCjOqXn2lwuOdlfg6wgBjt7RjvNhfUzod1YIAKwKBMkgmpouaE41/zn9k8g LA2EGPEQ96yPJA8bBq+8O5naLyVe65VLIgmuSzflxOqJQfMKSRTd3guh91MhT0O12h 0wztS3oNwGEFQ== Date: Sat, 03 Aug 2024 10:58:18 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 5/9] dt-bindings: clock: xilinx: add description of user monitor interrupt Message-ID: <20240803105702.9621-6-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: cc6f1df396aa2ef7de7db5590f55ebc7042936a5 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This Xilinx clocking wizard IP core outputs this interrupt signal to indicate when one of the four optional user clock inputs is either stopped, overruns, underruns or glitches. This functionality was only added from version 6.0 onwards, so restrict it to particular compatible strings. Signed-off-by: Harry Austen Reviewed-by: Krzysztof Kozlowski --- v1 -> v2: Fix binding errors by moving interrupts up front, restrict later .../bindings/clock/xlnx,clocking-wizard.yaml | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml index 9d5324dc1027a..9e5078cef2962 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml @@ -39,6 +39,14 @@ properties: - const: clk_in1 - const: s_axi_aclk + interrupts: + items: + - description: user clock monitor interrupt + + interrupt-names: + items: + - const: monitor + xlnx,speed-grade: $ref: /schemas/types.yaml#/definitions/uint32 @@ -62,17 +70,32 @@ required: - xlnx,speed-grade - xlnx,nr-outputs +allOf: + - if: + properties: + compatible: + enum: + - xlnx,clocking-wizard + - xlnx,clocking-wizard-v5.2 + then: + properties: + interrupts: false + interrupt-names: false + additionalProperties: false examples: - | + #include clock-controller@b0000000 { - compatible = "xlnx,clocking-wizard"; + compatible = "xlnx,clocking-wizard-v6.0"; reg = <0xb0000000 0x10000>; #clock-cells = <1>; xlnx,speed-grade = <1>; xlnx,nr-outputs = <6>; clock-names = "clk_in1", "s_axi_aclk"; clocks = <&clkc 15>, <&clkc 15>; + interrupts-extended = <&intc 52 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "monitor"; }; ... From patchwork Sat Aug 3 10:58:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752345 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73B0C1514C9 for ; Sat, 3 Aug 2024 10:58:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682711; cv=none; b=KhBG8SYu3N3xWMt0FmD8QjCuyx6+gSs5F1RG/Z4jD1oUXdZEcLBih4N6LzyMrWX8XdpwFPG8UdCXMmF6ttSCih2434hunXlZJbNlWlMmVEd40MU/9yHEJGGfAnfYRJQM+b3c065mvmoPrDmYmXWVP4biuZV/DMGctoZtTjz9GaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682711; c=relaxed/simple; bh=gvWrW/1wtge8jipyut5vNCvN2H6YSOziPTrjTVdSIWA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EoayBPfRoBQ9QEbLNsFOr9b5+0QDLD186W/xSWqkLhMajqk2uomA3f7jMuUa2g0Ne1OuJ94ksPxxtMFFx1UhHPlHD1wji9Mzkr0g6+A8igyIrohyccqUKchLl80HIO0nUSOdjpAAnKoQgn6NR/lp3E8rln51QZJhwr9j8+oo2aA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=KtgwXZRc; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="KtgwXZRc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682707; x=1722941907; bh=llyHHwAfUnsQLIATlG97RZG3ZZL4o5MlcbSrH2uwttg=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=KtgwXZRcvI58S6gOfvukZO9zhvLEuRtNpQVrE9J8XQNIjLKvXc+4CEiD+Nxh/HmMR glDD7qqvsGWhNVExbjIz7J0irBda6n0E55BqDYb1UajKCFpOl7bS+LNcC2cthNwPsP wzFyBZYSn8tp6D6CVcCnCasvEY2lJseFyE03ayO5bIxCV0dMXpUkQljYfgGYvYPc0g QxPQS1hxMGzTLE1EpkLjqDXwhYbRNz42L3MX1vOjasxf3eu+jHhwKXFRtIfxJLSXVD kbze4Ny2LdU85VhXjdodobsqsFGm6wLcUoIWGnzoATvV6biAn73ZnlNqtQk4a9kEw2 guYTJp2FUb+CQ== Date: Sat, 03 Aug 2024 10:58:24 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 6/9] clk: clocking-wizard: add user clock monitor support Message-ID: <20240803105702.9621-7-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 53032881eef22176f8403430de3565ccf3a6858e Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Xilinx clocking wizard IP core supports monitoring of up to four optional user clock inputs, with a corresponding interrupt for notification in change of clock state (stop, underrun, overrun or glitch). Give access to this monitor logic through use of an auxiliary device. Use presence of the user monitor interrupt description in devicetree to indicate whether or not the auxiliary device should be registered. Also, this functionality is only supported from v6.0 onwards, so add indication of support to the device match data, in order to be tied to the utilised compatible string. Signed-off-by: Harry Austen --- v1 -> v2: - Remove direct UIO dependency by utilising auxiliary device - Move some logic from probe into clk_wzrd_setup_monitor for tidiness drivers/clk/xilinx/Kconfig | 1 + drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 60 ++++++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/drivers/clk/xilinx/Kconfig b/drivers/clk/xilinx/Kconfig index 051756953558b..87f507bd9b6f3 100644 --- a/drivers/clk/xilinx/Kconfig +++ b/drivers/clk/xilinx/Kconfig @@ -21,6 +21,7 @@ config COMMON_CLK_XLNX_CLKWZRD tristate "Xilinx Clocking Wizard" depends on OF depends on HAS_IOMEM + select AUXILIARY_BUS help Support for the Xilinx Clocking Wizard IP core clock generator. Adds support for clocking wizard and compatible. diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 1f8023d24029f..557e11017faf9 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include @@ -129,6 +130,7 @@ enum clk_wzrd_int_clks { * @axi_clk: Handle to input clock 's_axi_aclk' * @clks_internal: Internal clocks * @speed_grade: Speed grade of the device + * @adev: User clock monitor auxiliary device * @suspended: Flag indicating power state of the device */ struct clk_wzrd { @@ -139,6 +141,7 @@ struct clk_wzrd { struct clk_hw *clks_internal[wzrd_clk_int_max]; unsigned int speed_grade; bool suspended; + struct auxiliary_device adev; struct clk_hw_onecell_data clk_data; }; @@ -171,8 +174,9 @@ struct clk_wzrd_divider { spinlock_t *lock; /* divider lock */ }; -struct versal_clk_data { +struct clk_wzrd_data { bool is_versal; + bool supports_monitor; }; #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb) @@ -958,16 +962,58 @@ static int __maybe_unused clk_wzrd_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend, clk_wzrd_resume); -static const struct versal_clk_data versal_data = { - .is_versal = true, +static const struct clk_wzrd_data version_6_0_data = { + .is_versal = false, + .supports_monitor = true, }; +static const struct clk_wzrd_data versal_data = { + .is_versal = true, + .supports_monitor = true, +}; + +static void clk_wzrd_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev = _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int clk_wzrd_setup_monitor(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct clk_wzrd_data *data = device_get_match_data(dev); + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); + struct auxiliary_device *adev = &clk_wzrd->adev; + int ret; + + if (!data || !data->supports_monitor) + return 0; + + adev->name = "clk-mon"; + adev->dev.parent = dev; + adev->dev.platform_data = (__force void *)clk_wzrd->base; + + ret = auxiliary_device_init(adev); + if (ret) + return ret; + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(dev, clk_wzrd_unregister_adev, adev); +} + static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs) { const char *clkout_name, *clk_name, *clk_mul_name; struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); u32 regl, regh, edge, regld, reghd, edged, div; - const struct versal_clk_data *data; + const struct clk_wzrd_data *data; unsigned long flags = 0; bool is_versal = false; void __iomem *ctrl_reg; @@ -1170,6 +1216,10 @@ static int clk_wzrd_probe(struct platform_device *pdev) return -EINVAL; } + ret = clk_wzrd_setup_monitor(pdev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to setup monitor\n"); + ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); if (ret) return ret; @@ -1204,7 +1254,7 @@ static const struct of_device_id clk_wzrd_ids[] = { { .compatible = "xlnx,versal-clk-wizard", .data = &versal_data }, { .compatible = "xlnx,clocking-wizard" }, { .compatible = "xlnx,clocking-wizard-v5.2" }, - { .compatible = "xlnx,clocking-wizard-v6.0" }, + { .compatible = "xlnx,clocking-wizard-v6.0", .data = &version_6_0_data }, { }, }; MODULE_DEVICE_TABLE(of, clk_wzrd_ids); From patchwork Sat Aug 3 10:58:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752346 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D39671514FD; Sat, 3 Aug 2024 10:58:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682716; cv=none; b=XCUzCy3+exmAixpW4Umv8+/Rj0l4A75ZcdLm3fWYl9fceTPGVV0CkT0fiC8DWcxWB47eihnT4QD05RVM8rJNx53si+96Y/dKwjzs810yvM5R2s0HOaIYijJxwg1SuPPcJBc627ZufPIeW5yMkuLrfNLWDOjJN0Uss+AQ/5Lq46c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682716; c=relaxed/simple; bh=TXYMxbNPrsq7kiuHy2+BGQkmZqtm/3pBLgdvU13PUmo=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Hs76dCDi6/VHXzQHv0INKhxqbwk6FajqMuvp2CkKZSh7sLNib93LZy/jiodXGj5uBJUdIT92CPkM72o8fslgIsySEo+2GFrtclH8MyMv2eDWzQnsSHxPpL0lS5KK/Yno/u+5pMPxWfBIcvaG/ZYColbGhbud8xA1PGkPjwrWxDw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=Nmz1OsC5; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="Nmz1OsC5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682712; x=1722941912; bh=J5O0WfbkON8VHuSeGepk1ISC6Og/9F2pK8v9QAkqW4E=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=Nmz1OsC5UciTfdkZib6DCWz4ljkmRhAwotXfEc7GB2UdkMFf4/JCT/bN7glNA6BSk /MtLk9uwpOow4ixZb0LA6ZEn3iHc3/TiaSbzE0QPJkb+atozA5+6k4RPbrt4mcsuh2 3b95nAnWUyWp8V7tty+Kqqe8h40mtcTVcBvL151eYxLhxDd0JD5DkMA70VS20JLgqC PLe39NhCy6D02DlsEC3LV/pAvitKdxMb9UpTNvlNDK/l7lOVrxryKObjNhkenUiNHH t5S0QAcgk52SfRmPOHc+Oasd2e+pEJVrXAEwK4j3zJ3b6EAPKf8tlKlhM4FWCVfJfG 9gUIcT5VJGv8A== Date: Sat, 03 Aug 2024 10:58:30 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 7/9] uio: add Xilinx user clock monitor support Message-ID: <20240803105702.9621-8-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 0bc1fe7a2cd4c4d3c0a7304955c8869d91c4b6f4 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Xilinx clocking wizard IP core supports monitoring of up to four optional user clock inputs, with a corresponding interrupt for notification in change of clock state (stop, underrun, overrun or glitch). Give userspace access to this monitor logic through use of the UIO framework. Implemented as an auxiliary_driver to avoid introducing UIO dependency to the main clock driver. Signed-off-by: Harry Austen --- v1 -> v2: New drivers/uio/Kconfig | 8 ++++ drivers/uio/Makefile | 1 + drivers/uio/uio_xlnx_clk_mon.c | 71 ++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 drivers/uio/uio_xlnx_clk_mon.c diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index b060dcd7c6350..ca8a53de26a67 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig @@ -164,4 +164,12 @@ config UIO_DFL opae-sdk/tools/libopaeuio/ If you compile this as a module, it will be called uio_dfl. + +config UIO_XLNX_CLK_MON + tristate "Xilinx user clock monitor support" + depends on COMMON_CLK_XLNX_CLKWZRD + help + Userspace I/O interface to the user clock monitor logic within the + Xilinx Clocking Wizard IP core. + endif diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index 1c5f3b5a95cf5..1e8c242265431 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_UIO_MF624) += uio_mf624.o obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o obj-$(CONFIG_UIO_HV_GENERIC) += uio_hv_generic.o obj-$(CONFIG_UIO_DFL) += uio_dfl.o +obj-$(CONFIG_UIO_XLNX_CLK_MON) += uio_xlnx_clk_mon.o diff --git a/drivers/uio/uio_xlnx_clk_mon.c b/drivers/uio/uio_xlnx_clk_mon.c new file mode 100644 index 0000000000000..afcbeae98eaaf --- /dev/null +++ b/drivers/uio/uio_xlnx_clk_mon.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for user clock monitor logic within Xilinx 'Clocking Wizard' IP core + * + * Copyright (C) 2024 Harry Austen + */ + +#include +#include +#include +#include +#include +#include + +#define WZRD_INTR_ENABLE 0x10 + +static int clk_mon_irqcontrol(struct uio_info *info, s32 irq_on) +{ + if (irq_on) + iowrite32(GENMASK(15, 0), info->mem[0].internal_addr + WZRD_INTR_ENABLE); + else + iowrite32(0, info->mem[0].internal_addr + WZRD_INTR_ENABLE); + + return 0; +} + +static int probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) +{ + struct platform_device *pdev = to_platform_device(adev->dev.parent); + struct device *dev = &adev->dev; + struct uio_info *info; + int irq; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return 0; + + info->name = KBUILD_MODNAME; + info->version = "0.0.1"; + + info->mem[0].name = "clock monitor"; + info->mem[0].memtype = UIO_MEM_PHYS; + info->mem[0].addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; + info->mem[0].size = (WZRD_INTR_ENABLE + 4 + PAGE_SIZE - 1) & PAGE_MASK; + info->mem[0].internal_addr = (__force void __iomem *)dev->platform_data; + + info->irq = irq; + info->irqcontrol = clk_mon_irqcontrol; + return devm_uio_register_device(dev, info); +} + +static struct auxiliary_device_id ids[] = { + { .name = "clk_xlnx_clock_wizard.clk-mon" }, + {} +}; +MODULE_DEVICE_TABLE(auxiliary, ids); + +static struct auxiliary_driver xlnx_clk_mon_driver = { + .id_table = ids, + .probe = probe, +}; + +module_auxiliary_driver(xlnx_clk_mon_driver); + +MODULE_AUTHOR("Harry Austen "); +MODULE_DESCRIPTION("Driver for Xilinx user clock monitor logic"); +MODULE_LICENSE("GPL"); From patchwork Sat Aug 3 10:58:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752347 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B83714D2B5 for ; Sat, 3 Aug 2024 10:58:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682725; cv=none; b=o7OjpWvrYmTX4KafLuB2TvaB7emYhNi7ZulmrNNZv0aDXQbFvvI4JCfuuoYuI3QIcopvcTJ5qZDV3F3dA7hBpAUK6JX7w3LDubDeHpgVdoxH6t4UuHDEPrDlGbI+YnDCbMjDgoGVpmBJ/Y+GdaFmW+GBeNZsKPn/eA3qC+Nb8Dg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682725; c=relaxed/simple; bh=EBCRVfZznRXJg7v+5Ar3qMNV55WvBT1KwUlciYgpqVA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=To/LMGCqPxXiBaOYHIYCn1BJ29aUGw28J9E7saZ01bX49Xy02tsXFTKWnk+ItPo+J+tHXQypjXIsiSbHPVDiZpuWeWBEAsdgIAeKmet9CCLUIX3RGdNh1qlroLd7nL0aKptoy9ACGauxJphHOtTVoosspi5CSHB7uAzktBfO8Ak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=mGa6OwPc; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="mGa6OwPc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682722; x=1722941922; bh=L8IlsP2aPV2YpmlTJK6/jkHvyJCmhcqNmn7zjirm4mU=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=mGa6OwPcgWh/b+Vhs6jCYkRHtnie9C9R/Mf9kZL+k32epSr1Pv8PeMCkNtKPS1fV+ PDl96eqPMnZIPPyYFLAegyKpPwbGblOFiuKBJYBj8IpZh8RTyD8o2WuKzMrneDk3vP 71NK/2L1mt3abu0atpaMY3Gj5cPm29mTt7FHgTnLAFy4epRJgYTagjN/+Jx6Avd0z1 g1lDkuP9WHr3UpyF1noAHC9PSVaEGGgC4EHMzcB9qBOm7HY7iprkOl5oSPlSTixp6z ejPYxDK4W3AH9AqZ5KT2PdDRpl1kxaR3gwQ3JQHPMifKrQQd/uXrEwS0vmLFUxZkIb T2au5yPHaOIig== Date: Sat, 03 Aug 2024 10:58:38 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 8/9] dt-bindings: clock: xilinx: describe whether dynamic reconfig is enabled Message-ID: <20240803105702.9621-9-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 26a9b51b5d389d6e469395ce25f5ff994c41be71 Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Xilinx clocking wizard IP core's dynamic reconfiguration support is optionally enabled at build time. Add a devicetree boolean property to describe whether the hardware supports this feature or not. Signed-off-by: Harry Austen Acked-by: Krzysztof Kozlowski --- v1 -> v2: Use "flag" instead of boolean type .../devicetree/bindings/clock/xlnx,clocking-wizard.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml index 9e5078cef2962..8b28a01dbb993 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml @@ -48,6 +48,12 @@ properties: - const: monitor + xlnx,dynamic-reconfig: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicate whether the core has been configured with support for dynamic + runtime reconfguration of the clocking primitive MMCM/PLL. + xlnx,speed-grade: $ref: /schemas/types.yaml#/definitions/uint32 enum: [1, 2, 3] @@ -91,6 +97,7 @@ examples: compatible = "xlnx,clocking-wizard-v6.0"; reg = <0xb0000000 0x10000>; #clock-cells = <1>; + xlnx,dynamic-reconfig; xlnx,speed-grade = <1>; xlnx,nr-outputs = <6>; clock-names = "clk_in1", "s_axi_aclk"; From patchwork Sat Aug 3 10:58:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Austen X-Patchwork-Id: 13752348 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50F1914D702; Sat, 3 Aug 2024 10:58:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682730; cv=none; b=nig1c/dwy/UYBplYiVcAl+thtoCVqewvQzDJJ49NgUuyk9jnH559AApgiOLnO0CYxDXDICKazGdlkYgOJ7OIE/6R5KtNZCxwwrlNROLfdvck7hd1apWo9ocPPJXpJ9spybu271/hj8m9Dajv/WRa7B8z9ONE/L2iyHG5keSMSII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722682730; c=relaxed/simple; bh=+2Ps0RkWvd4hA5xbknz9GXhP/fqeSiFOTT6hvj1HlSY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nhRkRL2Gwv9iuCSxgmUg3MNwwpCKBOgrXddTQbnfV1lTmUAomJjzK1wsWpJuga2sWl6eBRK2x7cpVZlgafYBPaAflIFyrTPgQYpf2EXFnlQqWPH49ZCj3AEgwNQ+MAcpMm2YbRWaTtvO4OZc8udZjvG+Rxsc1yF5ECqFjGE342k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com; spf=pass smtp.mailfrom=protonmail.com; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b=CONJO6R8; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=protonmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=protonmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="CONJO6R8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1722682726; x=1722941926; bh=0H2g73lUPxVU1hWK6gZKi285FJE1qovcLzfd2WX0+uE=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=CONJO6R8fF9XsX3qremVKWzb1WTgZAho8oQnYriBXxuVeBM2jnxqf1ArH4mEOjyR0 KHHYJaGAfYCOSih662ri1L4oFylwwe2ITNlpWDc88CkKdsyZTAiSufE+6eZIhguh8L eq7mZLnF836BbB35EqedsbfloTvB/bMQcM9mxUTojKARkZaMLXnlh1uc5x3cVdvmQb L4Hn7OCWbJ9Su8ZIzc04UlV4XB0HyokI4dBwNdTdCvT9BF0qp/nptdc/tHRsUW/bh5 xep/0GPf674cfporFewBA5llcBxcm+KbS07ZSYSQd0yFkLpIZ1hDFJ5SpyPrXAeIP7 AEJpS81s1lOTw== Date: Sat, 03 Aug 2024 10:58:43 +0000 To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Michal Simek , Greg Kroah-Hartman From: Harry Austen Cc: Shubhrajyoti Datta , Dave Ertman , Ira Weiny , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Harry Austen Subject: [PATCH v2 9/9] clk: clocking-wizard: move dynamic reconfig setup behind flag Message-ID: <20240803105702.9621-10-hpausten@protonmail.com> In-Reply-To: <20240803105702.9621-1-hpausten@protonmail.com> References: <20240803105702.9621-1-hpausten@protonmail.com> Feedback-ID: 53116287:user:proton X-Pm-Message-ID: 25c4f45d44befa37fd567ea85bd876fa56719a8e Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Xilinx clocking wizard IP core's dynamic reconfiguration support is optionally enabled at build time. Use the new boolean devicetree property to indicate whether the hardware supports this feature or not. Signed-off-by: Harry Austen --- v1 -> v2: No functional change drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 73 +++++++++++----------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 557e11017faf9..fb655d53b2029 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -1192,20 +1192,6 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (IS_ERR(clk_wzrd->base)) return PTR_ERR(clk_wzrd->base); - ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); - if (!ret) { - if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { - dev_warn(&pdev->dev, "invalid speed grade '%d'\n", - clk_wzrd->speed_grade); - clk_wzrd->speed_grade = 0; - } - } - - clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); - if (IS_ERR(clk_wzrd->clk_in1)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), - "clk_in1 not found\n"); - clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); if (IS_ERR(clk_wzrd->axi_clk)) return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), @@ -1220,31 +1206,48 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (ret) return dev_err_probe(&pdev->dev, ret, "failed to setup monitor\n"); - ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); - if (ret) - return ret; - - clk_wzrd->clk_data.num = nr_outputs; - ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, &clk_wzrd->clk_data); - if (ret) { - dev_err(&pdev->dev, "unable to register clock provider\n"); - return ret; - } + if (of_property_read_bool(np, "xlnx,dynamic-reconfig")) { + ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); + if (!ret) { + if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { + dev_warn(&pdev->dev, "invalid speed grade '%d'\n", + clk_wzrd->speed_grade); + clk_wzrd->speed_grade = 0; + } + } - if (clk_wzrd->speed_grade) { - clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; + clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); + if (IS_ERR(clk_wzrd->clk_in1)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), + "clk_in1 not found\n"); - ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1, - &clk_wzrd->nb); + ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); if (ret) - dev_warn(&pdev->dev, - "unable to register clock notifier\n"); + return ret; + + clk_wzrd->clk_data.num = nr_outputs; + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, + &clk_wzrd->clk_data); + if (ret) { + dev_err(&pdev->dev, "unable to register clock provider\n"); + return ret; + } - ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk, - &clk_wzrd->nb); - if (ret) - dev_warn(&pdev->dev, - "unable to register clock notifier\n"); + if (clk_wzrd->speed_grade) { + clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; + + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + } } return 0;