The BCM590XX supports up to 128 internal interrupts, which are used by
various parts of the chip. Add regmap_irq-based interrupt handling and
helper functions to allow subdevice drivers to easily use the interrupts.

Signed-off-by: Artur Weber <aweber.ker...@gmail.com>
---
This patch is a prerequisite for future subdevice additions, since
many of them rely on the interrupts; I have a power-on key driver and
an RTC driver ready which both use the IRQ data/helper functions included
in this patch (they will be sent in subsequent patch series), and more
are on the way.
---
Changes in v2:
- Rename xSROVRI IRQs to xSR_OVRI to match LDO_OVRI naming
- Link to v1: 
https://lore.kernel.org/r/20250816-bcm590xx-irq-v1-1-ccbb49062...@gmail.com
---
Changes in v2:
- Rename xSROVRI IRQs to xSR_OVRI to match LDO_OVRI naming
---
 drivers/mfd/Kconfig          |   1 +
 drivers/mfd/bcm590xx.c       | 281 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/bcm590xx.h | 231 +++++++++++++++++++++++++++++++++++
 3 files changed, 513 insertions(+)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 
6fb3768e3d71cbb5c81f63de36cdb2d27a0a7726..e76b18e29dbc6ba40f162276cb19b89806b326a6
 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -175,6 +175,7 @@ config MFD_BCM590XX
        tristate "Broadcom BCM590xx PMUs"
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        depends on I2C
        help
          Support for the BCM590xx PMUs from Broadcom
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index 
5a8456bbd63f65b9260f05ef6546c026bf822bae..a8459c97ead1702368a3d631ccf1f48a757212f0
 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -26,16 +26,30 @@
 #define BCM590XX_PMUREV_ANA_MASK       0xF0
 #define BCM590XX_PMUREV_ANA_SHIFT      4
 
+#define BCM590XX_REG_IRQ1              0x20
+#define BCM590XX_REG_IRQ1_MASK         0x30
+
 static const struct mfd_cell bcm590xx_devs[] = {
        {
                .name = "bcm590xx-vregs",
        },
 };
 
+static bool bcm590xx_volatile_pri(struct device *dev, unsigned int reg)
+{
+       /*
+        * IRQ registers are clear-on-read, make sure we don't cache them
+        * so that they get read/cleared correctly
+        */
+       return (reg >= BCM590XX_REG_IRQ1 &&
+               reg <= (BCM590XX_REG_IRQ1 + 15));
+}
+
 static const struct regmap_config bcm590xx_regmap_config_pri = {
        .reg_bits       = 8,
        .val_bits       = 8,
        .max_register   = BCM590XX_MAX_REGISTER_PRI,
+       .volatile_reg   = bcm590xx_volatile_pri,
        .cache_type     = REGCACHE_MAPLE,
 };
 
@@ -46,6 +60,268 @@ static const struct regmap_config 
bcm590xx_regmap_config_sec = {
        .cache_type     = REGCACHE_MAPLE,
 };
 
