regulator: tps6594-regulator: Fix random kernel crash
Random kernel crash detected in TI CICD when regulator driver is added.
This is root caused to irq index increment being done twice causing
irq_data being allocated outside of the range.
- Rework tps6594_request_reg_irqs with correct index increment
- Adjust irq_data kmalloc size to the exact size needed for the device
This has been reported on TI mainline. No public bug report associated.
Reported-by: Udit Kumar <u-kumar1@ti.com>
Fixes: f17ccc5deb
("regulator: tps6594-regulator: Add driver for TI TPS6594 regulators")
Signed-off-by: Jerome Neanne <jneanne@baylibre.com>
Link: https://lore.kernel.org/r/20230828-tps6594_random_boot_crash_fix-v1-1-f29cbf9ddb37@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
c69290557c
commit
ca0e36e3e3
|
@ -384,21 +384,19 @@ static int tps6594_request_reg_irqs(struct platform_device *pdev,
|
||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
irq_data[*irq_idx + j].dev = tps->dev;
|
irq_data[*irq_idx].dev = tps->dev;
|
||||||
irq_data[*irq_idx + j].type = irq_type;
|
irq_data[*irq_idx].type = irq_type;
|
||||||
irq_data[*irq_idx + j].rdev = rdev;
|
irq_data[*irq_idx].rdev = rdev;
|
||||||
|
|
||||||
error = devm_request_threaded_irq(tps->dev, irq, NULL,
|
error = devm_request_threaded_irq(tps->dev, irq, NULL,
|
||||||
tps6594_regulator_irq_handler,
|
tps6594_regulator_irq_handler, IRQF_ONESHOT,
|
||||||
IRQF_ONESHOT,
|
irq_type->irq_name, &irq_data[*irq_idx]);
|
||||||
irq_type->irq_name,
|
|
||||||
&irq_data[*irq_idx]);
|
|
||||||
(*irq_idx)++;
|
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(tps->dev, "tps6594 failed to request %s IRQ %d: %d\n",
|
dev_err(tps->dev, "tps6594 failed to request %s IRQ %d: %d\n",
|
||||||
irq_type->irq_name, irq, error);
|
irq_type->irq_name, irq, error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
(*irq_idx)++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -420,8 +418,8 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
|
||||||
int error, i, irq, multi, delta;
|
int error, i, irq, multi, delta;
|
||||||
int irq_idx = 0;
|
int irq_idx = 0;
|
||||||
int buck_idx = 0;
|
int buck_idx = 0;
|
||||||
int ext_reg_irq_nb = 2;
|
size_t ext_reg_irq_nb = 2;
|
||||||
|
size_t reg_irq_nb;
|
||||||
enum {
|
enum {
|
||||||
MULTI_BUCK12,
|
MULTI_BUCK12,
|
||||||
MULTI_BUCK123,
|
MULTI_BUCK123,
|
||||||
|
@ -484,15 +482,16 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tps->chip_id == LP8764)
|
if (tps->chip_id == LP8764) {
|
||||||
/* There is only 4 buck on LP8764 */
|
/* There is only 4 buck on LP8764 */
|
||||||
buck_configured[4] = 1;
|
buck_configured[4] = 1;
|
||||||
|
reg_irq_nb = size_mul(REGS_INT_NB, (BUCK_NB - 1));
|
||||||
|
} else {
|
||||||
|
reg_irq_nb = size_mul(REGS_INT_NB, (size_add(BUCK_NB, LDO_NB)));
|
||||||
|
}
|
||||||
|
|
||||||
irq_data = devm_kmalloc_array(tps->dev,
|
irq_data = devm_kmalloc_array(tps->dev, reg_irq_nb,
|
||||||
REGS_INT_NB * sizeof(struct tps6594_regulator_irq_data),
|
sizeof(struct tps6594_regulator_irq_data), GFP_KERNEL);
|
||||||
ARRAY_SIZE(tps6594_bucks_irq_types) +
|
|
||||||
ARRAY_SIZE(tps6594_ldos_irq_types),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!irq_data)
|
if (!irq_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue