Skip to content

Commit a8841dc

Browse files
dlechUwe Kleine-König
authored andcommitted
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: [email protected] Acked-by: Nuno Sá <[email protected]> Reviewed-by: Trevor Gamblin <[email protected]> Signed-off-by: David Lechner <[email protected]> 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 <[email protected]>
1 parent e683131 commit a8841dc

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
@@ -257,7 +257,7 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
257257
struct regmap *regmap;
258258
struct pwm_chip *chip;
259259
struct axi_pwmgen_ddata *ddata;
260-
struct clk *clk;
260+
struct clk *axi_clk, *clk;
261261
void __iomem *io_base;
262262
int ret;
263263

@@ -280,9 +280,26 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
280280
ddata = pwmchip_get_drvdata(chip);
281281
ddata->regmap = regmap;
282282

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

287304
ret = devm_clk_rate_exclusive_get(dev, clk);
288305
if (ret)

0 commit comments

Comments
 (0)