Skip to content

Commit 2539b15

Browse files
committed
hwmon: (npcm750-pwm-fan) Fix crash observed when instantiating nuvoton,npcm750-pwm-fan
Commit 89fec12 ("hwmon: (npcm750-pwm-fan) Add NPCM8xx support") introduced support for PWM fans on Nuvoton's npcm845 SoC. This chip supports three PWM modules with four PWM channels each. The older npcm750 only supported two PWM modules. The commit did not take into account that the older SoC only supported two PWM modules. This results in a crash if npcm750 is instantiated when the code attempts to instantiate the non-existing third PWM module. Unable to handle kernel paging request at virtual address e0aa2000 when write [e0aa2000] *pgd=04ab6811, *pte=00000000, *ppte=00000000 Internal error: Oops: 807 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Tainted: G N 6.7.0-next-20240112-dirty #3 Hardware name: NPCM7XX Chip family PC is at npcm7xx_pwm_fan_probe+0x204/0x890 LR is at arm_heavy_mb+0x1c/0x38 Fix the problem by detecting the number of supported PWM modules in the probe function and only instantiating the supported modules. Fixes: 89fec12 ("hwmon: (npcm750-pwm-fan) Add NPCM8xx support") Cc: Tomer Maimon <tmaimon77@gmail.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 052d534 commit 2539b15

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

drivers/hwmon/npcm750-pwm-fan.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ struct npcm7xx_cooling_device {
195195
struct npcm7xx_pwm_fan_data {
196196
void __iomem *pwm_base;
197197
void __iomem *fan_base;
198+
int pwm_modules;
198199
unsigned long pwm_clk_freq;
199200
unsigned long fan_clk_freq;
200201
struct clk *pwm_clk;
@@ -710,7 +711,7 @@ static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data)
710711
/* Setting PWM Prescale Register value register to both modules */
711712
prescale_val |= (prescale_val << NPCM7XX_PWM_PRESCALE_SHIFT_CH01);
712713

713-
for (m = 0; m < NPCM7XX_PWM_MAX_MODULES ; m++) {
714+
for (m = 0; m < data->pwm_modules; m++) {
714715
iowrite32(prescale_val, NPCM7XX_PWM_REG_PR(data->pwm_base, m));
715716
iowrite32(NPCM7XX_PWM_PRESCALE2_DEFAULT,
716717
NPCM7XX_PWM_REG_CSR(data->pwm_base, m));
@@ -946,6 +947,8 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev)
946947
if (!data->info)
947948
return -EINVAL;
948949

950+
data->pwm_modules = data->info->pwm_max_channel / NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE;
951+
949952
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm");
950953
if (!res) {
951954
dev_err(dev, "pwm resource not found\n");
@@ -983,7 +986,7 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev)
983986
output_freq = npcm7xx_pwm_init(data);
984987
npcm7xx_fan_init(data);
985988

986-
for (cnt = 0; cnt < NPCM7XX_PWM_MAX_MODULES ; cnt++)
989+
for (cnt = 0; cnt < data->pwm_modules; cnt++)
987990
mutex_init(&data->pwm_lock[cnt]);
988991

989992
for (i = 0; i < NPCM7XX_FAN_MAX_MODULE; i++) {

0 commit comments

Comments
 (0)