Skip to content

Commit 55a669e

Browse files
committed
pwm: axi-pwmgen: fix missing separate external clock
Add proper support for external clock to the AXI PWM generator driver. In most cases, the HDL for this IP block is compiled with the default ASYNC_CLK_EN=1. With this option, there is a separate external clock that drives the PWM output separate from the peripheral clock. So the driver should be enabling the "axi" clock to power the peripheral and the "ext" clock to drive the PWM output. When ASYNC_CLK_EN=0, the "axi" clock is also used to drive the PWM output and there is no "ext" clock. Previously, if there was a separate external clock, users had to specify only the external clock and (incorrectly) omit the AXI clock in order to get the correct operating frequency for the PWM output. The devicetree bindings are updated to fix this shortcoming and this patch changes the driver to match the new bindings. To preserve compatibility with any existing dtbs that specify only one clock, we don't require the clock name on the first clock. Fixes: 41814fe ("pwm: Add driver for AXI PWM generator") Cc: stable@vger.kernel.org Acked-by: Nuno Sá <nuno.sa@analog.com> Reviewed-by: Trevor Gamblin <tgamblin@baylibre.com> Signed-off-by: David Lechner <dlechner@baylibre.com> Link: https://lore.kernel.org/r/20250529-pwm-axi-pwmgen-add-external-clock-v3-3-5d8809a7da91@baylibre.com Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org> (cherry picked from commit a8841dc) Signed-off-by: David Lechner <dlechner@baylibre.com>
1 parent ee2645e commit 55a669e

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

drivers/pwm/pwm-axi-pwmgen.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
253253
struct regmap *regmap;
254254
struct pwm_chip *chip;
255255
struct axi_pwmgen_ddata *ddata;
256-
struct clk *clk;
256+
struct clk *axi_clk, *clk;
257257
void __iomem *io_base;
258258
int ret;
259259

@@ -276,9 +276,26 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
276276
ddata = pwmchip_get_drvdata(chip);
277277
ddata->regmap = regmap;
278278

279-
clk = devm_clk_get_enabled(dev, NULL);
279+
/*
280+
* Using NULL here instead of "axi" for backwards compatibility. There
281+
* are some dtbs that don't give clock-names and have the "ext" clock
282+
* as the one and only clock (due to mistake in the original bindings).
283+
*/
284+
axi_clk = devm_clk_get_enabled(dev, NULL);
285+
if (IS_ERR(axi_clk))
286+
return dev_err_probe(dev, PTR_ERR(axi_clk), "failed to get axi clock\n");
287+
288+
clk = devm_clk_get_optional_enabled(dev, "ext");
280289
if (IS_ERR(clk))
281-
return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n");
290+
return dev_err_probe(dev, PTR_ERR(clk), "failed to get ext clock\n");
291+
292+
/*
293+
* If there is no "ext" clock, it means the HDL was compiled with
294+
* ASYNC_CLK_EN=0. In this case, the AXI clock is also used for the
295+
* PWM output clock.
296+
*/
297+
if (!clk)
298+
clk = axi_clk;
282299

283300
ret = devm_clk_rate_exclusive_get(dev, clk);
284301
if (ret)

0 commit comments

Comments
 (0)