Skip to content

Commit 1cb053e

Browse files
krzksre
authored andcommitted
power: supply: max77705: Fix potential IRQ chip conflict when probing two devices
MAX77705 charger is most likely always a single device on the board, however nothing stops board designers to have two of them, thus same device driver could probe twice. Or user could manually try to probing second time. Device driver is not ready for that case, because it allocates statically 'struct regmap_irq_chip' as non-const and stores during probe in 'irq_drv_data' member a pointer to per-probe state container ('struct max77705_charger_data'). devm_regmap_add_irq_chip() does not make a copy of 'struct regmap_irq_chip' but stores the pointer. Second probe - either successful or failure - would overwrite the 'irq_drv_data' from previous device probe, so interrupts would be executed in a wrong context. Fixes: a6a494c ("power: supply: max77705: Add charger driver for Maxim 77705") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://patch.msgid.link/20251023102905.71535-2-krzysztof.kozlowski@linaro.org Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
1 parent 8ed6b88 commit 1cb053e

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

drivers/power/supply/max77705_charger.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static const struct regmap_irq max77705_charger_irqs[] = {
9393
REGMAP_IRQ_REG_LINE(MAX77705_AICL_I, BITS_PER_BYTE),
9494
};
9595

96-
static struct regmap_irq_chip max77705_charger_irq_chip = {
96+
static const struct regmap_irq_chip max77705_charger_irq_chip = {
9797
.name = "max77705-charger",
9898
.status_base = MAX77705_CHG_REG_INT,
9999
.mask_base = MAX77705_CHG_REG_INT_MASK,
@@ -600,6 +600,7 @@ static int max77705_charger_probe(struct i2c_client *i2c)
600600
{
601601
struct power_supply_config pscfg = {};
602602
struct max77705_charger_data *chg;
603+
struct regmap_irq_chip *chip_desc;
603604
struct device *dev;
604605
struct regmap_irq_chip_data *irq_data;
605606
int ret;
@@ -613,6 +614,13 @@ static int max77705_charger_probe(struct i2c_client *i2c)
613614
chg->dev = dev;
614615
i2c_set_clientdata(i2c, chg);
615616

617+
chip_desc = devm_kmemdup(dev, &max77705_charger_irq_chip,
618+
sizeof(max77705_charger_irq_chip),
619+
GFP_KERNEL);
620+
if (!chip_desc)
621+
return -ENOMEM;
622+
chip_desc->irq_drv_data = chg;
623+
616624
chg->regmap = devm_regmap_init_i2c(i2c, &max77705_chg_regmap_config);
617625
if (IS_ERR(chg->regmap))
618626
return PTR_ERR(chg->regmap);
@@ -632,11 +640,9 @@ static int max77705_charger_probe(struct i2c_client *i2c)
632640
if (IS_ERR(chg->psy_chg))
633641
return PTR_ERR(chg->psy_chg);
634642

635-
max77705_charger_irq_chip.irq_drv_data = chg;
636643
ret = devm_regmap_add_irq_chip(chg->dev, chg->regmap, i2c->irq,
637644
IRQF_ONESHOT, 0,
638-
&max77705_charger_irq_chip,
639-
&irq_data);
645+
chip_desc, &irq_data);
640646
if (ret)
641647
return dev_err_probe(dev, ret, "failed to add irq chip\n");
642648

0 commit comments

Comments
 (0)