Skip to content

Commit

Permalink
MIPS: Loongson-3: IRQ balancing for PCI devices
Browse files Browse the repository at this point in the history
IRQ0 (HPET), IRQ1 (Keyboard), IRQ2 (Cascade), IRQ7 (SCI), IRQ8 (RTC)
and IRQ12 (Mouse) are handled by core-0 locally. Other PCI IRQs (3, 4,
5, 6, 14, 15) are balanced by all cores from Node-0. This can improve
I/O performance significantly.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J . Hill <Steven.Hill@cavium.com>
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16589/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
chenhuacai authored and ralfbaechle committed Jun 29, 2017
1 parent 99b0b5a commit e1b88ca
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
19 changes: 17 additions & 2 deletions arch/mips/loongson64/loongson-3/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,32 @@

#include "smp.h"

extern void loongson3_send_irq_by_ipi(int cpu, int irqs);
unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
unsigned int local_irq = 1<<0 | 1<<1 | 1<<2 | 1<<7 | 1<<8 | 1<<12;

static void ht_irqdispatch(void)
{
unsigned int i, irq;
unsigned int i, irq, irq0, irq1;
static unsigned int dest_cpu = 0;

irq = LOONGSON_HT1_INT_VECTOR(0);
LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */

irq0 = irq & local_irq; /* handled by local core */
irq1 = irq & ~local_irq; /* balanced by other cores */

if (dest_cpu == 0 || !cpu_online(dest_cpu))
irq0 |= irq1;
else
loongson3_send_irq_by_ipi(dest_cpu, irq1);

dest_cpu = dest_cpu + 1;
if (dest_cpu >= num_possible_cpus() || cpu_data[dest_cpu].package > 0)
dest_cpu = 0;

for (i = 0; i < ARRAY_SIZE(ht_irq); i++) {
if (irq & (0x1 << ht_irq[i]))
if (irq0 & (0x1 << ht_irq[i]))
do_IRQ(ht_irq[i]);
}
}
Expand Down
18 changes: 17 additions & 1 deletion arch/mips/loongson64/loongson-3/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,21 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
}

#define IPI_IRQ_OFFSET 6

void loongson3_send_irq_by_ipi(int cpu, int irqs)
{
loongson3_ipi_write32(irqs << IPI_IRQ_OFFSET, ipi_set0_regs[cpu_logical_map(cpu)]);
}

void loongson3_ipi_interrupt(struct pt_regs *regs)
{
int i, cpu = smp_processor_id();
unsigned int action, c0count;
unsigned int action, c0count, irqs;

/* Load the ipi register to figure out what we're supposed to do */
action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
irqs = action >> IPI_IRQ_OFFSET;

/* Clear the ipi register to clear the interrupt */
loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
Expand All @@ -282,6 +290,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
core0_c0count[i] = c0count;
__wbflush(); /* Let others see the result ASAP */
}

if (irqs) {
int irq;
while ((irq = ffs(irqs))) {
do_IRQ(irq-1);
irqs &= ~(1<<(irq-1));
}
}
}

#define MAX_LOOPS 800
Expand Down

0 comments on commit e1b88ca

Please sign in to comment.