Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: max77705: Setup the core driver as an interrupt controller

Current implementation describes only MFD's own topsys interrupts.
However, max77705 has a register which indicates interrupt source, i.e.
it acts as an interrupt controller. There's 4 interrupt sources in
max77705: topsys, charger, fuelgauge, usb type-c manager.

Setup max77705 MFD parent as an interrupt controller. Delete topsys
interrupts because currently unused.

Remove shared interrupt flag, because we're are an interrupt controller
now, and subdevices should request interrupts from us.

Fixes: c8d50f029748 ("mfd: Add new driver for MAX77705 PMIC")

Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com>
Link: https://lore.kernel.org/r/20250909-max77705-fix_interrupt_handling-v3-1-233c5a1a20b5@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Dzmitry Sankouski and committed by
Lee Jones
605c9820 afe0f949

+14 -21
+14 -21
drivers/mfd/max77705.c
··· 61 61 .max_register = MAX77705_PMIC_REG_USBC_RESET, 62 62 }; 63 63 64 - static const struct regmap_irq max77705_topsys_irqs[] = { 65 - { .mask = MAX77705_SYSTEM_IRQ_BSTEN_INT, }, 66 - { .mask = MAX77705_SYSTEM_IRQ_SYSUVLO_INT, }, 67 - { .mask = MAX77705_SYSTEM_IRQ_SYSOVLO_INT, }, 68 - { .mask = MAX77705_SYSTEM_IRQ_TSHDN_INT, }, 69 - { .mask = MAX77705_SYSTEM_IRQ_TM_INT, }, 64 + static const struct regmap_irq max77705_irqs[] = { 65 + { .mask = MAX77705_SRC_IRQ_CHG, }, 66 + { .mask = MAX77705_SRC_IRQ_TOP, }, 67 + { .mask = MAX77705_SRC_IRQ_FG, }, 68 + { .mask = MAX77705_SRC_IRQ_USBC, }, 70 69 }; 71 70 72 - static const struct regmap_irq_chip max77705_topsys_irq_chip = { 73 - .name = "max77705-topsys", 74 - .status_base = MAX77705_PMIC_REG_SYSTEM_INT, 75 - .mask_base = MAX77705_PMIC_REG_SYSTEM_INT_MASK, 71 + static const struct regmap_irq_chip max77705_irq_chip = { 72 + .name = "max77705", 73 + .status_base = MAX77705_PMIC_REG_INTSRC, 74 + .ack_base = MAX77705_PMIC_REG_INTSRC, 75 + .mask_base = MAX77705_PMIC_REG_INTSRC_MASK, 76 76 .num_regs = 1, 77 - .irqs = max77705_topsys_irqs, 78 - .num_irqs = ARRAY_SIZE(max77705_topsys_irqs), 77 + .irqs = max77705_irqs, 78 + .num_irqs = ARRAY_SIZE(max77705_irqs), 79 79 }; 80 80 81 81 static int max77705_i2c_probe(struct i2c_client *i2c) ··· 110 110 111 111 ret = devm_regmap_add_irq_chip(dev, max77705->regmap, 112 112 i2c->irq, 113 - IRQF_ONESHOT | IRQF_SHARED, 0, 114 - &max77705_topsys_irq_chip, 113 + IRQF_ONESHOT, 0, 114 + &max77705_irq_chip, 115 115 &irq_data); 116 116 if (ret) 117 117 return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); 118 - 119 - /* Unmask interrupts from all blocks in interrupt source register */ 120 - ret = regmap_update_bits(max77705->regmap, 121 - MAX77705_PMIC_REG_INTSRC_MASK, 122 - MAX77705_SRC_IRQ_ALL, (unsigned int)~MAX77705_SRC_IRQ_ALL); 123 - if (ret < 0) 124 - return dev_err_probe(dev, ret, "Could not unmask interrupts in INTSRC\n"); 125 118 126 119 domain = regmap_irq_get_domain(irq_data); 127 120