Commit c7cad38d authored by Florian Fainelli's avatar Florian Fainelli Committed by Thomas Gleixner
Browse files

irqchip/irq-brcmstb-l2: Avoid saving mask on shutdown



The interrupt controller shutdown path does not need to save the mask of
enabled interrupts because the next state the system is going to be in is
akin to a cold boot, or a kexec'd kernel. Saving the mask only makes sense
if the software state needs to preserve the hardware state across a system
suspend/resume cycle.

As an optimization, and given that there are systems with dozens of such
interrupt controller, save a "slow" memory mapped I/O read in the shutdown
path where no saving/restoring is required.

Reported-by: default avatarTim Ross <tim.ross@broadcom.com>
Signed-off-by: default avatarFlorian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240424175732.1526531-1-florian.fainelli@broadcom.com
parent 6678ae19
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
	chained_irq_exit(chip, desc);
}

static void brcmstb_l2_intc_suspend(struct irq_data *d)
static void __brcmstb_l2_intc_suspend(struct irq_data *d, bool save)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct irq_chip_type *ct = irq_data_get_chip_type(d);
@@ -127,6 +127,7 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)

	irq_gc_lock_irqsave(gc, flags);
	/* Save the current mask */
	if (save)
		b->saved_mask = irq_reg_readl(gc, ct->regs.mask);

	if (b->can_wake) {
@@ -137,6 +138,16 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
	irq_gc_unlock_irqrestore(gc, flags);
}

static void brcmstb_l2_intc_shutdown(struct irq_data *d)
{
	__brcmstb_l2_intc_suspend(d, false);
}

static void brcmstb_l2_intc_suspend(struct irq_data *d)
{
	__brcmstb_l2_intc_suspend(d, true);
}

static void brcmstb_l2_intc_resume(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
@@ -252,7 +263,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,

	ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
	ct->chip.irq_resume = brcmstb_l2_intc_resume;
	ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
	ct->chip.irq_pm_shutdown = brcmstb_l2_intc_shutdown;

	if (data->can_wake) {
		/* This IRQ chip can wake the system, set all child interrupts