Re: [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe()
From: Nuno Sá
Date: Fri Nov 06 2026 - 08:02:16 EST
On Thu, Nov 05, 2026 at 02:38:06PM +0000, Lee Jones wrote:
> axi_pwmgen_probe() calls axi_pwmgen_setup(), which reads and writes MMIO
> registers to verify the IP core version and determine the channel count,
> before acquiring and enabling axi_clk. If the bootloader leaves the AXI
> peripheral clock gated, accessing the registers causes an unclocked bus
> access fault.
>
> Acquire and enable the clocks before calling axi_pwmgen_setup().
>
> Fixes: 41814fe5c782 ("pwm: Add driver for AXI PWM generator")
> Closes: https://sashiko.dev/#/bug/linux-bc988dbc-7b12-4785-a164-b6dcab29b86a
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
> ---
FWIW, I think this is a valid fix. Likely never happens because the AXI
clock is mostly "assumed enabled" but we already had some edge cases in
other cores related to not having the clock enabled. Anyways, LGTM:
Reviewed-by: Nuno Sá <nuno.sa@xxxxxxxxxx>
> drivers/pwm/pwm-axi-pwmgen.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/pwm/pwm-axi-pwmgen.c b/drivers/pwm/pwm-axi-pwmgen.c
> index b40522f01002..7c1b38124787 100644
> --- a/drivers/pwm/pwm-axi-pwmgen.c
> +++ b/drivers/pwm/pwm-axi-pwmgen.c
> @@ -270,16 +270,6 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
> return dev_err_probe(dev, PTR_ERR(regmap),
> "failed to init register map\n");
>
> - ret = axi_pwmgen_setup(regmap, dev);
> - if (ret < 0)
> - return ret;
> -
> - chip = devm_pwmchip_alloc(dev, ret, sizeof(*ddata));
> - if (IS_ERR(chip))
> - return PTR_ERR(chip);
> - ddata = pwmchip_get_drvdata(chip);
> - ddata->regmap = regmap;
> -
> /*
> * Using NULL here instead of "axi" for backwards compatibility. There
> * are some dtbs that don't give clock-names and have the "ext" clock
> @@ -305,6 +295,16 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
> if (ret)
> return dev_err_probe(dev, ret, "failed to get exclusive rate\n");
>
> + ret = axi_pwmgen_setup(regmap, dev);
> + if (ret < 0)
> + return ret;
> +
> + chip = devm_pwmchip_alloc(dev, ret, sizeof(*ddata));
> + if (IS_ERR(chip))
> + return PTR_ERR(chip);
> + ddata = pwmchip_get_drvdata(chip);
> + ddata->regmap = regmap;
> +
> ddata->clk_rate_hz = clk_get_rate(clk);
> if (!ddata->clk_rate_hz || ddata->clk_rate_hz > NSEC_PER_SEC)
> return dev_err_probe(dev, -EINVAL,
> Cc: Drew Fustini <dfustini@xxxxxxxxxxxx>
> --
> 2.56.0.398.g882cbad275-goog
>