int wake_count;
 
        void *status_reg_buf;
+       unsigned int *main_status_buf;
        unsigned int *status_buf;
        unsigned int *mask_buf;
        unsigned int *mask_buf_def;
        .irq_set_wake           = regmap_irq_set_wake,
 };
 
+static inline int read_sub_irq_data(struct regmap_irq_chip_data *data,
+                                          unsigned int b)
+{
+       const struct regmap_irq_chip *chip = data->chip;
+       struct regmap *map = data->map;
+       struct regmap_irq_sub_irq_map *subreg;
+       int i, ret = 0;
+
+       if (!chip->sub_reg_offsets) {
+               /* Assume linear mapping */
+               ret = regmap_read(map, chip->status_base +
+                                 (b * map->reg_stride * data->irq_reg_stride),
+                                  &data->status_buf[b]);
+       } else {
+               subreg = &chip->sub_reg_offsets[b];
+               for (i = 0; i < subreg->num_regs; i++) {
+                       unsigned int offset = subreg->offset[i];
+
+                       ret = regmap_read(map, chip->status_base + offset,
+                                         &data->status_buf[offset]);
+                       if (ret)
+                               break;
+               }
+       }
+       return ret;
+}
+
 static irqreturn_t regmap_irq_thread(int irq, void *d)
 {
        struct regmap_irq_chip_data *data = d;
        }
 
        /*
-        * Read in the statuses, using a single bulk read if possible
-        * in order to reduce the I/O overheads.
+        * Read only registers with active IRQs if the chip has 'main status
+        * register'. Else read in the statuses, using a single bulk read if
+        * possible in order to reduce the I/O overheads.
         */
-       if (!map->use_single_read && map->reg_stride == 1 &&
-           data->irq_reg_stride == 1) {
+
+       if (chip->num_main_regs) {
+               unsigned int max_main_bits;
+               unsigned long size;
+
+               size = chip->num_regs * sizeof(unsigned int);
+
+               max_main_bits = (chip->num_main_status_bits) ?
+                                chip->num_main_status_bits : chip->num_regs;
+               /* Clear the status buf as we don't read all status regs */
+               memset(data->status_buf, 0, size);
+
+               /* We could support bulk read for main status registers
+                * but I don't expect to see devices with really many main
+                * status registers so let's only support single reads for the
+                * sake of simplicity. and add bulk reads only if needed
+                */
+               for (i = 0; i < chip->num_main_regs; i++) {
+                       ret = regmap_read(map, chip->main_status +
+                                 (i * map->reg_stride
+                                  * data->irq_reg_stride),
+                                 &data->main_status_buf[i]);
+                       if (ret) {
+                               dev_err(map->dev,
+                                       "Failed to read IRQ status %d\n",
+                                       ret);
+                               goto exit;
+                       }
+               }
+
+               /* Read sub registers with active IRQs */
+               for (i = 0; i < chip->num_main_regs; i++) {
+                       unsigned int b;
+                       const unsigned long mreg = data->main_status_buf[i];
+
+                       for_each_set_bit(b, &mreg, map->format.val_bytes * 8) {
+                               if (i * map->format.val_bytes * 8 + b >
+                                   max_main_bits)
+                                       break;
+                               ret = read_sub_irq_data(data, b);
+
+                               if (ret != 0) {
+                                       dev_err(map->dev,
+                                               "Failed to read IRQ status %d\n",
+                                               ret);
+                                       if (chip->runtime_pm)
+                                               pm_runtime_put(map->dev);
+                                       goto exit;
+                               }
+                       }
+
+               }
+       } else if (!map->use_single_read && map->reg_stride == 1 &&
+                  data->irq_reg_stride == 1) {
+
                u8 *buf8 = data->status_reg_buf;
                u16 *buf16 = data->status_reg_buf;
                u32 *buf32 = data->status_reg_buf;
        if (!d)
                return -ENOMEM;
 
+       if (chip->num_main_regs) {
+               d->main_status_buf = kcalloc(chip->num_main_regs,
+                                            sizeof(unsigned int),
+                                            GFP_KERNEL);
+
+               if (!d->main_status_buf)
+                       goto err_alloc;
+       }
+
        d->status_buf = kcalloc(chip->num_regs, sizeof(unsigned int),
                                GFP_KERNEL);
        if (!d->status_buf)
 
                .reg_offset = (_id) / (_reg_bits),      \
        }
 
+#define REGMAP_IRQ_MAIN_REG_OFFSET(arr)                                \
+       { .num_regs = ARRAY_SIZE((arr)), .offset = &(arr)[0] }
+
+struct regmap_irq_sub_irq_map {
+       unsigned int num_regs;
+       unsigned int *offset;
+};
+
 /**
  * struct regmap_irq_chip - Description of a generic regmap irq_chip.
  *
  * @name:        Descriptive name for IRQ controller.
  *
+ * @main_status: Base main status register address. For chips which have
+ *              interrupts arranged in separate sub-irq blocks with own IRQ
+ *              registers and which have a main IRQ registers indicating
+ *              sub-irq blocks with unhandled interrupts. For such chips fill
+ *              sub-irq register information in status_base, mask_base and
+ *              ack_base.
+ * @num_main_status_bits: Should be given to chips where number of meaningfull
+ *                       main status bits differs from num_regs.
+ * @sub_reg_offsets: arrays of mappings from main register bits to sub irq
+ *                  registers. First item in array describes the registers
+ *                  for first main status bit. Second array for second bit etc.
+ *                  Offset is given as sub register status offset to
+ *                  status_base. Should contain num_regs arrays.
+ *                  Can be provided for chips with more complex mapping than
+ *                  1.st bit to 1.st sub-reg, 2.nd bit to 2.nd sub-reg, ...
+ * @num_main_regs: Number of 'main status' irq registers for chips which have
+ *                main_status set.
+ *
  * @status_base: Base status register address.
  * @mask_base:   Base mask register address.
  * @mask_writeonly: Base mask register is write only.
 struct regmap_irq_chip {
        const char *name;
 
+       unsigned int main_status;
+       unsigned int num_main_status_bits;
+       struct regmap_irq_sub_irq_map *sub_reg_offsets;
+       int num_main_regs;
+
        unsigned int status_base;
        unsigned int mask_base;
        unsigned int unmask_base;