Skip to content

Commit

Permalink
MIPS: SGI-IP27: rework HUB interrupts
Browse files Browse the repository at this point in the history
This commit rearranges the HUB interrupt code by using MIPS_IRQ_CPU
interrupt handling code and modern Linux IRQ framework features to get
rid of global arrays. It also adds support for irq affinity setting.

Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
  • Loading branch information
Thomas Bogendoerfer authored and Paul Burton committed Feb 19, 2019
1 parent 2c86562 commit 69a07a4
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 531 deletions.
1 change: 1 addition & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ config SGI_IP27
select DEFAULT_SGI_PARTITION
select SYS_HAS_EARLY_PRINTK
select HAVE_PCI
select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_64
select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
Expand Down
12 changes: 7 additions & 5 deletions arch/mips/include/asm/mach-ip27/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#ifndef __ASM_MACH_IP27_IRQ_H
#define __ASM_MACH_IP27_IRQ_H

/*
* A hardwired interrupt number is completely stupid for this system - a
* large configuration might have thousands if not tenthousands of
* interrupts.
*/
#define NR_IRQS 256

#include_next <irq.h>

#define IP27_HUB_PEND0_IRQ (MIPS_CPU_IRQ_BASE + 2)
#define IP27_HUB_PEND1_IRQ (MIPS_CPU_IRQ_BASE + 3)
#define IP27_RT_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 4)

#define IP27_HUB_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
#define IP27_HUB_IRQ_COUNT 128

#endif /* __ASM_MACH_IP27_IRQ_H */
9 changes: 0 additions & 9 deletions arch/mips/include/asm/mach-ip27/mmzone.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,11 @@

#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))

#define LEVELS_PER_SLICE 128

struct slice_data {
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};

struct hub_data {
kern_vars_t kern_vars;
DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
cpumask_t h_cpus;
unsigned long slice_map;
unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};

struct node_data {
Expand Down
4 changes: 1 addition & 3 deletions arch/mips/include/asm/pci/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,6 @@ struct bridge_controller {
struct bridge_regs *base;
nasid_t nasid;
unsigned int widget_id;
unsigned int irq_cpu;
u64 baddr;
unsigned int pci_int[8];
};
Expand All @@ -823,8 +822,7 @@ struct bridge_controller {
#define bridge_clr(bc, reg, val) \
__raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)

extern void register_bridge_irq(unsigned int irq);
extern int request_bridge_irq(struct bridge_controller *bc);
extern int request_bridge_irq(struct bridge_controller *bc, int pin);

extern struct pci_ops bridge_pci_ops;

Expand Down
18 changes: 1 addition & 17 deletions arch/mips/pci/pci-ip27.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,12 @@
*/
#define MAX_PCI_BUSSES 40

/*
* Max #PCI devices (like scsi controllers) we handle on a bus.
*/
#define MAX_DEVICES_PER_PCIBUS 8

/*
* XXX: No kmalloc available when we do our crosstalk scan,
* we should try to move it later in the boot process.
*/
static struct bridge_controller bridges[MAX_PCI_BUSSES];

/*
* Translate from irq to software PCI bus number and PCI slot.
*/
struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];

extern struct pci_ops bridge_pci_ops;

int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
Expand Down Expand Up @@ -77,7 +66,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
bc->io.end = ~0UL;
bc->io.flags = IORESOURCE_IO;

bc->irq_cpu = smp_processor_id();
bc->widget_id = widget_id;
bc->nasid = nasid;

Expand Down Expand Up @@ -165,16 +153,12 @@ int pcibios_plat_dev_init(struct pci_dev *dev)

irq = bc->pci_int[slot];
if (irq == -1) {
irq = request_bridge_irq(bc);
irq = request_bridge_irq(bc, slot);
if (irq < 0)
return irq;

bc->pci_int[slot] = irq;
}

irq_to_bridge[irq] = bc;
irq_to_slot[irq] = slot;

dev->irq = irq;

return 0;
Expand Down
3 changes: 1 addition & 2 deletions arch/mips/sgi-ip27/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
# Makefile for the IP27 specific kernel interface routines under Linux.
#

obj-y := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \
obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \
ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \
ip27-hubio.o ip27-xtalk.o

obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
obj-$(CONFIG_PCI) += ip27-irq-pci.o
obj-$(CONFIG_SMP) += ip27-smp.o
33 changes: 2 additions & 31 deletions arch/mips/sgi-ip27/ip27-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ static void per_hub_init(cnodeid_t cnode)
{
struct hub_data *hub = hub_data(cnode);
nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
int i;

cpumask_set_cpu(smp_processor_id(), &hub->h_cpus);

Expand Down Expand Up @@ -87,24 +86,6 @@ static void per_hub_init(cnodeid_t cnode)
__flush_cache_all();
}
#endif

/*
* Some interrupts are reserved by hardware or by software convention.
* Mark these as reserved right away so they won't be used accidentally
* later.
*/
for (i = 0; i <= BASE_PCI_IRQ; i++) {
__set_bit(i, hub->irq_alloc_mask);
LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
}

__set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);

for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
__set_bit(i, hub->irq_alloc_mask);
LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
}
}

void per_cpu_init(void)
Expand All @@ -113,8 +94,6 @@ void per_cpu_init(void)
int slice = LOCAL_HUB_L(PI_CPU_NUM);
cnodeid_t cnode = get_compact_nodeid();
struct hub_data *hub = hub_data(cnode);
struct slice_data *si = hub->slice + slice;
int i;

if (test_and_set_bit(slice, &hub->slice_map))
return;
Expand All @@ -123,22 +102,14 @@ void per_cpu_init(void)

per_hub_init(cnode);

for (i = 0; i < LEVELS_PER_SLICE; i++)
si->level_to_irq[i] = -1;

/*
* We use this so we can find the local hub's data as fast as only
* possible.
*/
cpu_data[cpu].data = si;

cpu_time_init();
install_ipi();

/* Install our NMI handler if symmon hasn't installed one. */
install_cpu_nmi_handler(cputoslice(cpu));

set_c0_status(SRB_DEV0 | SRB_DEV1);
enable_percpu_irq(IP27_HUB_PEND0_IRQ, IRQ_TYPE_NONE);
enable_percpu_irq(IP27_HUB_PEND1_IRQ, IRQ_TYPE_NONE);
}

/*
Expand Down
Loading

0 comments on commit 69a07a4

Please sign in to comment.