The following commit
abf6569d6482 ("pwm: imx-tpm: Make use of
devm_pwmchip_alloc() function") introduced an issue that accessing
registers without clock which results in the following boot crash
on MX7ULP platform. Fixed it by enabling clock properly.
Unhandled fault: external abort on non-linefetch (0x1008) at 0xf0978004
[
f0978004] *pgd=
64009811, *pte=
40250653, *ppte=
40250453
Internal error: : 1008 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc6-next-
20240301 #18
Hardware name: Freescale i.MX7ULP (Device Tree)
PC is at pwm_imx_tpm_probe+0x1c/0xd8
LR is at __devm_ioremap_resource+0xf8/0x1dc
pc : [<
c0629e58>] lr : [<
c0562d4c>] psr:
80000053
sp :
f0825e10 ip :
00000000 fp :
00000000
r10:
c148f8c0 r9 :
c41fc338 r8 :
c164b000
r7 :
00000000 r6 :
c406b400 r5 :
c406b410 r4 :
f0978000
r3 :
00000005 r2 :
00000000 r1 :
a0000053 r0 :
f0978000
Flags: Nzcv IRQs on FIQs off Mode SVC_32 ISA ARM Segment none
Control:
10c5387d Table:
6000406a DAC:
00000051
...
Call trace:
pwm_imx_tpm_probe from platform_probe+0x58/0xb0
platform_probe from really_probe+0xc4/0x2e0
really_probe from __driver_probe_device+0x84/0x19c
__driver_probe_device from driver_probe_device+0x2c/0x104
driver_probe_device from __driver_attach+0x90/0x170
__driver_attach from bus_for_each_dev+0x7c/0xd0
bus_for_each_dev from bus_add_driver+0xc4/0x1cc
bus_add_driver from driver_register+0x7c/0x114
driver_register from do_one_initcall+0x58/0x270
do_one_initcall from kernel_init_freeable+0x170/0x218
kernel_init_freeable from kernel_init+0x14/0x140
kernel_init from ret_from_fork+0x14/0x20
Fixes: abf6569d6482 ("pwm: imx-tpm: Make use of devm_pwmchip_alloc() function")
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Link: https://lore.kernel.org/r/20240304102929.893542-1-aisheng.dong@nxp.com
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
{
struct pwm_chip *chip;
struct imx_tpm_pwm_chip *tpm;
+ struct clk *clk;
void __iomem *base;
int ret;
unsigned int npwm;
if (IS_ERR(base))
return PTR_ERR(base);
+ clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+ "failed to get PWM clock\n");
+
/* get number of channels */
val = readl(base + PWM_IMX_TPM_PARAM);
npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
platform_set_drvdata(pdev, tpm);
tpm->base = base;
-
- tpm->clk = devm_clk_get_enabled(&pdev->dev, NULL);
- if (IS_ERR(tpm->clk))
- return dev_err_probe(&pdev->dev, PTR_ERR(tpm->clk),
- "failed to get PWM clock\n");
+ tpm->clk = clk;
chip->ops = &imx_tpm_pwm_ops;