Skip to content

Commit 0401f24

Browse files
Uwe Kleine-Königthierryreding
authored andcommitted
pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
When a driver calls pwmchip_add() it has to be prepared to immediately get its callbacks called. So move allocation of driver data and hardware initialization before the call to pwmchip_add(). This fixes a potential NULL pointer exception and a race condition on register writes. Fixes: 841e6f9 ("pwm: NXP LPC18xx PWM/SCT driver") Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 914195e commit 0401f24

File tree

1 file changed

+9
-11
lines changed

1 file changed

+9
-11
lines changed

drivers/pwm/pwm-lpc18xx-sct.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,6 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
395395
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT,
396396
BIT(lpc18xx_pwm->period_event));
397397

398-
ret = pwmchip_add(&lpc18xx_pwm->chip);
399-
if (ret < 0) {
400-
dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
401-
goto disable_pwmclk;
402-
}
403-
404398
for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
405399
struct lpc18xx_pwm_data *data;
406400

@@ -410,25 +404,29 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
410404
GFP_KERNEL);
411405
if (!data) {
412406
ret = -ENOMEM;
413-
goto remove_pwmchip;
407+
goto disable_pwmclk;
414408
}
415409

416410
pwm_set_chip_data(pwm, data);
417411
}
418412

419-
platform_set_drvdata(pdev, lpc18xx_pwm);
420-
421413
val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
422414
val &= ~LPC18XX_PWM_BIDIR;
423415
val &= ~LPC18XX_PWM_CTRL_HALT;
424416
val &= ~LPC18XX_PWM_PRE_MASK;
425417
val |= LPC18XX_PWM_PRE(0);
426418
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
427419

420+
ret = pwmchip_add(&lpc18xx_pwm->chip);
421+
if (ret < 0) {
422+
dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
423+
goto disable_pwmclk;
424+
}
425+
426+
platform_set_drvdata(pdev, lpc18xx_pwm);
427+
428428
return 0;
429429

430-
remove_pwmchip:
431-
pwmchip_remove(&lpc18xx_pwm->chip);
432430
disable_pwmclk:
433431
clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
434432
return ret;

0 commit comments

Comments
 (0)