static irqreturn_t max77843_irq_thread(int irq, void *data) { struct max77843_dev *max77843 = data; u8 irq_reg[MAX77843_IRQ_GROUP_NR] = {0}; u8 irq_src; int ret; int i; pr_debug("%s: irq gpio pre-state(0x%02x)\n", __func__, gpio_get_value(max77843->irq_gpio)); clear_retry: ret = max77843_read_reg(max77843->i2c, MAX77843_PMIC_REG_INTSRC, &irq_src); if (ret < 0) { dev_err(max77843->dev, "Failed to read interrupt source: %d\n", ret); return IRQ_NONE; } pr_info("%s: interrupt source(0x%02x)\n", __func__, irq_src); if (irq_src & MAX77843_IRQSRC_TOP) { /* TOPSYS_INT */ ret = max77843_read_reg(max77843->i2c, MAX77843_PMIC_REG_TOPSYS_INT, &irq_reg[MAX77843_TOPSYS_INT]); pr_info("%s: topsys interrupt(0x%02x)\n", __func__, irq_reg[MAX77843_TOPSYS_INT]); } if (irq_src & MAX77843_IRQSRC_CHG) { /* CHG_INT */ ret = max77843_read_reg(max77843->charger, MAX77843_CHG_REG_INT, &irq_reg[MAX77843_CHG_INT]); pr_info("%s: charger interrupt(0x%02x)\n", __func__, irq_reg[MAX77843_CHG_INT]); /* mask chgin to prevent chgin infinite interrupt * chgin is unmasked chgin isr */ if (irq_reg[MAX77843_CHG_INT] & max77843_irqs[MAX77843_CHG_IRQ_CHGIN_I].mask) { max77843_update_reg(max77843->i2c, MAX77843_CHG_REG_INT_MASK, MAX77843_CHGIN_IM, MAX77843_CHGIN_IM); } } if (irq_src & MAX77843_IRQSRC_FG) { pr_info("%s: fuelgauge interrupt, IRQ_BASE(%d), NESTED_IRQ(%d)\n", __func__, max77843->irq_base, max77843->irq_base + MAX77843_FG_IRQ_ALERT); handle_nested_irq(max77843->irq_base + MAX77843_FG_IRQ_ALERT); return IRQ_HANDLED; } if (irq_src & MAX77843_IRQSRC_MUIC) { /* MUIC INT1 ~ INT3 */ max77843_bulk_read(max77843->muic, MAX77843_MUIC_REG_INT1, MAX77843_NUM_IRQ_MUIC_REGS, &irq_reg[MAX77843_MUIC_INT1]); pr_info("%s: muic interrupt(0x%02x, 0x%02x, 0x%02x)\n", __func__, irq_reg[MAX77843_MUIC_INT1], irq_reg[MAX77843_MUIC_INT2], irq_reg[MAX77843_MUIC_INT3]); } pr_debug("%s: irq gpio post-state(0x%02x)\n", __func__, gpio_get_value(max77843->irq_gpio)); if (gpio_get_value(max77843->irq_gpio) == 0) { pr_warn("%s: irq_gpio is not High!\n", __func__); goto clear_retry; } #if 0 /* Apply masking */ for (i = 0; i < MAX77843_IRQ_GROUP_NR; i++) { if (i >= MAX77843_MUIC_INT1 && i <= MAX77843_MUIC_INT3) irq_reg[i] &= max77843->irq_masks_cur[i]; else irq_reg[i] &= ~max77843->irq_masks_cur[i]; } #endif /* Report */ for (i = 0; i < MAX77843_IRQ_NR; i++) { if (irq_reg[max77843_irqs[i].group] & max77843_irqs[i].mask) handle_nested_irq(max77843->irq_base + i); } return IRQ_HANDLED; }
static irqreturn_t max77843_irq_thread(int irq, void *data) { struct max77843_dev *max77843 = data; u8 irq_reg[MAX77843_IRQ_GROUP_NR] = {0}; u8 tmp_irq_reg[MAX77843_IRQ_GROUP_NR] = {}; #if defined(CONFIG_MUIC_MAX77843_SUPPORT_AFC_CHARGER) u8 tmp_irq_mask_reg[MAX77843_IRQ_GROUP_NR] = {}; #endif /* CONFIG_MUIC_MAX77843_SUPPORT_AFC_CHARGER */ static int check_num; u8 irq_src; int i, ret; pr_debug("%s: irq gpio pre-state(0x%02x)\n", __func__, gpio_get_value(max77843->irq_gpio)); ret = max77843_read_reg(max77843->i2c, MAX77843_PMIC_REG_INTSRC, &irq_src); if (ret) { pr_err("%s:%s Failed to read interrupt source: %d\n", MFD_DEV_NAME, __func__, ret); return IRQ_NONE; } #ifdef BATTERY_LOG_MESSAGE pr_info("%s: interrupt source(0x%02x)\n", __func__, irq_src); #endif if (irq_src & MAX77843_IRQSRC_CHG) { /* CHG_INT */ ret = max77843_read_reg(max77843->charger, MAX77843_CHG_REG_CHG_INT, &irq_reg[CHG_INT]); pr_info("%s: charger interrupt(0x%02x)\n", __func__, irq_reg[CHG_INT]); /* mask chgin to prevent chgin infinite interrupt * chgin is unmasked chgin isr */ if (irq_reg[CHG_INT] & max77843_irqs[MAX77843_CHG_IRQ_CHGIN_I].mask) { u8 reg_data; max77843_read_reg(max77843->charger, MAX77843_CHG_REG_CHG_INT_MASK, ®_data); reg_data |= (1 << 6); max77843_write_reg(max77843->charger, MAX77843_CHG_REG_CHG_INT_MASK, reg_data); } } if (irq_src & MAX77843_IRQSRC_FG) { pr_info("[%s] fuelgauge interrupt\n", __func__); pr_info("[%s]IRQ_BASE(%d), NESTED_IRQ(%d)\n", __func__, max77843->irq_base, max77843->irq_base + MAX77843_FG_IRQ_ALERT); handle_nested_irq(max77843->irq_base + MAX77843_FG_IRQ_ALERT); return IRQ_HANDLED; } if (irq_src & MAX77843_IRQSRC_TOP) { /* SYS_INT */ ret = max77843_read_reg(max77843->i2c, MAX77843_PMIC_REG_SYSTEM_INT, &irq_reg[SYS_INT]); pr_info("%s: topsys interrupt(0x%02x)\n", __func__, irq_reg[SYS_INT]); } if (irq_src & MAX77843_IRQSRC_MUIC) { /* MUIC INT1 ~ INT3 */ ret = max77843_bulk_read(max77843->muic, MAX77843_MUIC_REG_INT1, MAX77843_NUM_IRQ_MUIC_REGS, &tmp_irq_reg[MUIC_INT1]); if (ret) { pr_err("%s:%s Failed to read interrupt source: %d\n", MFD_DEV_NAME, __func__, ret); return IRQ_NONE; } #if defined(CONFIG_MUIC_MAX77843_SUPPORT_AFC_CHARGER) max77843_bulk_read(max77843->muic, MAX77843_MUIC_REG_INTMASK1, MAX77843_NUM_IRQ_MUIC_REGS, &tmp_irq_mask_reg[MUIC_INT1]); for (i = MUIC_INT1; i < MAX77843_IRQ_GROUP_NR; i++) tmp_irq_reg[i] &= tmp_irq_mask_reg[i]; #endif /* CONFIG_MUIC_MAX77843_SUPPORT_AFC_CHARGER */ /* Or temp irq register to irq register for if it retries */ for (i = MUIC_INT1; i <= MUIC_MAX_INT; i++) irq_reg[i] |= tmp_irq_reg[i]; pr_info("%s: muic interrupt(0x%02x, 0x%02x, 0x%02x)\n", __func__, irq_reg[MUIC_INT1], irq_reg[MUIC_INT2], irq_reg[MUIC_INT3]); /* for debug */ if ((irq_reg[MUIC_INT1] == 0) && (irq_reg[MUIC_INT2] == 0) && (irq_reg[MUIC_INT3] == 0)) { pr_info("%s: irq gpio post-state(0x%02x)\n", __func__, gpio_get_value(max77843->irq_gpio)); if (check_num >= 15) { max77843_muic_read_register(max77843->muic); panic("max77843 muic interrupt gpio Err!\n"); } check_num++; } else check_num = 0; } /* Apply masking */ for (i = 0; i < MAX77843_IRQ_GROUP_NR; i++) { if (i >= MUIC_INT1 && i <= MUIC_MAX_INT) irq_reg[i] &= max77843->irq_masks_cur[i]; else irq_reg[i] &= ~max77843->irq_masks_cur[i]; } /* Report */ for (i = 0; i < MAX77843_IRQ_NR; i++) { if (irq_reg[max77843_irqs[i].group] & max77843_irqs[i].mask) handle_nested_irq(max77843->irq_base + i); } return IRQ_HANDLED; }