#define MAX_MAPPINGS   (MAX_WORDS * 2)
 #define IRQS_PER_WORD  32
 
+struct bcm7120_l1_intc_data {
+       struct bcm7120_l2_intc_data *b;
+       u32 irq_map_mask[MAX_WORDS];
+};
+
 struct bcm7120_l2_intc_data {
        unsigned int n_words;
        void __iomem *map_base[MAX_MAPPINGS];
        struct irq_domain *domain;
        bool can_wake;
        u32 irq_fwd_mask[MAX_WORDS];
-       u32 irq_map_mask[MAX_WORDS];
+       struct bcm7120_l1_intc_data *l1_data;
        int num_parent_irqs;
        const __be32 *map_mask_prop;
 };
 
 static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
 {
-       struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc);
+       struct bcm7120_l1_intc_data *data = irq_desc_get_handler_data(desc);
+       struct bcm7120_l2_intc_data *b = data->b;
        struct irq_chip *chip = irq_desc_get_chip(desc);
        unsigned int idx;
 
 
                irq_gc_lock(gc);
                pending = irq_reg_readl(gc, b->stat_offset[idx]) &
-                                           gc->mask_cache;
+                                           gc->mask_cache &
+                                           data->irq_map_mask[idx];
                irq_gc_unlock(gc);
 
                for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
 
 static int bcm7120_l2_intc_init_one(struct device_node *dn,
                                        struct bcm7120_l2_intc_data *data,
-                                       int irq)
+                                       int irq, u32 *valid_mask)
 {
+       struct bcm7120_l1_intc_data *l1_data = &data->l1_data[irq];
        int parent_irq;
        unsigned int idx;
 
 
        /* For multiple parent IRQs with multiple words, this looks like:
         * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
+        *
+        * We need to associate a given parent interrupt with its corresponding
+        * map_mask in order to mask the status register with it because we
+        * have the same handler being called for multiple parent interrupts.
+        *
+        * This is typically something needed on BCM7xxx (STB chips).
         */
        for (idx = 0; idx < data->n_words; idx++) {
                if (data->map_mask_prop) {
-                       data->irq_map_mask[idx] |=
+                       l1_data->irq_map_mask[idx] |=
                                be32_to_cpup(data->map_mask_prop +
                                             irq * data->n_words + idx);
                } else {
-                       data->irq_map_mask[idx] = 0xffffffff;
+                       l1_data->irq_map_mask[idx] = 0xffffffff;
                }
+               valid_mask[idx] |= l1_data->irq_map_mask[idx];
        }
 
-       irq_set_chained_handler_and_data(parent_irq,
-                                        bcm7120_l2_intc_irq_handle, data);
+       l1_data->b = data;
 
+       irq_set_chained_handler_and_data(parent_irq,
+                                        bcm7120_l2_intc_irq_handle, l1_data);
        return 0;
 }
 
        struct irq_chip_type *ct;
        int ret = 0;
        unsigned int idx, irq, flags;
+       u32 valid_mask[MAX_WORDS] = { };
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                goto out_unmap;
        }
 
+       data->l1_data = kcalloc(data->num_parent_irqs, sizeof(*data->l1_data),
+                               GFP_KERNEL);
+       if (!data->l1_data) {
+               ret = -ENOMEM;
+               goto out_free_l1_data;
+       }
+
        ret = iomap_regs_fn(dn, data);
        if (ret < 0)
-               goto out_unmap;
+               goto out_free_l1_data;
 
        for (idx = 0; idx < data->n_words; idx++) {
                __raw_writel(data->irq_fwd_mask[idx],
        }
 
        for (irq = 0; irq < data->num_parent_irqs; irq++) {
-               ret = bcm7120_l2_intc_init_one(dn, data, irq);
+               ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask);
                if (ret)
-                       goto out_unmap;
+                       goto out_free_l1_data;
        }
 
        data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words,
                                             &irq_generic_chip_ops, NULL);
        if (!data->domain) {
                ret = -ENOMEM;
-               goto out_unmap;
+               goto out_free_l1_data;
        }
 
        /* MIPS chips strapped for BE will automagically configure the
                irq = idx * IRQS_PER_WORD;
                gc = irq_get_domain_generic_chip(data->domain, irq);
 
-               gc->unused = 0xffffffff & ~data->irq_map_mask[idx];
+               gc->unused = 0xffffffff & ~valid_mask[idx];
                gc->private = data;
                ct = gc->chip_types;
 
 
 out_free_domain:
        irq_domain_remove(data->domain);
+out_free_l1_data:
+       kfree(data->l1_data);
 out_unmap:
        for (idx = 0; idx < MAX_MAPPINGS; idx++) {
                if (data->map_base[idx])