mirror of https://github.com/torvalds/linux.git
irqchip/sifive-plic: Cache the interrupt enable state
Optimize the PLIC driver by maintaining the interrupt enable state in the handler's enable_save array during normal operation rather than only during suspend/resume. This eliminates the need to read enable registers during suspend and makes the enable state immediately available for other purposes. Let __plic_toggle() update both the hardware registers and the cached enable_save state atomically within the existing enable_lock protection. That allows to remove the suspend-time enable register reading since handler::enable_save now always reflects the current state. [ tglx: Massaged change log ] Signed-off-by: Charles Mirabile <cmirabil@redhat.com> Signed-off-by: Lucas Zampieri <lzampier@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://patch.msgid.link/20251024083647.475239-4-lzampier@redhat.com
This commit is contained in:
parent
9dfb295a93
commit
14ff9e54dd
|
|
@ -94,15 +94,22 @@ static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
|
||||||
|
|
||||||
static int plic_irq_set_type(struct irq_data *d, unsigned int type);
|
static int plic_irq_set_type(struct irq_data *d, unsigned int type);
|
||||||
|
|
||||||
static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
|
static void __plic_toggle(struct plic_handler *handler, int hwirq, int enable)
|
||||||
{
|
{
|
||||||
u32 __iomem *reg = enable_base + (hwirq / 32) * sizeof(u32);
|
u32 __iomem *base = handler->enable_base;
|
||||||
u32 hwirq_mask = 1 << (hwirq % 32);
|
u32 hwirq_mask = 1 << (hwirq % 32);
|
||||||
|
int group = hwirq / 32;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = readl(base + group);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
writel(readl(reg) | hwirq_mask, reg);
|
value |= hwirq_mask;
|
||||||
else
|
else
|
||||||
writel(readl(reg) & ~hwirq_mask, reg);
|
value &= ~hwirq_mask;
|
||||||
|
|
||||||
|
handler->enable_save[group] = value;
|
||||||
|
writel(value, base + group);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
|
static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
|
||||||
|
|
@ -110,7 +117,7 @@ static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&handler->enable_lock, flags);
|
raw_spin_lock_irqsave(&handler->enable_lock, flags);
|
||||||
__plic_toggle(handler->enable_base, hwirq, enable);
|
__plic_toggle(handler, hwirq, enable);
|
||||||
raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
|
raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,33 +254,16 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type)
|
||||||
|
|
||||||
static int plic_irq_suspend(void)
|
static int plic_irq_suspend(void)
|
||||||
{
|
{
|
||||||
unsigned int i, cpu;
|
|
||||||
unsigned long flags;
|
|
||||||
u32 __iomem *reg;
|
|
||||||
struct plic_priv *priv;
|
struct plic_priv *priv;
|
||||||
|
|
||||||
priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv;
|
priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv;
|
||||||
|
|
||||||
/* irq ID 0 is reserved */
|
/* irq ID 0 is reserved */
|
||||||
for (i = 1; i < priv->nr_irqs; i++) {
|
for (unsigned int i = 1; i < priv->nr_irqs; i++) {
|
||||||
__assign_bit(i, priv->prio_save,
|
__assign_bit(i, priv->prio_save,
|
||||||
readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID));
|
readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_present_cpu(cpu) {
|
|
||||||
struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu);
|
|
||||||
|
|
||||||
if (!handler->present)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&handler->enable_lock, flags);
|
|
||||||
for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
|
|
||||||
reg = handler->enable_base + i * sizeof(u32);
|
|
||||||
handler->enable_save[i] = readl(reg);
|
|
||||||
}
|
|
||||||
raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue