mfd: max77693: Handle IRQs using regmap
authorRobert Baldyga <r.baldyga@samsung.com>
Wed, 21 May 2014 06:52:48 +0000 (08:52 +0200)
committerLee Jones <lee.jones@linaro.org>
Tue, 17 Jun 2014 14:17:00 +0000 (15:17 +0100)
This patch modifies mfd driver to use regmap for handling interrupts.
It allows to simplify irq handling process. This modifications needed
to make small changes in function drivers, which use interrupts.

Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
drivers/extcon/extcon-max77693.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/max77693-irq.c [deleted file]
drivers/mfd/max77693.c
include/linux/mfd/max77693-private.h

index ba84a6e77e03cb55b23935a6028a9506efd3fc65..c7278b1649da9f743814434cfe017e69e4189d00 100644 (file)
@@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
                struct max77693_muic_irq *muic_irq = &muic_irqs[i];
                unsigned int virq = 0;
 
-               virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
+               virq = regmap_irq_get_virq(max77693->irq_data_muic,
+                                       muic_irq->irq);
                if (!virq) {
                        ret = -EINVAL;
                        goto err_irq;
index ee8204cc31e916dbd344ca2c0a3a93135ab64cd5..2feac14d1085cbb5a7e5b621d6e3ae42e25d6e58 100644 (file)
@@ -384,6 +384,7 @@ config MFD_MAX77693
        depends on I2C=y
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        help
          Say yes here to add support for Maxim Semiconductor MAX77693.
          This is a companion Power Management IC with Flash, Haptic, Charger,
index 8afedba535c7c1375b8d88da388fb7c3762f27fc..8c6e7bba4660e42b925810553a21bf9e440ceaa3 100644 (file)
@@ -116,7 +116,7 @@ obj-$(CONFIG_MFD_DA9063)    += da9063.o
 
 obj-$(CONFIG_MFD_MAX14577)     += max14577.o
 obj-$(CONFIG_MFD_MAX77686)     += max77686.o max77686-irq.o
-obj-$(CONFIG_MFD_MAX77693)     += max77693.o max77693-irq.o
+obj-$(CONFIG_MFD_MAX77693)     += max77693.o
 obj-$(CONFIG_MFD_MAX8907)      += max8907.o
 max8925-objs                   := max8925-core.o max8925-i2c.o
 obj-$(CONFIG_MFD_MAX8925)      += max8925.o
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644 (file)
index 7d8f99f..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * max77693-irq.c - Interrupt controller support for MAX77693
- *
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * SangYoung Son <hello.son@samsung.com>
- *
- * This program is not provided / owned by Maxim Integrated Products.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This driver is based on max8997-irq.c
- */
-
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/irqdomain.h>
-#include <linux/mfd/max77693.h>
-#include <linux/mfd/max77693-private.h>
-#include <linux/regmap.h>
-
-static const unsigned int max77693_mask_reg[] = {
-       [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
-       [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
-       [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
-       [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
-       [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
-       [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
-};
-
-static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
-                               enum max77693_irq_source src)
-{
-       switch (src) {
-       case LED_INT ... CHG_INT:
-               return max77693->regmap;
-       case MUIC_INT1 ... MUIC_INT3:
-               return max77693->regmap_muic;
-       default:
-               return ERR_PTR(-EINVAL);
-       }
-}
-
-struct max77693_irq_data {
-       int mask;
-       enum max77693_irq_source group;
-};
-
-#define DECLARE_IRQ(idx, _group, _mask)                \
-       [(idx)] = { .group = (_group), .mask = (_mask) }
-static const struct max77693_irq_data max77693_irqs[] = {
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN,        LED_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT,       LED_INT, 1 << 1),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN,        LED_INT, 1 << 2),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT,       LED_INT, 1 << 3),
-       DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH,         LED_INT, 1 << 4),
-
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT,      TOPSYS_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT,      TOPSYS_INT, 1 << 1),
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT,     TOPSYS_INT, 1 << 3),
-
-       DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I,             CHG_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I,             CHG_INT, 1 << 2),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I,             CHG_INT, 1 << 3),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I,             CHG_INT, 1 << 4),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I,           CHG_INT, 1 << 6),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC,         MUIC_INT1, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW,     MUIC_INT1, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR,     MUIC_INT1, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K,       MUIC_INT1, 1 << 3),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP,      MUIC_INT2, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN,  MUIC_INT2, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR,      MUIC_INT2, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP,       MUIC_INT2, 1 << 3),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT,      MUIC_INT2, 1 << 4),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM,       MUIC_INT2, 1 << 5),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC,         MUIC_INT3, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC,       MUIC_INT3, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP,         MUIC_INT3, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR,  MUIC_INT3, 1 << 3),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET,     MUIC_INT3, 1 << 5),
-};
-
-static void max77693_irq_lock(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-
-       mutex_lock(&max77693->irqlock);
-}
-
-static void max77693_irq_sync_unlock(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       int i;
-
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               u8 mask_reg = max77693_mask_reg[i];
-               struct regmap *map = max77693_get_regmap(max77693, i);
-
-               if (mask_reg == MAX77693_REG_INVALID ||
-                               IS_ERR_OR_NULL(map))
-                       continue;
-               max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
-
-               regmap_write(map, max77693_mask_reg[i],
-                               max77693->irq_masks_cur[i]);
-       }
-
-       mutex_unlock(&max77693->irqlock);
-}
-
-static const inline struct max77693_irq_data *
-irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
-{
-       struct irq_data *data = irq_get_irq_data(irq);
-       return &max77693_irqs[data->hwirq];
-}
-
-static void max77693_irq_mask(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       const struct max77693_irq_data *irq_data =
-                               irq_to_max77693_irq(max77693, data->irq);
-
-       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
-               return;
-
-       if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
-               max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-       else
-               max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
-}
-
-static void max77693_irq_unmask(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       const struct max77693_irq_data *irq_data =
-           irq_to_max77693_irq(max77693, data->irq);
-
-       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
-               return;
-
-       if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
-               max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
-       else
-               max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-}
-
-static struct irq_chip max77693_irq_chip = {
-       .name                   = "max77693",
-       .irq_bus_lock           = max77693_irq_lock,
-       .irq_bus_sync_unlock    = max77693_irq_sync_unlock,
-       .irq_mask               = max77693_irq_mask,
-       .irq_unmask             = max77693_irq_unmask,
-};
-
-#define MAX77693_IRQSRC_CHG            (1 << 0)
-#define MAX77693_IRQSRC_TOP            (1 << 1)
-#define MAX77693_IRQSRC_FLASH          (1 << 2)
-#define MAX77693_IRQSRC_MUIC           (1 << 3)
-static irqreturn_t max77693_irq_thread(int irq, void *data)
-{
-       struct max77693_dev *max77693 = data;
-       u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
-       unsigned int irq_src;
-       int ret;
-       int i, cur_irq;
-
-       ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
-                               &irq_src);
-       if (ret < 0) {
-               dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
-                               ret);
-               return IRQ_NONE;
-       }
-
-       if (irq_src & MAX77693_IRQSRC_CHG) {
-               /* CHG_INT */
-               unsigned int data;
-               ret = regmap_read(max77693->regmap,
-                               MAX77693_CHG_REG_CHG_INT, &data);
-               irq_reg[CHG_INT] = data;
-       }
-
-       if (irq_src & MAX77693_IRQSRC_TOP) {
-               /* TOPSYS_INT */
-               unsigned int data;
-               ret = regmap_read(max77693->regmap,
-                       MAX77693_PMIC_REG_TOPSYS_INT, &data);
-               irq_reg[TOPSYS_INT] = data;
-       }
-
-       if (irq_src & MAX77693_IRQSRC_FLASH) {
-               /* LED_INT */
-               unsigned int data;
-               ret = regmap_read(max77693->regmap,
-                       MAX77693_LED_REG_FLASH_INT, &data);
-               irq_reg[LED_INT] = data;
-       }
-
-       if (irq_src & MAX77693_IRQSRC_MUIC)
-               /* MUIC INT1 ~ INT3 */
-               regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
-                       &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS);
-
-       /* Apply masking */
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               if (i >= MUIC_INT1 && i <= MUIC_INT3)
-                       irq_reg[i] &= max77693->irq_masks_cur[i];
-               else
-                       irq_reg[i] &= ~max77693->irq_masks_cur[i];
-       }
-
-       /* Report */
-       for (i = 0; i < MAX77693_IRQ_NR; i++) {
-               if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
-                       cur_irq = irq_find_mapping(max77693->irq_domain, i);
-                       if (cur_irq)
-                               handle_nested_irq(cur_irq);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
-int max77693_irq_resume(struct max77693_dev *max77693)
-{
-       if (max77693->irq)
-               max77693_irq_thread(0, max77693);
-
-       return 0;
-}
-
-static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
-                               irq_hw_number_t hw)
-{
-       struct max77693_dev *max77693 = d->host_data;
-
-       irq_set_chip_data(irq, max77693);
-       irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq);
-       irq_set_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
-       set_irq_flags(irq, IRQF_VALID);
-#else
-       irq_set_noprobe(irq);
-#endif
-       return 0;
-}
-
-static struct irq_domain_ops max77693_irq_domain_ops = {
-       .map = max77693_irq_domain_map,
-};
-
-int max77693_irq_init(struct max77693_dev *max77693)
-{
-       struct irq_domain *domain;
-       int i;
-       int ret = 0;
-       unsigned int intsrc_mask;
-
-       mutex_init(&max77693->irqlock);
-
-       /* Mask individual interrupt sources */
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               struct regmap *map;
-               /* MUIC IRQ  0:MASK 1:NOT MASK */
-               /* Other IRQ 1:MASK 0:NOT MASK */
-               if (i >= MUIC_INT1 && i <= MUIC_INT3) {
-                       max77693->irq_masks_cur[i] = 0x00;
-                       max77693->irq_masks_cache[i] = 0x00;
-               } else {
-                       max77693->irq_masks_cur[i] = 0xff;
-                       max77693->irq_masks_cache[i] = 0xff;
-               }
-               map = max77693_get_regmap(max77693, i);
-
-               if (IS_ERR_OR_NULL(map))
-                       continue;
-               if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
-                       continue;
-               if (i >= MUIC_INT1 && i <= MUIC_INT3)
-                       regmap_write(map, max77693_mask_reg[i], 0x00);
-               else
-                       regmap_write(map, max77693_mask_reg[i], 0xff);
-       }
-
-       domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
-                                       &max77693_irq_domain_ops, max77693);
-       if (!domain) {
-               dev_err(max77693->dev, "could not create irq domain\n");
-               ret = -ENODEV;
-               goto err_irq;
-       }
-       max77693->irq_domain = domain;
-
-       /* Unmask max77693 interrupt */
-       ret = regmap_read(max77693->regmap,
-                       MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
-       if (ret < 0) {
-               dev_err(max77693->dev, "fail to read PMIC register\n");
-               goto err_irq;
-       }
-
-       intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
-       intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
-       intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
-       ret = regmap_write(max77693->regmap,
-                       MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
-       if (ret < 0) {
-               dev_err(max77693->dev, "fail to write PMIC register\n");
-               goto err_irq;
-       }
-
-       ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
-                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                  "max77693-irq", max77693);
-       if (ret)
-               dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
-                       max77693->irq, ret);
-
-err_irq:
-       return ret;
-}
-
-void max77693_irq_exit(struct max77693_dev *max77693)
-{
-       if (max77693->irq)
-               free_irq(max77693->irq, max77693);
-}
index a0308336adaf8ff2f72e10c09a9b0f5f35d80ff3..249c139ef04ae3c80e14bd4674a251892f23ecfd 100644 (file)
@@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = {
        .max_register = MAX77693_PMIC_REG_END,
 };
 
+static const struct regmap_irq max77693_led_irqs[] = {
+       { .mask = LED_IRQ_FLED2_OPEN,  },
+       { .mask = LED_IRQ_FLED2_SHORT, },
+       { .mask = LED_IRQ_FLED1_OPEN,  },
+       { .mask = LED_IRQ_FLED1_SHORT, },
+       { .mask = LED_IRQ_MAX_FLASH,   },
+};
+
+static const struct regmap_irq_chip max77693_led_irq_chip = {
+       .name                   = "max77693-led",
+       .status_base            = MAX77693_LED_REG_FLASH_INT,
+       .mask_base              = MAX77693_LED_REG_FLASH_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_led_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_led_irqs),
+};
+
+static const struct regmap_irq max77693_topsys_irqs[] = {
+       { .mask = TOPSYS_IRQ_T120C_INT,  },
+       { .mask = TOPSYS_IRQ_T140C_INT,  },
+       { .mask = TOPSYS_IRQ_LOWSYS_INT, },
+};
+
+static const struct regmap_irq_chip max77693_topsys_irq_chip = {
+       .name                   = "max77693-topsys",
+       .status_base            = MAX77693_PMIC_REG_TOPSYS_INT,
+       .mask_base              = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_topsys_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_topsys_irqs),
+};
+
+static const struct regmap_irq max77693_charger_irqs[] = {
+       { .mask = CHG_IRQ_BYP_I,   },
+       { .mask = CHG_IRQ_THM_I,   },
+       { .mask = CHG_IRQ_BAT_I,   },
+       { .mask = CHG_IRQ_CHG_I,   },
+       { .mask = CHG_IRQ_CHGIN_I, },
+};
+
+static const struct regmap_irq_chip max77693_charger_irq_chip = {
+       .name                   = "max77693-charger",
+       .status_base            = MAX77693_CHG_REG_CHG_INT,
+       .mask_base              = MAX77693_CHG_REG_CHG_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_charger_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_charger_irqs),
+};
+
 static const struct regmap_config max77693_regmap_muic_config = {
        .reg_bits = 8,
        .val_bits = 8,
        .max_register = MAX77693_MUIC_REG_END,
 };
 
+static const struct regmap_irq max77693_muic_irqs[] = {
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC,           },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW,       },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR,       },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K,         },
+
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN,    },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP,         },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM,         },
+
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC,           },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC,         },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP,           },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR,    },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED,   },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET,       },
+};
+
+static const struct regmap_irq_chip max77693_muic_irq_chip = {
+       .name                   = "max77693-muic",
+       .status_base            = MAX77693_MUIC_REG_INT1,
+       .mask_base              = MAX77693_MUIC_REG_INTMASK1,
+       .mask_invert            = true,
+       .num_regs               = 3,
+       .irqs                   = max77693_muic_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_muic_irqs),
+};
+
 static int max77693_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
@@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                goto err_regmap_muic;
        }
 
-       ret = max77693_irq_init(max77693);
-       if (ret < 0)
-               goto err_irq;
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_led_irq_chip,
+                               &max77693->irq_data_led);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_regmap_muic;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_topsys_irq_chip,
+                               &max77693->irq_data_topsys);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_topsys;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_charger_irq_chip,
+                               &max77693->irq_data_charger);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_charger;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_muic_irq_chip,
+                               &max77693->irq_data_muic);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_muic;
+       }
 
        pm_runtime_set_active(max77693->dev);
 
@@ -138,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
        return ret;
 
 err_mfd:
-       max77693_irq_exit(max77693);
-err_irq:
+       mfd_remove_devices(max77693->dev);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+err_irq_muic:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+err_irq_charger:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+err_irq_topsys:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
 err_regmap_muic:
        i2c_unregister_device(max77693->haptic);
 err_i2c_haptic:
@@ -152,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
        mfd_remove_devices(max77693->dev);
-       max77693_irq_exit(max77693);
+
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
+
        i2c_unregister_device(max77693->muic);
        i2c_unregister_device(max77693->haptic);
 
@@ -170,8 +300,11 @@ static int max77693_suspend(struct device *dev)
        struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
-       if (device_may_wakeup(dev))
-               irq_set_irq_wake(max77693->irq, 1);
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(max77693->irq);
+               disable_irq(max77693->irq);
+       }
+
        return 0;
 }
 
@@ -180,9 +313,12 @@ static int max77693_resume(struct device *dev)
        struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
-       if (device_may_wakeup(dev))
-               irq_set_irq_wake(max77693->irq, 0);
-       return max77693_irq_resume(max77693);
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(max77693->irq);
+               enable_irq(max77693->irq);
+       }
+
+       return 0;
 }
 
 static const struct dev_pm_ops max77693_pm = {
index 80ec31d561c4e0c47d0b9be2d95554f0a6c6389c..c466ff3e16b8906cbe5ff8700ba3912ea7a296a6 100644 (file)
@@ -262,6 +262,41 @@ enum max77693_irq_source {
        MAX77693_IRQ_GROUP_NR,
 };
 
+#define LED_IRQ_FLED2_OPEN             BIT(0)
+#define LED_IRQ_FLED2_SHORT            BIT(1)
+#define LED_IRQ_FLED1_OPEN             BIT(2)
+#define LED_IRQ_FLED1_SHORT            BIT(3)
+#define LED_IRQ_MAX_FLASH              BIT(4)
+
+#define TOPSYS_IRQ_T120C_INT           BIT(0)
+#define TOPSYS_IRQ_T140C_INT           BIT(1)
+#define TOPSYS_IRQ_LOWSYS_INT          BIT(3)
+
+#define CHG_IRQ_BYP_I                  BIT(0)
+#define CHG_IRQ_THM_I                  BIT(2)
+#define CHG_IRQ_BAT_I                  BIT(3)
+#define CHG_IRQ_CHG_I                  BIT(4)
+#define CHG_IRQ_CHGIN_I                        BIT(6)
+
+#define MUIC_IRQ_INT1_ADC              BIT(0)
+#define MUIC_IRQ_INT1_ADC_LOW          BIT(1)
+#define MUIC_IRQ_INT1_ADC_ERR          BIT(2)
+#define MUIC_IRQ_INT1_ADC1K            BIT(3)
+
+#define MUIC_IRQ_INT2_CHGTYP           BIT(0)
+#define MUIC_IRQ_INT2_CHGDETREUN       BIT(1)
+#define MUIC_IRQ_INT2_DCDTMR           BIT(2)
+#define MUIC_IRQ_INT2_DXOVP            BIT(3)
+#define MUIC_IRQ_INT2_VBVOLT           BIT(4)
+#define MUIC_IRQ_INT2_VIDRM            BIT(5)
+
+#define MUIC_IRQ_INT3_EOC              BIT(0)
+#define MUIC_IRQ_INT3_CGMBC            BIT(1)
+#define MUIC_IRQ_INT3_OVP              BIT(2)
+#define MUIC_IRQ_INT3_MBCCHG_ERR       BIT(3)
+#define MUIC_IRQ_INT3_CHG_ENABLED      BIT(4)
+#define MUIC_IRQ_INT3_BAT_DET          BIT(5)
+
 enum max77693_irq {
        /* PMIC - FLASH */
        MAX77693_LED_IRQ_FLED2_OPEN,
@@ -282,6 +317,10 @@ enum max77693_irq {
        MAX77693_CHG_IRQ_CHG_I,
        MAX77693_CHG_IRQ_CHGIN_I,
 
+       MAX77693_IRQ_NR,
+};
+
+enum max77693_irq_muic {
        /* MUIC INT1 */
        MAX77693_MUIC_IRQ_INT1_ADC,
        MAX77693_MUIC_IRQ_INT1_ADC_LOW,
@@ -304,7 +343,7 @@ enum max77693_irq {
        MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,
        MAX77693_MUIC_IRQ_INT3_BAT_DET,
 
-       MAX77693_IRQ_NR,
+       MAX77693_MUIC_IRQ_NR,
 };
 
 struct max77693_dev {
@@ -319,7 +358,10 @@ struct max77693_dev {
        struct regmap *regmap_muic;
        struct regmap *regmap_haptic;
 
-       struct irq_domain *irq_domain;
+       struct regmap_irq_chip_data *irq_data_led;
+       struct regmap_irq_chip_data *irq_data_topsys;
+       struct regmap_irq_chip_data *irq_data_charger;
+       struct regmap_irq_chip_data *irq_data_muic;
 
        int irq;
        int irq_gpio;