From: Andre Przywara <andre.przywara@arm.com> To: Yangtao Li <tiny.windzz@gmail.com>, Viresh Kumar <vireshk@kernel.org>, Nishanth Menon <nm@ti.com>, Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Conor Dooley <conor+dt@kernel.org>, Chen-Yu Tsai <wens@csie.org>, Jernej Skrabec <jernej.skrabec@gmail.com>, Samuel Holland <samuel@sholland.org>, "Rafael J . Wysocki" <rafael@kernel.org> Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Brandon Cheo Fusi <fusibrandon13@gmail.com>, Martin Botka <martin.botka@somainline.org>, Martin Botka <martin.botka1@gmail.com>, Chris Morgan <macroalpha82@gmail.com>, Ryan Walklin <ryan@testtoast.com> Subject: [PATCH v3 5/8] cpufreq: sun50i: Add support for opp_supported_hw Date: Tue, 26 Mar 2024 11:47:40 +0000 [thread overview] Message-ID: <20240326114743.712167-6-andre.przywara@arm.com> (raw) In-Reply-To: <20240326114743.712167-1-andre.przywara@arm.com> The opp_supported_hw DT property allows the DT to specify a mask of chip revisions that a certain OPP is eligible for. This allows for easy limiting of maximum frequencies, for instance. Add support for that in the sun50i-cpufreq-nvmem driver. We support both the existing opp-microvolt suffix properties as well as the opp-supported-hw property, the generic code figures out which is needed automatically. However if none of the DT OPP nodes contain an opp-supported-hw property, the core code will ignore all OPPs and the driver will fail probing. So check the DT's eligibility first before using that feature. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- drivers/cpufreq/sun50i-cpufreq-nvmem.c | 62 ++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 7b44f3b13e7d2..bd170611c7906 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -57,6 +57,41 @@ static const struct of_device_id cpu_opp_match_list[] = { {} }; +/** + * dt_has_supported_hw() - Check if any OPPs use opp-supported-hw + * + * If we ask the cpufreq framework to use the opp-supported-hw feature, it + * will ignore every OPP node without that DT property. If none of the OPPs + * have it, the driver will fail probing, due to the lack of OPPs. + * + * Returns true if we have at least one OPP with the opp-supported-hw property. + */ +static bool dt_has_supported_hw(void) +{ + bool has_opp_supported_hw = false; + struct device_node *np, *opp; + struct device *cpu_dev; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) + return -ENODEV; + + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) + return -ENOENT; + + for_each_child_of_node(np, opp) { + if (of_find_property(opp, "opp-supported-hw", NULL)) { + has_opp_supported_hw = true; + break; + } + } + + of_node_put(np); + + return has_opp_supported_hw; +} + /** * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value * @@ -110,7 +145,8 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) { int *opp_tokens; char name[MAX_NAME_LEN]; - unsigned int cpu; + unsigned int cpu, supported_hw; + struct dev_pm_opp_config config = {}; int speed; int ret; @@ -125,7 +161,18 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) return speed; } + /* + * We need at least one OPP with the "opp-supported-hw" property, + * or else the upper layers will ignore every OPP and will bail out. + */ + if (dt_has_supported_hw()) { + supported_hw = 1U << speed; + config.supported_hw = &supported_hw; + config.supported_hw_count = 1; + } + snprintf(name, MAX_NAME_LEN, "speed%d", speed); + config.prop_name = name; for_each_possible_cpu(cpu) { struct device *cpu_dev = get_cpu_device(cpu); @@ -135,12 +182,11 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) goto free_opp; } - opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name); - if (opp_tokens[cpu] < 0) { - ret = opp_tokens[cpu]; - pr_err("Failed to set prop name\n"); + ret = dev_pm_opp_set_config(cpu_dev, &config); + if (ret < 0) goto free_opp; - } + + opp_tokens[cpu] = ret; } cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, @@ -155,7 +201,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) free_opp: for_each_possible_cpu(cpu) - dev_pm_opp_put_prop_name(opp_tokens[cpu]); + dev_pm_opp_clear_config(opp_tokens[cpu]); kfree(opp_tokens); return ret; @@ -169,7 +215,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev) platform_device_unregister(cpufreq_dt_pdev); for_each_possible_cpu(cpu) - dev_pm_opp_put_prop_name(opp_tokens[cpu]); + dev_pm_opp_clear_config(opp_tokens[cpu]); kfree(opp_tokens); } -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Andre Przywara <andre.przywara@arm.com> To: Yangtao Li <tiny.windzz@gmail.com>, Viresh Kumar <vireshk@kernel.org>, Nishanth Menon <nm@ti.com>, Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Conor Dooley <conor+dt@kernel.org>, Chen-Yu Tsai <wens@csie.org>, Jernej Skrabec <jernej.skrabec@gmail.com>, Samuel Holland <samuel@sholland.org>, "Rafael J . Wysocki" <rafael@kernel.org> Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Brandon Cheo Fusi <fusibrandon13@gmail.com>, Martin Botka <martin.botka@somainline.org>, Martin Botka <martin.botka1@gmail.com>, Chris Morgan <macroalpha82@gmail.com>, Ryan Walklin <ryan@testtoast.com> Subject: [PATCH v3 5/8] cpufreq: sun50i: Add support for opp_supported_hw Date: Tue, 26 Mar 2024 11:47:40 +0000 [thread overview] Message-ID: <20240326114743.712167-6-andre.przywara@arm.com> (raw) In-Reply-To: <20240326114743.712167-1-andre.przywara@arm.com> The opp_supported_hw DT property allows the DT to specify a mask of chip revisions that a certain OPP is eligible for. This allows for easy limiting of maximum frequencies, for instance. Add support for that in the sun50i-cpufreq-nvmem driver. We support both the existing opp-microvolt suffix properties as well as the opp-supported-hw property, the generic code figures out which is needed automatically. However if none of the DT OPP nodes contain an opp-supported-hw property, the core code will ignore all OPPs and the driver will fail probing. So check the DT's eligibility first before using that feature. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- drivers/cpufreq/sun50i-cpufreq-nvmem.c | 62 ++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 7b44f3b13e7d2..bd170611c7906 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -57,6 +57,41 @@ static const struct of_device_id cpu_opp_match_list[] = { {} }; +/** + * dt_has_supported_hw() - Check if any OPPs use opp-supported-hw + * + * If we ask the cpufreq framework to use the opp-supported-hw feature, it + * will ignore every OPP node without that DT property. If none of the OPPs + * have it, the driver will fail probing, due to the lack of OPPs. + * + * Returns true if we have at least one OPP with the opp-supported-hw property. + */ +static bool dt_has_supported_hw(void) +{ + bool has_opp_supported_hw = false; + struct device_node *np, *opp; + struct device *cpu_dev; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) + return -ENODEV; + + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) + return -ENOENT; + + for_each_child_of_node(np, opp) { + if (of_find_property(opp, "opp-supported-hw", NULL)) { + has_opp_supported_hw = true; + break; + } + } + + of_node_put(np); + + return has_opp_supported_hw; +} + /** * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value * @@ -110,7 +145,8 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) { int *opp_tokens; char name[MAX_NAME_LEN]; - unsigned int cpu; + unsigned int cpu, supported_hw; + struct dev_pm_opp_config config = {}; int speed; int ret; @@ -125,7 +161,18 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) return speed; } + /* + * We need at least one OPP with the "opp-supported-hw" property, + * or else the upper layers will ignore every OPP and will bail out. + */ + if (dt_has_supported_hw()) { + supported_hw = 1U << speed; + config.supported_hw = &supported_hw; + config.supported_hw_count = 1; + } + snprintf(name, MAX_NAME_LEN, "speed%d", speed); + config.prop_name = name; for_each_possible_cpu(cpu) { struct device *cpu_dev = get_cpu_device(cpu); @@ -135,12 +182,11 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) goto free_opp; } - opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name); - if (opp_tokens[cpu] < 0) { - ret = opp_tokens[cpu]; - pr_err("Failed to set prop name\n"); + ret = dev_pm_opp_set_config(cpu_dev, &config); + if (ret < 0) goto free_opp; - } + + opp_tokens[cpu] = ret; } cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, @@ -155,7 +201,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) free_opp: for_each_possible_cpu(cpu) - dev_pm_opp_put_prop_name(opp_tokens[cpu]); + dev_pm_opp_clear_config(opp_tokens[cpu]); kfree(opp_tokens); return ret; @@ -169,7 +215,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev) platform_device_unregister(cpufreq_dt_pdev); for_each_possible_cpu(cpu) - dev_pm_opp_put_prop_name(opp_tokens[cpu]); + dev_pm_opp_clear_config(opp_tokens[cpu]); kfree(opp_tokens); } -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-03-26 11:48 UTC|newest] Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-03-26 11:47 [PATCH v3 0/8] cpufreq: sun50i: Add Allwinner H616 support Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-26 11:47 ` [PATCH v3 1/8] firmware: smccc: Export revision soc_id function Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-26 13:18 ` Sudeep Holla 2024-03-26 13:18 ` Sudeep Holla 2024-03-26 11:47 ` [PATCH v3 2/8] cpufreq: dt-platdev: Blocklist Allwinner H616/618 SoCs Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-27 20:57 ` Jernej Škrabec 2024-03-27 20:57 ` Jernej Škrabec 2024-03-26 11:47 ` [PATCH v3 3/8] dt-bindings: opp: Describe H616 OPPs and opp-supported-hw Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-26 21:37 ` Rob Herring 2024-03-26 21:37 ` Rob Herring 2024-03-26 11:47 ` [PATCH v3 4/8] cpufreq: sun50i: Refactor speed bin decoding Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-27 21:19 ` Jernej Škrabec 2024-03-27 21:19 ` Jernej Škrabec 2024-03-26 11:47 ` Andre Przywara [this message] 2024-03-26 11:47 ` [PATCH v3 5/8] cpufreq: sun50i: Add support for opp_supported_hw Andre Przywara 2024-03-27 21:20 ` Jernej Škrabec 2024-03-27 21:20 ` Jernej Škrabec 2024-03-26 11:47 ` [PATCH v3 6/8] cpufreq: sun50i: Add H616 support Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-27 3:46 ` Samuel Holland 2024-03-27 3:46 ` Samuel Holland 2024-03-27 11:46 ` Andre Przywara 2024-03-27 11:46 ` Andre Przywara 2024-03-27 11:58 ` Sudeep Holla 2024-03-27 11:58 ` Sudeep Holla 2024-03-27 12:01 ` Sudeep Holla 2024-03-27 12:01 ` Sudeep Holla 2024-03-27 12:16 ` Andre Przywara 2024-03-27 12:16 ` Andre Przywara 2024-03-26 11:47 ` [PATCH v3 7/8] arm64: dts: allwinner: h616: Add CPU OPPs table Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-27 21:24 ` Jernej Škrabec 2024-03-27 21:24 ` Jernej Škrabec 2024-03-26 11:47 ` [PATCH v3 8/8] arm64: dts: allwinner: h616: enable DVFS for all boards Andre Przywara 2024-03-26 11:47 ` Andre Przywara 2024-03-27 21:25 ` Jernej Škrabec 2024-03-27 21:25 ` Jernej Škrabec
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240326114743.712167-6-andre.przywara@arm.com \ --to=andre.przywara@arm.com \ --cc=conor+dt@kernel.org \ --cc=devicetree@vger.kernel.org \ --cc=fusibrandon13@gmail.com \ --cc=jernej.skrabec@gmail.com \ --cc=krzysztof.kozlowski+dt@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-pm@vger.kernel.org \ --cc=linux-sunxi@lists.linux.dev \ --cc=macroalpha82@gmail.com \ --cc=martin.botka1@gmail.com \ --cc=martin.botka@somainline.org \ --cc=nm@ti.com \ --cc=rafael@kernel.org \ --cc=robh+dt@kernel.org \ --cc=ryan@testtoast.com \ --cc=samuel@sholland.org \ --cc=sboyd@kernel.org \ --cc=tiny.windzz@gmail.com \ --cc=vireshk@kernel.org \ --cc=wens@csie.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.