+/** Interrupt handling **/
+
+/* IRQ IDs in the MFD header follow the IRQ order in hardware. */
+#define BCM590XX_REGMAP_IRQ_REG(id)    REGMAP_IRQ_REG_LINE(id, 8)
+
+/* BCM59054 IRQs */
+
+static const struct regmap_irq bcm59054_regmap_irqs[] = {
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBINS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBRM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_BATINS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_BATRM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBC_CV_LOOP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBC_CV_TMR_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_EOC),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RESUME_VBUS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBTEMPLOW),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBTEMPHIGH),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBOV),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBOV),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHGERRDIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBOV_DIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBOV_DIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBC_TF),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHG_HW_TTR_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHG_HW_TCH_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHG_SW_TMR_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHG_TCH_1MIN_BF_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USB_PORT_DIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USB_CC_REDUCE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VBUSLOWBND),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_UBPD_CHG_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VBUS_VALID_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_OTG_SESS_VALID_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VB_SESS_END_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ID_RM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VBUS_VALID_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VA_SESS_VALID_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VB_SESS_END_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ID_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_IDCHG),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RIC_C_TO_FLOAT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHGDET_LATCH),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CHGDET_TO),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ADP_CHANGE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ADP_SNS_END),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ADP_PROB),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_ADP_PRB_ERR),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_PRESSED),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_RELEASED),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_WAKEUP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_BIT_VLD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_RESTART),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_T1),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_T2),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_T3),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_I2C_RESTART),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GBAT_PLUG_IN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SMPL_INT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUX_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUX_RM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_XTAL_FAILURE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBWV_R_10S_WAIT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MBWV_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTC_ALARM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTC_SEC),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTC_MIN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTCADJ),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_FGC),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_BBLOW),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_DIE_OT_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_DIE_OT_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTM_DATA_RDY),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTM_IN_CON_MEAS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTM_UPPER),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTM_IGNORE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RTM_OVERRIDDEN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUD_HSAB_SHCKT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUD_IHFD_SHCKT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_POK_NOP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_LEN_ERR),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_RCV_ERR),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_BUSQ_RESP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_BUSQ_POS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_EOT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_XMT_END),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MIPI_INT_POS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_LOWBAT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDSR1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDSR2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_IOSR1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_IOSR2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RESERVED),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RFLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUDLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBLDO_OVR),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDXLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MICLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SIMLDO1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SIMLDO2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MMCLDO1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CAMLDO1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CAMLDO2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VIBLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO3_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_RFLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_AUDLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_USBLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDXLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MICLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SIMLDO1_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SIMLDO2_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MMCLDO1_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_MMCLDO2_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CAMLDO1_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_CAMLDO2_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VIBLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_SDLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO1_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO2_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_GPLDO3_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_TCXLDO_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_LVLDO1_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_LVLDO2_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_TCXLDO_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_LVLDO1_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_LVLDO2_SHD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VBOVRV),
+       BCM590XX_REGMAP_IRQ_REG(BCM59054_IRQ_VBOVRI),
+};
+
+static const struct regmap_irq_chip bcm59054_irq_chip = {
+       .name = "bcm59054-irq",
+       .irqs = bcm59054_regmap_irqs,
+       .num_irqs = BCM59054_IRQ_MAX,
+       .num_regs = 16,
+       .status_base = BCM590XX_REG_IRQ1,
+       .mask_base = BCM590XX_REG_IRQ1_MASK,
+       .clear_on_unmask = true,
+};
+
+/* BCM59056 IRQs */
+
+static const struct regmap_irq bcm59056_regmap_irqs[] = {
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTC_ALARM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTC_SEC),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTC_MIN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTCADJ),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_BATINS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_BATRM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_GBAT_PLUG_IN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_SMPL_INT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_USBINS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_USBRM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_USBOV),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_EOC),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RESUME_VBUS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHG_HW_TTR_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHG_HW_TCH_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHG_SW_TMR_EXP),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHGDET_LATCH),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHGDET_TO),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBTEMPLOW),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBTEMPHIGH),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBOV),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBOV_DIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_USBOV_DIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CHGERRDIS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VBUS_1V5_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VBUS_4V5_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VBUS_1V5_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VBUS_4V5_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBWV_R_10S_WAIT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_BBLOW),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_LOWBAT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VERYLOWBAT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTM_DATA_RDY),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTM_IN_CON_MEAS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTM_UPPER),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTM_IGNORE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_RTM_OVERRIDDEN),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_AUD_HSAB_SHCKT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_AUD_IHFD_SHCKT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_MBC_TF),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_CSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_IOSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_SDSR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ASR_OVRI),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_UBPD_CHG_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ACD_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ACD_RM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_PONKEYB_HOLD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_PONKEYB_F),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_PONKEYB_R),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_PONKEYB_OFFHOLD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_PONKEYB_RESTART),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_IDCHG),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_JIG_USB_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_UART_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ID_INS),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ID_RM),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ADP_CHANGE),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_ADP_SNS_END),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_SESSION_END_VLD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_SESSION_END_INVLD),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_VBUS_OVERCURRENT),
+       BCM590XX_REGMAP_IRQ_REG(BCM59056_IRQ_FGC),
+};
+
+static const struct regmap_irq_chip bcm59056_irq_chip = {
+       .name = "bcm59056-irq",
+       .irqs = bcm59056_regmap_irqs,
+       .num_irqs = BCM59056_IRQ_MAX,
+       .num_regs = 16,
+       .status_base = BCM590XX_REG_IRQ1,
+       .mask_base = BCM590XX_REG_IRQ1_MASK,
+       .clear_on_unmask = true,
+};
+
+static int bcm590xx_irq_init(struct bcm590xx *bcm590xx)
+{
+       const struct regmap_irq_chip *irq_chip;
+       int ret;
+
+       if (!bcm590xx->irq) {
+               dev_err(bcm590xx->dev, "No IRQ configured\n");
+               return -EINVAL;
+       }
+
+       switch (bcm590xx->pmu_id) {
+       case BCM590XX_PMUID_BCM59054:
+               irq_chip = &bcm59054_irq_chip;
+               break;
+       case BCM590XX_PMUID_BCM59056:
+               irq_chip = &bcm59056_irq_chip;
+               break;
+       default:
+               dev_err(bcm590xx->dev,
+                       "Unknown device type, this is a driver bug!\n");
+               return -EINVAL;
+       }
+
+       ret = devm_regmap_add_irq_chip(bcm590xx->dev, bcm590xx->regmap_pri,
+                       bcm590xx->irq, IRQF_TRIGGER_FALLING, 0,
+                       irq_chip, &bcm590xx->irq_data);
+       if (ret) {
+               dev_err(bcm590xx->dev, "Failed to reguest IRQ %d: %d\n",
+                       bcm590xx->irq, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+/** Chip version parsing **/
+
 /* Map PMU ID value to model name string */
 static const char * const bcm590xx_names[] = {
        [BCM590XX_PMUID_BCM59054] = "BCM59054",
@@ -98,6 +374,7 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
 
        i2c_set_clientdata(i2c_pri, bcm590xx);
        bcm590xx->dev = &i2c_pri->dev;
+       bcm590xx->irq = i2c_pri->irq;
        bcm590xx->i2c_pri = i2c_pri;
 
        bcm590xx->pmu_id = (uintptr_t) of_device_get_match_data(bcm590xx->dev);
@@ -132,6 +409,10 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
        if (ret)
                goto err;
 
+       ret = bcm590xx_irq_init(bcm590xx);
+       if (ret)
+               goto err;
+
        ret = devm_mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
                                   ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
        if (ret < 0) {
diff --git a/include/linux/mfd/bcm590xx.h b/include/linux/mfd/bcm590xx.h
index 
5a5783abd47b9a6bb6f9bb3a8cafddbd01aa7fcc..710eb309bb4cc57f6b383f70b63c35861164fa52
 100644
--- a/include/linux/mfd/bcm590xx.h
+++ b/include/linux/mfd/bcm590xx.h
@@ -50,6 +50,237 @@ struct bcm590xx {
        /* Chip revision, read from PMUREV reg */
        u8 rev_digital;
        u8 rev_analog;
+
+       /* Interrupts */
+       int irq;
+       struct regmap_irq_chip_data *irq_data;
+};
+
+/* Interrupt handling helper functions */
+
+static inline int
+bcm590xx_devm_request_irq(struct device *dev, struct bcm590xx *bcm590xx, int 
irq,
+                         irq_handler_t handler, unsigned long flags,
+                         const char *name, void *data)
+{
+       if (!bcm590xx->irq_data)
+               return -EINVAL;
+
+       return devm_request_threaded_irq(dev,
+                               regmap_irq_get_virq(bcm590xx->irq_data, irq),
+                               NULL, handler, flags, name, data);
+}
+
+static inline void
+bcm590xx_devm_free_irq(struct device *dev, struct bcm590xx *bcm590xx, int irq,
+                      void *data)
+{
+       if (!bcm590xx->irq_data)
+               return;
+
+       devm_free_irq(dev, regmap_irq_get_virq(bcm590xx->irq_data, irq), data);
+}
+
+/* BCM59054 IRQs */
+
+enum bcm59054_irq {
+       BCM59054_IRQ_USBINS = 0,
+       BCM59054_IRQ_USBRM,
+       BCM59054_IRQ_BATINS,
+       BCM59054_IRQ_BATRM,
+       BCM59054_IRQ_MBC_CV_LOOP,
+       BCM59054_IRQ_MBC_CV_TMR_EXP,
+       BCM59054_IRQ_EOC,
+       BCM59054_IRQ_RESUME_VBUS,
+       BCM59054_IRQ_MBTEMPLOW,
+       BCM59054_IRQ_MBTEMPHIGH,
+       BCM59054_IRQ_USBOV,
+       BCM59054_IRQ_MBOV,
+       BCM59054_IRQ_CHGERRDIS,
+       BCM59054_IRQ_MBOV_DIS,
+       BCM59054_IRQ_USBOV_DIS,
+       BCM59054_IRQ_MBC_TF,
+       BCM59054_IRQ_CHG_HW_TTR_EXP,
+       BCM59054_IRQ_CHG_HW_TCH_EXP,
+       BCM59054_IRQ_CHG_SW_TMR_EXP,
+       BCM59054_IRQ_CHG_TCH_1MIN_BF_EXP,
+       BCM59054_IRQ_USB_PORT_DIS,
+       BCM59054_IRQ_USB_CC_REDUCE,
+       BCM59054_IRQ_VBUSLOWBND,
+       BCM59054_IRQ_UBPD_CHG_F,
+       BCM59054_IRQ_VBUS_VALID_F,
+       BCM59054_IRQ_OTG_SESS_VALID_F,
+       BCM59054_IRQ_VB_SESS_END_F,
+       BCM59054_IRQ_ID_RM,
+       BCM59054_IRQ_VBUS_VALID_R,
+       BCM59054_IRQ_VA_SESS_VALID_R,
+       BCM59054_IRQ_VB_SESS_END_R,
+       BCM59054_IRQ_ID_INS,
+       BCM59054_IRQ_IDCHG,
+       BCM59054_IRQ_RIC_C_TO_FLOAT,
+       BCM59054_IRQ_CHGDET_LATCH,
+       BCM59054_IRQ_CHGDET_TO,
+       BCM59054_IRQ_ADP_CHANGE,
+       BCM59054_IRQ_ADP_SNS_END,
+       BCM59054_IRQ_ADP_PROB,
+       BCM59054_IRQ_ADP_PRB_ERR,
+       BCM59054_IRQ_POK_PRESSED,
+       BCM59054_IRQ_POK_RELEASED,
+       BCM59054_IRQ_POK_WAKEUP,
+       BCM59054_IRQ_POK_BIT_VLD,
+       BCM59054_IRQ_POK_RESTART,
+       BCM59054_IRQ_POK_T1,
+       BCM59054_IRQ_POK_T2,
+       BCM59054_IRQ_POK_T3,
+       BCM59054_IRQ_I2C_RESTART,
+       BCM59054_IRQ_GBAT_PLUG_IN,
+       BCM59054_IRQ_SMPL_INT,
+       BCM59054_IRQ_AUX_INS,
+       BCM59054_IRQ_AUX_RM,
+       BCM59054_IRQ_XTAL_FAILURE,
+       BCM59054_IRQ_MBWV_R_10S_WAIT,
+       BCM59054_IRQ_MBWV_F,
+       BCM59054_IRQ_RTC_ALARM,
+       BCM59054_IRQ_RTC_SEC,
+       BCM59054_IRQ_RTC_MIN,
+       BCM59054_IRQ_RTCADJ,
+       BCM59054_IRQ_FGC,
+       BCM59054_IRQ_BBLOW,
+       BCM59054_IRQ_DIE_OT_R,
+       BCM59054_IRQ_DIE_OT_F,
+       BCM59054_IRQ_RTM_DATA_RDY,
+       BCM59054_IRQ_RTM_IN_CON_MEAS,
+       BCM59054_IRQ_RTM_UPPER,
+       BCM59054_IRQ_RTM_IGNORE,
+       BCM59054_IRQ_RTM_OVERRIDDEN,
+       BCM59054_IRQ_AUD_HSAB_SHCKT,
+       BCM59054_IRQ_AUD_IHFD_SHCKT,
+       BCM59054_IRQ_POK_NOP,
+       BCM59054_IRQ_MIPI_LEN_ERR,
+       BCM59054_IRQ_MIPI_RCV_ERR,
+       BCM59054_IRQ_MIPI_BUSQ_RESP,
+       BCM59054_IRQ_MIPI_BUSQ_POS,
+       BCM59054_IRQ_MIPI_EOT,
+       BCM59054_IRQ_MIPI_XMT_END,
+       BCM59054_IRQ_MIPI_INT_POS,
+       BCM59054_IRQ_LOWBAT,
+       BCM59054_IRQ_CSR_OVRI,
+       BCM59054_IRQ_VSR_OVRI,
+       BCM59054_IRQ_MSR_OVRI,
+       BCM59054_IRQ_SDSR1_OVRI,
+       BCM59054_IRQ_SDSR2_OVRI,
+       BCM59054_IRQ_IOSR1_OVRI,
+       BCM59054_IRQ_IOSR2_OVRI,
+       BCM59054_IRQ_RESERVED,
+       BCM59054_IRQ_RFLDO_OVRI,
+       BCM59054_IRQ_AUDLDO_OVRI,
+       BCM59054_IRQ_USBLDO_OVR,
+       BCM59054_IRQ_SDXLDO_OVRI,
+       BCM59054_IRQ_MICLDO_OVRI,
+       BCM59054_IRQ_SIMLDO1_OVRI,
+       BCM59054_IRQ_SIMLDO2_OVRI,
+       BCM59054_IRQ_MMCLDO1_OVRI,
+       BCM59054_IRQ_CAMLDO1_OVRI,
+       BCM59054_IRQ_CAMLDO2_OVRI,
+       BCM59054_IRQ_VIBLDO_OVRI,
+       BCM59054_IRQ_SDLDO_OVRI,
+       BCM59054_IRQ_GPLDO1_OVRI,
+       BCM59054_IRQ_GPLDO2_OVRI,
+       BCM59054_IRQ_GPLDO3_OVRI,
+       BCM59054_IRQ_RFLDO_SHD,
+       BCM59054_IRQ_AUDLDO_SHD,
+       BCM59054_IRQ_USBLDO_SHD,
+       BCM59054_IRQ_SDXLDO_SHD,
+       BCM59054_IRQ_MICLDO_SHD,
+       BCM59054_IRQ_SIMLDO1_SHD,
+       BCM59054_IRQ_SIMLDO2_SHD,
+       BCM59054_IRQ_MMCLDO1_SHD,
+       BCM59054_IRQ_MMCLDO2_SHD,
+       BCM59054_IRQ_CAMLDO1_SHD,
+       BCM59054_IRQ_CAMLDO2_SHD,
+       BCM59054_IRQ_VIBLDO_SHD,
+       BCM59054_IRQ_SDLDO_SHD,
+       BCM59054_IRQ_GPLDO1_SHD,
+       BCM59054_IRQ_GPLDO2_SHD,
+       BCM59054_IRQ_GPLDO3_SHD,
+       BCM59054_IRQ_TCXLDO_OVRI,
+       BCM59054_IRQ_LVLDO1_OVRI,
+       BCM59054_IRQ_LVLDO2_OVRI,
+       BCM59054_IRQ_TCXLDO_SHD,
+       BCM59054_IRQ_LVLDO1_SHD,
+       BCM59054_IRQ_LVLDO2_SHD,
+       BCM59054_IRQ_VBOVRV,
+       BCM59054_IRQ_VBOVRI,
+       BCM59054_IRQ_MAX,
+};
+
+/* BCM59056 IRQs */
+
+enum bcm59056_irq {
+       BCM59056_IRQ_RTC_ALARM = 0,
+       BCM59056_IRQ_RTC_SEC,
+       BCM59056_IRQ_RTC_MIN,
+       BCM59056_IRQ_RTCADJ,
+       BCM59056_IRQ_BATINS,
+       BCM59056_IRQ_BATRM,
+       BCM59056_IRQ_GBAT_PLUG_IN,
+       BCM59056_IRQ_SMPL_INT,
+       BCM59056_IRQ_USBINS,
+       BCM59056_IRQ_USBRM,
+       BCM59056_IRQ_USBOV,
+       BCM59056_IRQ_EOC,
+       BCM59056_IRQ_RESUME_VBUS,
+       BCM59056_IRQ_CHG_HW_TTR_EXP,
+       BCM59056_IRQ_CHG_HW_TCH_EXP,
+       BCM59056_IRQ_CHG_SW_TMR_EXP,
+       BCM59056_IRQ_CHGDET_LATCH,
+       BCM59056_IRQ_CHGDET_TO,
+       BCM59056_IRQ_MBTEMPLOW,
+       BCM59056_IRQ_MBTEMPHIGH,
+       BCM59056_IRQ_MBOV,
+       BCM59056_IRQ_MBOV_DIS,
+       BCM59056_IRQ_USBOV_DIS,
+       BCM59056_IRQ_CHGERRDIS,
+       BCM59056_IRQ_VBUS_1V5_R,
+       BCM59056_IRQ_VBUS_4V5_R,
+       BCM59056_IRQ_VBUS_1V5_F,
+       BCM59056_IRQ_VBUS_4V5_F,
+       BCM59056_IRQ_MBWV_R_10S_WAIT,
+       BCM59056_IRQ_BBLOW,
+       BCM59056_IRQ_LOWBAT,
+       BCM59056_IRQ_VERYLOWBAT,
+       BCM59056_IRQ_RTM_DATA_RDY,
+       BCM59056_IRQ_RTM_IN_CON_MEAS,
+       BCM59056_IRQ_RTM_UPPER,
+       BCM59056_IRQ_RTM_IGNORE,
+       BCM59056_IRQ_RTM_OVERRIDDEN,
+       BCM59056_IRQ_AUD_HSAB_SHCKT,
+       BCM59056_IRQ_AUD_IHFD_SHCKT,
+       BCM59056_IRQ_MBC_TF,
+       BCM59056_IRQ_CSR_OVRI,
+       BCM59056_IRQ_IOSR_OVRI,
+       BCM59056_IRQ_SDSR_OVRI,
+       BCM59056_IRQ_ASR_OVRI,
+       BCM59056_IRQ_UBPD_CHG_F,
+       BCM59056_IRQ_ACD_INS,
+       BCM59056_IRQ_ACD_RM,
+       BCM59056_IRQ_PONKEYB_HOLD,
+       BCM59056_IRQ_PONKEYB_F,
+       BCM59056_IRQ_PONKEYB_R,
+       BCM59056_IRQ_PONKEYB_OFFHOLD,
+       BCM59056_IRQ_PONKEYB_RESTART,
+       BCM59056_IRQ_IDCHG,
+       BCM59056_IRQ_JIG_USB_INS,
+       BCM59056_IRQ_UART_INS,
+       BCM59056_IRQ_ID_INS,
+       BCM59056_IRQ_ID_RM,
+       BCM59056_IRQ_ADP_CHANGE,
+       BCM59056_IRQ_ADP_SNS_END,
+       BCM59056_IRQ_SESSION_END_VLD,
+       BCM59056_IRQ_SESSION_END_INVLD,
+       BCM59056_IRQ_VBUS_OVERCURRENT,
+       BCM59056_IRQ_FGC,
+       BCM59056_IRQ_MAX,
 };
 
 #endif /*  __LINUX_MFD_BCM590XX_H */

---
base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f
change-id: 20250816-bcm590xx-irq-2d4c1cbe00b1

Best regards,
-- 
Artur Weber <aweber.ker...@gmail.com>


Reply via email to