On 19/06/15 16:26, Brian Norris wrote: > Make use of the new irq_chip chip_{suspend,resume} callbacks. > > This is required because if there are no installed child IRQs for > this chip, the irq_{suspend,resume} functions will not be called. > However, we still need to save/restore the forwarding mask, to enable > the top-level GIC interrupt; otherwise, we lose UART output after S3 > resume. > > In addition to refactoring the callbacks, we have to self-initialize the > mask cache, since the genirq core also doesn't initialize this until the > first child IRQ is installed. > > The original problem report is described in extra detail here: > http://lkml.kernel.org/g/20150619224123.GL4917@ld-irv-0074 > > Signed-off-by: Brian Norris <computersforpeace@xxxxxxxxx> Acked-by: Florian Fainelli <f.fainelli@xxxxxxxxx> > --- > drivers/irqchip/irq-bcm7120-l2.c | 21 +++++++++++++-------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c > index 299d4de2deb5..98f0129fe843 100644 > --- a/drivers/irqchip/irq-bcm7120-l2.c > +++ b/drivers/irqchip/irq-bcm7120-l2.c > @@ -81,10 +81,9 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) > chained_irq_exit(chip, desc); > } > > -static void bcm7120_l2_intc_suspend(struct irq_data *d) > +static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc) > { > - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); > - struct irq_chip_type *ct = irq_data_get_chip_type(d); > + struct irq_chip_type *ct = gc->chip_types; > struct bcm7120_l2_intc_data *b = gc->private; > > irq_gc_lock(gc); > @@ -94,10 +93,9 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d) > irq_gc_unlock(gc); > } > > -static void bcm7120_l2_intc_resume(struct irq_data *d) > +static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc) > { > - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); > - struct irq_chip_type *ct = irq_data_get_chip_type(d); > + struct irq_chip_type *ct = gc->chip_types; > > /* Restore the saved mask */ > irq_gc_lock(gc); > @@ -281,8 +279,15 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, > ct->chip.irq_mask = irq_gc_mask_clr_bit; > ct->chip.irq_unmask = irq_gc_mask_set_bit; > ct->chip.irq_ack = irq_gc_noop; > - ct->chip.irq_suspend = bcm7120_l2_intc_suspend; > - ct->chip.irq_resume = bcm7120_l2_intc_resume; > + ct->chip.chip_suspend = bcm7120_l2_intc_suspend; > + ct->chip.chip_resume = bcm7120_l2_intc_resume; > + > + /* > + * Initialize mask-cache, in case we need it for > + * saving/restoring fwd mask even w/o any child interrupts > + * installed > + */ Your commit message is a tad clearer than this comment, but this is still good enough to understand what is being done here. > + gc->mask_cache = irq_reg_readl(gc, ct->regs.mask); > > if (data->can_wake) { > /* This IRQ chip can wake the system, set all > -- Florian