From d6bf1d39c3413a44712cba461d47d31e0cec51d7 Mon Sep 17 00:00:00 2001 From: Yi-Wei Wang Date: Wed, 1 Jul 2026 12:20:32 +0900 Subject: [PATCH] pwm: tegra: Avoid hard-coded max clock frequency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clock driving the Tegra PWM IP can be sourced from different parent clocks. Hence, let dev_pm_opp_set_rate() set the max clock rate based upon the current parent clock that can be specified via device-tree. After this, the Tegra194 SoC data becomes redundant, so get rid of it. Signed-off-by: Yi-Wei Wang Reviewed-by: Thierry Reding Co-developed-by: Mikko Perttunen Signed-off-by: Mikko Perttunen Tested-by: Jon Hunter Reviewed-by: Jon Hunter Link: https://patch.msgid.link/20260701-t264-pwm-v6-3-2718f61f411f@nvidia.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-tegra.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index f8c5495a56a6..3eef299c51f8 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -59,9 +59,6 @@ struct tegra_pwm_soc { unsigned int num_channels; - - /* Maximum IP frequency for given SoCs */ - unsigned long max_frequency; }; struct tegra_pwm_chip { @@ -303,7 +300,7 @@ static int tegra_pwm_probe(struct platform_device *pdev) return ret; /* Set maximum frequency of the IP */ - ret = dev_pm_opp_set_rate(&pdev->dev, pc->soc->max_frequency); + ret = dev_pm_opp_set_rate(&pdev->dev, ULONG_MAX); if (ret < 0) { dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret); goto put_pm; @@ -315,10 +312,15 @@ static int tegra_pwm_probe(struct platform_device *pdev) * so that PWM period can be calculated more accurately. */ pc->clk_rate = clk_get_rate(pc->clk); + if (pc->clk_rate < (1 << TEGRA_PWM_DUTY_WIDTH)) { + dev_err(&pdev->dev, "clock maximum frequency out of range\n"); + ret = -ERANGE; + goto put_pm; + } /* Set minimum limit of PWM period for the IP */ pc->min_period_ns = - (NSEC_PER_SEC / (pc->soc->max_frequency >> TEGRA_PWM_DUTY_WIDTH)) + 1; + (NSEC_PER_SEC / (pc->clk_rate >> TEGRA_PWM_DUTY_WIDTH)) + 1; pc->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm"); if (IS_ERR(pc->rst)) { @@ -397,23 +399,16 @@ static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev) static const struct tegra_pwm_soc tegra20_pwm_soc = { .num_channels = 4, - .max_frequency = 48000000UL, }; static const struct tegra_pwm_soc tegra186_pwm_soc = { .num_channels = 1, - .max_frequency = 102000000UL, -}; - -static const struct tegra_pwm_soc tegra194_pwm_soc = { - .num_channels = 1, - .max_frequency = 408000000UL, }; static const struct of_device_id tegra_pwm_of_match[] = { { .compatible = "nvidia,tegra20-pwm", .data = &tegra20_pwm_soc }, { .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc }, - { .compatible = "nvidia,tegra194-pwm", .data = &tegra194_pwm_soc }, + { .compatible = "nvidia,tegra194-pwm", .data = &tegra186_pwm_soc }, { } }; MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);